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

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

什么是装饰器模式

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

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

  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中的应用:桥梁之间的旧与新

相关推荐
渊渟岳17 分钟前
掌握设计模式--装饰模式
设计模式
小马哥编程2 小时前
Function.prototype和Object.prototype 的区别
javascript
王小王和他的小伙伴2 小时前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
学前端的小朱2 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
outstanding木槿2 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
zh路西法2 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(二):从FSM开始的2D游戏角色操控底层源码编写
c++·游戏·unity·设计模式·状态模式
好名字08213 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
夏旭泽3 小时前
设计模式-备忘录模式
设计模式·备忘录模式
摇光933 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
蓝染-惣右介3 小时前
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
java·设计模式