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

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

什么是装饰器模式

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

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

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

相关推荐
I'm Jie1 天前
深入了解 Vue 3 组件间通信机制
前端·javascript·vue.js
用户90443816324601 天前
90%前端都踩过的JS内存黑洞:从《你不知道的JavaScript》解锁底层逻辑与避坑指南
前端·javascript·面试
PPPPickup1 天前
easychat项目复盘---获取联系人列表,联系人详细,删除拉黑联系人
java·前端·javascript
老前端的功夫1 天前
前端高可靠架构:医疗级Web应用的实时通信设计与实践
前端·javascript·vue.js·ubuntu·架构·前端框架
脾气有点小暴1 天前
前端页面跳转的核心区别与实战指南
开发语言·前端·javascript
San30.1 天前
深入 JavaScript 内存机制:从栈与堆到闭包的底层原理
开发语言·javascript·udp
Fantastic_sj1 天前
Vue3相比Vue2的改进之处
前端·javascript·vue.js
ttod_qzstudio1 天前
深入理解 TypeScript 数组的 find 与 filter 方法:精准查找的艺术
javascript·typescript·filter·find
ZouZou老师1 天前
C++设计模式之解释器模式:以家具生产为例
c++·设计模式·解释器模式
冬男zdn1 天前
优雅处理数组的几个实用方法
前端·javascript