Шаблонный метод в JavaScript
Я хочу, чтобы в JavaScript, чтобы реализовать шаблон шаблонов метода.
У меня есть PropertyDecorator с некоторыми подклассами: OpenButtonDecorator, SeeButtonDecorator и так далее. Я хочу иметь в Property decorator следующую функцию:
var build = function(){
decorate(); //Abstract in PropertyDecorator, defined in subclasses
return le.build();
}
Как я могу заставить этот сценарий работать? Может быть, я неправильно реализовал наследование:S (помогите с этим тоже:))
Заранее спасибо.
1 ответ
Javascript - это динамический типизированный язык на основе прототипов. Шаблонный метод является шаблоном проектирования и, следовательно, не зависит от языка, но его реализация может варьироваться в зависимости от языка.
В случае javascript, а также в других динамически типизированных языках, таких как ruby, абстрактные классы и интерфейсы не имеют большого смысла, так как динамическое связывание происходит посредством делегирования. (Вызов метода распространяется на более высокие уровни в дереве наследования, пока прототип не сможет обработать запрос). Это, в сочетании с утиной типизацией, которая означает, что любой метод может быть потенциально вызван в любом экземпляре, устраняет необходимость явного контракта, который в языках на основе классов определяется теми объявленными методами, которые видны в определенном типе.
Таким образом, чтобы реализовать шаблон, просто вызовите несуществующий метод родительского метода сборки прототипа (этот метод будет шаблоном) и просто реализуйте этот метод на подклассах:
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());
}
Отправка метода происходит следующим образом:
- Экземпляр вызвал метод?
- Нет -> делегировать вызов родителю (это прототип) и повторить.
- Да-> Выполнить тело метода в контексте неявного объекта (тот, который получил вызов в начале).
Таким образом, при вызове new SeeButtonDecorator(). Build() сначала он попытается выполнить метод сборки на экземпляре. Поскольку это не определено в экземпляре, вызов метода будет делегирован родительскому экземпляру, у которого в этом случае прототипу SeeButtonDecorator, в данном случае, также нет метода, поэтому он делегирует вызов своему родителю (PropertyDecorator). PropertyDecorator, имеет build()
метод.
function PropertyDecorator()
{
this.build = function()
{
var decoration=this.decorate();
return "The decoration I did: "+decoration;
};
}
При выполнении этого, build
Тело метода будет оцениваться в контексте нового SeeButtonDecorator (). Сам экземпляр не будет иметь decorate()
метод, как это определено в функции SeeButtonDecorator () (ее прототип). Что ж, на этот раз вызов будет делегирован прототипу экземпляра, который наконец получит метод decorate():
function SeeButtonDecorator()
{
this.decorate = function()
{
return "see button";
};
}
Метод будет снова выполнен в контексте экземпляра и вернет строку, возвращаясь в стек вызовов до возврата
The decoration I did: see button