装饰器模式:一种灵活的扩展对象功能的方式

对类或对象增加行为一般有两种方式:继承和关联实现。继承是一种静态机制不能控制增加行为的方式和时机。而关联实现,就是将一个类的对象嵌入到另一对象中,由另一个对象控制嵌入对象行为。本次说的装饰器模式就是一种关联实现。

什么是装饰器模式

装饰器模式是一种设计模式,它允许在运行时添加额外的功能到对象,而不需要改变其原有的代码。这使得你可以将一些行为(或称之为"装饰")动态地绑在对象上。

为什么要使用装饰器模式?

  1. 灵活性和扩展性:装饰器模式允许你在运行时动态地添加或删除对象的行为。这样,你可以根据需要灵活地扩展对象的功能,而不必在编译时预先决定所有的行为。
  2. 无需继承:装饰器模式不依赖于继承,而是使用组合和继承来实现功能的扩展。这有助于减少代码的耦合度,使得代码更易于维护和修改。
  3. 更好的模块化:装饰器模式可以将不同的功能模块分离出来,每个模块负责实现一部分功能。这有助于实现更好的模块化,使得代码更容易组织和理解。
  4. 可复用性:装饰器模式允许你在不同的上下文中重复使用同一个对象,只需简单地给它添加不同的装饰器即可。

模式结构

装饰器模式的UML图通常涉及以下几个核心组件:

  1. Component:定义一个接口,允许对象被装饰。
  2. Decorator:实现Component接口,并包含一个指向Component的指针。在需要的时候,它可以包装一个具体的Component对象。
  3. ConcreteComponent:定义Component接口的具体实现类。
  4. 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()

装饰器模式和适配器模式的区别

装饰器模式和适配器模式都是用于在不影响其他代码的情况下,扩展已有的对象或类的功能。然而,它们在实现方式和意图上存在一些区别:

  1. 意图:装饰器模式的主要意图是动态地添加职责或行为,它以包装的方式提供了一种灵活的方式来扩展对象的功能。适配器模式则是为了解决两个接口之间不兼容的问题,使得它们可以协同工作。
  2. 对象类型:装饰器模式可以包装同种类型的对象,使其能够动态地增加新的行为或责任。适配器模式通常需要将一个类的接口转换成客户所期望的另一个接口,因此它可以包装不同类型的对象。
  3. 适用场景:装饰器模式适用于在不改变对象接口的情况下为对象动态地添加新的职责或行为。适配器模式适用于需要将一个类的接口转换成客户所期望的另一个接口的情况,例如,将一种数据格式转换成另一种数据格式。

相关文章
适配器模式在JavaScript中的应用:桥梁之间的旧与新

相关推荐
web行路人2 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱0014 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼92122 分钟前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂24 分钟前
ajax关于axios库的运用小案例
前端·javascript·ajax
周亚鑫1 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二1 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236481 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
fruge2 小时前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js
嚣张农民2 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试