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

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

什么是装饰器模式

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

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

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

相关推荐
香芋芋圆6 小时前
AI 冲击内卷之下,普通前端如何破局?WebGIS—— 低门槛突围赛道
前端·javascript·人工智能·学习·职场发展
INS_KF7 小时前
【编程笔记】成员函数中两个 const 的区别(const Data &getData() const;)
前端·javascript·笔记
宿6747 小时前
vue3-async
前端·javascript·vue.js
excel8 小时前
Nuxt + Twin CSS 中宽度超过屏幕时底部出现空白的原因与解决方案
前端·javascript
一个游离的指针11 小时前
函数管道:消除深度嵌套调用
前端·javascript
柚yuzumi12 小时前
前端优化,从少触发一次开始:防抖与节流
前端·javascript
默_笙12 小时前
🚤 CSS 布局的"圈地运动":BFC 就是浏览器的独立领地
前端·javascript
用户9385156350712 小时前
大模型记忆指南:从短时缓存到永久记忆,手把手带你吃透 LangChain Memory 管理
javascript·人工智能
xqchen13 小时前
Web Components 普及困境深度解析:技术标准与工程实践的落差
javascript
爱丶不疚13 小时前
写给前端工程师的现代 Python 工程化最佳实践:从 pnpm 到 uv,从 CommonJS 到 src-layout
javascript·python·typescript