Question

I want, in javascript, to implement the template method pattern.

I have a PropertyDecorator with some subclasses: OpenButtonDecorator, SeeButtonDecorator and so on. I want to have in Property decorator the next function:

var build = function(){
   decorate(); //Abstract in PropertyDecorator, defined in subclasses
   return le.build();
}

How can I get this scenario working? Maybe I implemented wrong the inheritance :S (help with that too :) )

Thank you in advance.

Was it helpful?

Solution

Javascript is a dynamic typed, prototype-based language. Template method is a design pattern and hence language independent, but its implementation can vary across languages.

In the case of javascript, and also in other dynamically typed languages, like ruby, abstract classes and interfaces doesn't make much sense, since dynamic linking occurs via delegation. (A method call is propagated to higher levels in the inheritance tree until a prototype can handle the request). This, in conjunction with duck-typing, which means that any method can be potentially called on any instance, avoids the need of an explicit contract, which in class-based languages is defined by those declared methods that are visible on a certain Type.

So in order to implement the pattern, just call an inexistent method on the parent's prototype build method (that method will be the template) and simply implement that method on the sublcasses:

function PropertyDecorator()
{
   this.build = function()
   {
      var decoration=this.decorate();
      return "The decoration I did: "+decoration;
   };
}

//we set the parent (those prototype that instances of this class will delegate calls to) 
OpenButtonDecorator.prototype = new PropertyDecorator();
function OpenButtonDecorator()
{
   this.decorate = function()
   {
     return "open button";
   };
}


SeeButtonDecorator.prototype = new PropertyDecorator();
function SeeButtonDecorator()
{
   this.decorate = function()
   {
      return "see button";
   };
}



var decorators=Array(new SeeButtonDecorator(),new OpenButtonDecorator());
for (var decorator in decorators){
    document.writeln(decorators[decorator].build());
}

A method dispatch occurs this way:

  • Does the instance have the method invoked?
    • No -> Delegate call to the parent (it's prototype) and repeat.
    • Yes-> Execute method body in the context of the implicit object (the one that received the call in the beginning).

So, when calling new SeeButtonDecorator().build(), first, it will try to execute build method on the instance. As it's not defined in the instance, method invocation will be delegated to the instance parent, which in this case SeeButtonDecorator prototype, this one, hasn't got the method neither, so it will delegate the call to it's parent (PropertyDecorator). PropertyDecorator, has the build() method.

function PropertyDecorator()
{
   this.build = function()
   {
      var decoration=this.decorate();
      return "The decoration I did: "+decoration;
   };
}

When executing it, build method's body will be evaluated in the context of the new SeeButtonDecorator(). The instance itself won't have a decorate() method, as it's defined in SeeButtonDecorator() function (its prototype). Well, this time the call will be delegated to the instance prototype, wich will finally got a decorate() method:

function SeeButtonDecorator()
{
   this.decorate = function()
   {
      return "see button";
   };
}

The method will be executed in the context of the instance again, and will return the string, falling back in the call stack until returning

The decoration I did: see button
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top