javascript中的模板方法

时间:2010-10-08 15:08:38

标签: javascript inheritance template-method-pattern

我希望在javascript中实现模板方法模式。

我有一个带有一些子类的PropertyDecorator:OpenButtonDecorator,SeeButtonDecorator等等。我想在Property decorator中有下一个函数:

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

如何让这个场景有效?也许我实现了错误的继承:S(也帮助:))

提前谢谢。

1 个答案:

答案 0 :(得分:12)

Javascript是一种动态类型,基于原型的语言。模板方法是一种设计模式,因此与语言无关,但其实现可能因语言而异。

对于javascript,以及其他动态类型语言,如ruby,抽象类和接口没有多大意义,因为动态链接是通过委托进行的。 (方法调用在继承树中传播到更高级别,直到原型可以处理请求)。这与duck-typing相结合,这意味着可以在任何实例上调用任何方法,避免需要显式契约,这在基于类的语言中由在某个Type上可见的那些声明的方法定义。

因此,为了实现模式,只需在父的原型构建方法上调用一个不存在的方法(该方法将是模板),并在子库中简单地实现该方法:

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());
}

方法调度以这种方式发生:

  • 实例是否调用了该方法?
    • 否 - >委托给父母(它的原型)并重复。
    • 是 - >在隐式对象(在开头接收调用的对象)的上下文中执行方法体。

因此,在调用新的SeeButtonDecorator()。build()时,首先,它将尝试在实例上执行构建方法。因为它没有在实例中定义,所以方法调用将被委托给实例父实例,在本例中,SeeButtonDecorator原型,这个实例不具有该方法,因此它将委托调用它的父代(PropertyDecorator)。 PropertyDecorator具有build()方法。

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

执行它时,将在新的SeeButtonDecorator()的上下文中评估build方法的主体。实例本身不会有decorate()方法,因为它在SeeButtonDecorator()函数(其原型)中定义。好吧,这次调用将被委托给实例原型,最终会得到一个decorate()方法:

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

该方法将在实例的上下文中再次执行,并将返回字符串,返回调用堆栈直到返回

The decoration I did: see button