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
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.
1