0

I have been using Template Design pattern in my code for implementing CRUD procedures for different resources.

There are some steps which are same for many resources and some which need some addition/overriding.

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;


}

As Joshua Bloch wrote in the third edition of Effective Java,

The Template Method pattern [..] is far less attractive. The modern alternative is to provide a static factory or constructor that accepts a function object to achieve the same effect.

I feel the code reuse in 10-15 resources procedures I am writing is significant. Shall Template design pattern be avoided due to Inheritance ?

7

Inheritance is not bad per se. It depends on how you use it. Avoiding a technique just because someone says it is bad is not a good way to make decisions.

While I see where Josh Bloch is coming from, the alternative he proposes is not quite the same thing. The Template pattern aims to enforce a particular design; it takes advantage of the rigidity of base classes to achieve this end. The static factory or constructor, on the other hand, focuses more on flexibility and decoupling because it is compatible with Dependency Injection techniques.

In other words, they have two (somewhat) different purposes.

When deciding on whether or not to use a particular software development technique, evaluate it on its relative merits within the context of your particular project, not on the summary opinions of others. Let those opinions guide you, if you wish, but always be the final arbiter.

Further Reading
Template Method Pattern
Java Constructors vs Static Factory Methods
Function object

  • @ Robert Harvey: So you pointing out the two approaches are different: inheritance vs injecting function object (IFO). IFO purpose being decoupling (with no code reuse) and inheritance purpose being code reuse ? – Siddharth Trikha May 17 at 6:27
  • You can have code reuse with static factories and constructors. What I'm saying is that coupling can sometimes be a feature. The Template pattern is unfashionable nowadays because it causes coupling and everyone "knows" coupling is "bad," but sometimes coupling is what you want. – Robert Harvey May 17 at 15:55
  • Okay. Now, if I try to implement my design through injecting function object, each of my procedures class 'R1Procedures', 'R2Procedures', etc would have an object passed (my current base class) and call it's methods ? In that case I will repeating calling same methods inside create method of each procedure class. How is code reused in this design ? – Siddharth Trikha May 18 at 12:08
  • Code is reused because, so long as that object conforms to the interface your class expects, it can be any object you want. – Robert Harvey May 22 at 16:49
2

Your ResourceCommonProcedures doesn't really seem to be an example of the Template Method pattern (as it doesn't really define a 'template' for an operation, except perhaps in a trivial sense). Your base class acts as a factory that produces a concrete ResourceCommonProcedures-derived instance based on an identifying parameter (resourceType). Arguably, that sort of logic should be in some other class, and not in ResourceCommonProcedures, as creating a response and deciding which objects should handle the request are likely different responsibilities (that said, if the current design isn't causing you problems of that sort, don't change it just for the sake of it).

But since you asked about the Template Method pattern, there are a couple of things to consider. First, the intent of the pattern is to define a skeleton (or a template) of some operation, that enforces some constraints but also provides extension points (or plug-in points). You see this kind of thing in frameworks (e.g, when they provide a base class you derive from, and override certain methods), but the pattern can appear in other contexts as well. Usually, the base class is not aware of the extensions (except maybe for a couple that provide default behavior).

Second, there are different ways to achieve this sort of extensibility/configurability. Broadly speaking, you can go the inheritance route (as described in the Go4 book1), or use composition. The choice here is essentially about what kind of interface you want/need to provide to the extending code (although, other things can affect your design as well). Compositional interfaces are generally more flexible, and lambdas (or, rather, functional interfaces) offer a convenient way to express them.

Traditionally, for the composition-based approach, you would define a required interface for extensions to implement, and design your base class to accept a dependency via this interface. In more complicated scenarios, you could have more than one interface, for a couple of different dependencies, in different roles. This is more flexible (as you can mix and match different objects for the different roles, or inject the same object in more then one role), but it does come with some increase in complexity, and is arguably a bit cumbersome. Functional interfaces can be used to essentially define a role interface for each of the extension points separately (for each sub-operation); they let you inject lambdas, as well as references to static and instance methods of other classes/objects, and there's a bunch of standard ones that come with the language.

Third, the extensions can be separate, fairly independent peaces of code, or they can be a part of an integrated hole, regardless of how the base class' extension interface is defined (at least in principle; granted, some things may be easier to do with one approach then with the other).

The Effective Java chapter you refer to argues to prefer the use of standard functional interfaces, it seems, in more or less in the same spirit as the well-known advice to favor composition over inheritance (found, incidentally, in the Go4 book1) - as a general design heuristic. That doesn't mean that you should never use inheritance, just that you should weigh the pros and cons before you decide.


1 Gamma et al. 1995. Design Patterns: Elements of Reusable Object-Oriented Software

1

One of the strong selling points of OO is supposed to be encapsulation: the implementation details are hidden away and only API, in the form of method signatures and the like, are exposed to the wider world. Yet there is a well recognised way of breaking that encapsulation: you guarantee that a method will perform certain actions, including calling other - abstract - methods in a certain way. You have suddenly made your implementation part of that public API; you have broken that method's encapsulation.

When you have a method in a base class and you tightly couple the implementation of that method to every single child class that will ever exist, then you have a further problem: any change to that implementation will risk breaking a child class. That child class may have been written long after you wrote the base class, by a third party etc. You may have no control over it. If you find a bug, you may not be able to fix it because of the risk of breaking that other code by doing so.

This combination of problems: breaking encapsulation and in turn tightly coupling the implementation of a method to child class methods has a name: the fragile base class problem. But it also has another name: the template pattern. The template pattern does exactly what I describe above and it does it deliberately. So just like the singleton and service locator patterns, the template pattern sits firmly in the realms of antipatterns.

So no, you shouldn't avoid the template pattern due to inheritance per se, but you should definitely avoid it due to it perfectly embodying the worst possible use of inheritance.

0

I have to disagree with most responders here and claim that template design pattern is not a great solution due to inheritance.

From Wikipedia:

the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses.

Key here is behavioral and deferring. This means that everything that can be done by template pattern, can also be done with (or say transformed into) the strategy pattern. And as we all well know, the strategy pattern is non-existent (not explicit) in functional programming. If you do it that way, it will be more flexible and the concerns will be separated more prominently.

Why?

Because with the template pattern, you have to inherit all the other logic from the base class that is necessary for the execution, when you really just want to write a single (or a few at most) function(s).

So basically you just want to specify a part of the process, just one single function call. With the template you have to make it a class, while it would make more sense to keep it as one function.

IMO, anything you can do with template, you can do with strategy. Since strategy is cleaner, you should always go that way.

Sry I did not post code, I hope it is clear in itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.