对类或对象增加行为一般有两种方式:继承和关联实现。继承是一种静态机制不能控制增加行为的方式和时机。而关联实现,就是将一个类的对象嵌入到另一对象中,由另一个对象控制嵌入对象行为。本次说的装饰器模式就是一种关联实现。
什么是装饰器模式
装饰器模式是一种设计模式,它允许在运行时添加额外的功能到对象,而不需要改变其原有的代码。这使得你可以将一些行为(或称之为"装饰")动态地绑在对象上。
为什么要使用装饰器模式?
- 灵活性和扩展性:装饰器模式允许你在运行时动态地添加或删除对象的行为。这样,你可以根据需要灵活地扩展对象的功能,而不必在编译时预先决定所有的行为。
- 无需继承:装饰器模式不依赖于继承,而是使用组合和继承来实现功能的扩展。这有助于减少代码的耦合度,使得代码更易于维护和修改。
- 更好的模块化:装饰器模式可以将不同的功能模块分离出来,每个模块负责实现一部分功能。这有助于实现更好的模块化,使得代码更容易组织和理解。
- 可复用性:装饰器模式允许你在不同的上下文中重复使用同一个对象,只需简单地给它添加不同的装饰器即可。
模式结构
装饰器模式的UML图通常涉及以下几个核心组件:
- Component:定义一个接口,允许对象被装饰。
- Decorator:实现Component接口,并包含一个指向Component的指针。在需要的时候,它可以包装一个具体的Component对象。
- ConcreteComponent:定义Component接口的具体实现类。
- AbstractDecorator:定义所有具体装饰类的基类。
通过UML图,可以看出,通过装饰器模式,可以在不改动 ConcreteComponent
的情况下,对其进行扩展。
下面是javascript
的实现形式
javascript
var Component = function () {}
Component.prototype.opration = function () {
throw new Error("子类必须实现此方法");
}
var ConcreteComponent = function () {}
ConcreteComponent.prototype = Object.create(Component.prototype)
ConcreteComponent.prototype.constructor = Component
ConcreteComponent.prototype.opration = function () {
console.log("ConcreteComponent_opration");
}
var Decorator = function (component) {
this.component = component
}
Decorator.prototype = Object.create(Component.prototype)
Decorator.prototype.constructor = Component
Decorator.prototype.opration = function () {
this.component.opration()
}
var ConcreteDecoratorA = function () {
Decorator.apply(this, arguments)
}
ConcreteDecoratorA.prototype = Object.create(Decorator.prototype)
ConcreteDecoratorA.prototype.constructor = Decorator
ConcreteDecoratorA.prototype.addBehavior = function () {
console.log("ConcreteDecoratorA_addBehavior");
}
var ConcreteDecoratorB = function () {}
ConcreteDecoratorB.prototype = Object.create(Decorator.prototype)
ConcreteDecoratorB.prototype.constructor = Decorator
ConcreteDecoratorB.prototype.addBehavior = function () {
console.log("ConcreteDecoratorB_addBehavior");
}
var concreteComponent = new ConcreteComponent()
var concreteDecoratorA = new ConcreteDecoratorA(concreteComponent)
concreteDecoratorA.opration()
concreteDecoratorA.addBehavior()
装饰器模式和适配器模式的区别
装饰器模式和适配器模式都是用于在不影响其他代码的情况下,扩展已有的对象或类的功能。然而,它们在实现方式和意图上存在一些区别:
- 意图:装饰器模式的主要意图是动态地添加职责或行为,它以包装的方式提供了一种灵活的方式来扩展对象的功能。适配器模式则是为了解决两个接口之间不兼容的问题,使得它们可以协同工作。
- 对象类型:装饰器模式可以包装同种类型的对象,使其能够动态地增加新的行为或责任。适配器模式通常需要将一个类的接口转换成客户所期望的另一个接口,因此它可以包装不同类型的对象。
- 适用场景:装饰器模式适用于在不改变对象接口的情况下为对象动态地添加新的职责或行为。适配器模式适用于需要将一个类的接口转换成客户所期望的另一个接口的情况,例如,将一种数据格式转换成另一种数据格式。