Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template method in javascript

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.

like image 235
pablorc Avatar asked Oct 08 '10 15:10

pablorc


People also ask

What is template method pattern in design pattern?

Template method design pattern is to define an algorithm as a skeleton of operations and leave the details to be implemented by the child classes. The overall structure and sequence of the algorithm are preserved by the parent class. Template means Preset format like HTML templates which has a fixed preset format.

Why is template pattern used?

It lets subclasses implement varying behavior (through overriding of the hook methods). It avoids duplication in the code: the general workflow of the algorithm is implemented once in the abstract class's template method, and necessary variations are implemented in the subclasses.

What is Java template example?

Template Method is a behavioral design pattern that allows you to defines a skeleton of an algorithm in a base class and let subclasses override the steps without changing the overall algorithm's structure.

What is a template in OOP Java?

A template is a piece of code that can be copied and modified to fit a specific situation. Some templates show how, why, and when to use some feature of the language. Some templates show how to implement design patterns.


1 Answers

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
like image 63
Miguel Avatar answered Oct 14 '22 01:10

Miguel