在 JavaScript 中,裝飾器模式可以通過閉包和函數式編程技巧來實現。裝飾器模式允許我們在不修改原始對象的基礎上,動態地添加或修改功能。
以下是一個簡單的裝飾器模式的例子:
// 定義一個接口,用于裝飾器
function Component() {
this.name = 'Component';
}
Component.prototype.getName = function() {
return this.name;
};
// 定義一個具體的組件
function ConcreteComponent() {
Component.call(this);
this.name = 'ConcreteComponent';
}
ConcreteComponent.prototype = Object.create(Component.prototype);
ConcreteComponent.prototype.constructor = ConcreteComponent;
// 定義一個裝飾器基類
function Decorator(component) {
this._component = component;
}
Decorator.prototype.getName = function() {
return this._component.getName();
};
// 定義一個具體的裝飾器
function ConcreteDecoratorA(component) {
Decorator.call(this, component);
}
ConcreteDecoratorA.prototype = Object.create(Decorator.prototype);
ConcreteDecoratorA.prototype.constructor = ConcreteDecoratorA;
ConcreteDecoratorA.prototype.getName = function() {
return '[' + this._component.getName() + '] ConcreteDecoratorA';
};
// 定義另一個具體的裝飾器
function ConcreteDecoratorB(component) {
Decorator.call(this, component);
}
ConcreteDecoratorB.prototype = Object.create(Decorator.prototype);
ConcreteDecoratorB.prototype.constructor = ConcreteDecoratorB;
ConcreteDecoratorB.prototype.getName = function() {
return this._component.getName() + ' ConcreteDecoratorB';
};
// 使用裝飾器
const concreteComponent = new ConcreteComponent();
console.log(concreteComponent.getName()); // 輸出 "ConcreteComponent"
const decoratorA = new ConcreteDecoratorA(concreteComponent);
console.log(decoratorA.getName()); // 輸出 "[ConcreteComponent] ConcreteDecoratorA"
const decoratorB = new ConcreteDecoratorB(decoratorA);
console.log(decoratorB.getName()); // 輸出 "[ConcreteComponent] ConcreteDecoratorA ConcreteDecoratorB"
在這個例子中,我們首先定義了一個 Component
接口和兩個實現了該接口的具體組件 ConcreteComponent
。然后,我們定義了一個裝飾器基類 Decorator
和兩個具體裝飾器 ConcreteDecoratorA
和 ConcreteDecoratorB
。這些裝飾器都接受一個組件作為參數,并在其 getName
方法中調用組件的 getName
方法,從而在不修改原始組件的基礎上動態地添加了功能。
最后,我們創建了一個 ConcreteComponent
實例,并使用 ConcreteDecoratorA
和 ConcreteDecoratorB
對其進行裝飾,然后打印出裝飾后的組件名稱。