Java – How to generalize a classes that has identical function plus some additional function

designdesign-patternsinterfacesjavaobject-oriented-design

I have some designing problems with my project. To illustrate my problem, I'll use the following two classes from my project.

public class RAM_UserManagement{
  private Map<int,User> userList;
  public User addUser(User user){//do stuff}
  public User deleteUser(User user){//do stuff}
  public User updateUser(User user){//do stuff}
  public List<User> getAllUser(){//do stuff}
  public User getUserById(int userId){//do stuff}
}

public class RAM_ServiceManagment{
  private Map<int,Serivce> serviceList;
  public Service addService(Service ser){//do stuff}
  public Service deleteService(Service ser){//do stuff}
  public Service updateService(Service ser){//do stuff}
  public List<Service> getAllSerivces(){//do stuff}
  public Service getServiceById(int id){//do stuff}
  public Service getServiceByStatus(ENUM_STATUS status){//do stuff}
  public Service getServiceByUserName(String Name){//do stuff}
}

As you can see, from the nature of these classes they both doing exact same thing with some extra functionality. I am trying to generalize it by creating an interface. This is what I have in mind

public interface IStorage<T>{
  public T add(T item);
  public T delete(T item);
  public T update(T item);
  public List<T> getAll();//This is where I am struggling..
}

So CUD operation in both classes are ok to implement but the R(Read) method in both classes varies. In RAM_ServiceManagement I have extra getAll, getById, getStatus, getByName than the other class.

How can I generalize this? or generalization cannot be applied here at all? Really appreciate if you can give some suggestion.

Thanks

Best Answer

I'd try something like the following:

public abstract class RAM_Management<T> {
    protected Map<Integer, T> dataList;
    public T addData(T data) { /* ... */ }
    public T deleteData(T data) { /* ... */ }
    public T udpateData(T data) { /* ... */ }
    public List<T> getAllData() { /* ... */ }
    public T getDataById(int id) { /* ... */ }
}

public class RAM_UserManagement extends RAM_Management<User> {
    // needs no separate implementation
}

public class RAM_ServiceManagement extends RAM_Management<Service> {
    public Service getServiceByStatus(ENUM_STATUS status) { /* ... */ }
    public Service getServiceByUserName(String name) { /* ... */ }
}

By using an abstract base class instead of an interface, you avoid the need to re-write your implementations of the common methods (assuming that all they do is interact with the protected dataList member.) I've also assumed that both classes' getXXXById methods work the same; if they don't, then you just take it out of the abstract class and implement it in your concrete classes.

Related Topic