Java Design Patterns – Combining Inheritance and Factory Patterns

design-patternsinheritancejavaobject-orientedobject-oriented-design

I have a hierarchical data model and am trying to implement their CRUD operations in my Web Application.

Currently I have code inheritance for CRUD operations of my entities (resources) as follows:

ResourceCommonProcedures as a base class and each Resource procedure inheriting the base class.

public class ResourceCommonProcedures { 

    public Response create(Request request){
        Response response = new Response();
        int resType = this.getResourceType(request);

        ResourceCommonProcedures rp = getResourceController(resType);
        response = rp.create(request);

        return response;
    }

private ResourceCommonProcedures getResourceController(int resourceType){
            //..

            switch(resourceTypeName){


            case Resource1:
                return new R1Procedures();

            case Resource2:
                return new R2Procedures();

            case Resource3:
                return new R3Procedures();
            ............... 

}
}

Class R1Procedures extends ResourceCommonProcedures{


public Response create(Request request) {

        Response response = new Response();
            Resource1 resource = (Resource1) request.getContent();

            ...........
            // Converts DB structure to JPA 
            R1Converter r1Converter = new R1Converter();
            Resource1JPA resourceJpa = r1Converter.toJPA(resource);
            dao.persist();

            return response;

}
}

Class R2Procedures extends ResourceCommonProcedures{


public Response create(Request request) {

        Response response = new Response();
            Resource1 resource = (Resource2) request.getContent();

            // SOME RESOURCE 2 SPECIFIC CODE
            ...........
            // Converts DB structure to JPA 
            R2Converter r2Converter = new R2Converter();
            Resource2JPA resourceJpa = r2Converter.toJPA(resource);
            dao.persist();

            return response;


}

So currently the base has the controller code which decides which sub class method needs to be called.

So the client will call the base class create method, which will internally get the implementation class and call the specific create method.

Is this design good enough ??

Or should the getResourceController() must be taken out of base class and put in a separate class ??

Is there a design pattern specific to the case ??

Best Answer

I would go for an abstract generic class :

public class AbstractProcedure<T extends BusinessObject, TJPA extends JPAObject, TConverter extends Converter<T, TJPA >>{

public abstract TConverter<T, TJPA> getConverter();

public Response create(Request request) {
    Response response = new Response();
        T resource = (T) request.getContent();

        ...........
        // Converts DB structure to JPA 
        R1Converter r1Converter = getConverter();
        TJPA resourceJpa = r1Converter.toJPA(resource);
        dao.persist(resourceJpa);
        return response;
    }
 }

public class R1Converter implements Converter<R1, R1JPA>{
         @Override // come from the Converter interface
         public R1JPA toJpa(R1 object){}
}
public class R1Procedure extends AbstractProcedure<R1, R1JPA, R1Converter>{
      R1Converter converter = new R1Converter();
      public R1Converter getConverter(){
           return converter;
      }
}

Some point to consider :

  • You might want to rename your "Converter" to "Adapter"
  • Handling the database request in the same class than getting the data from the request is usually done is separated classes for separation of concerns. What if tomorrow a batch have to create entities ?
  • You can override create function to add some default value, right check and call super.create(). Though usage of super is not recommended, this is a sane usage of it IMHO.
Related Topic