JavaScript装饰者模式详解:动态扩展对象功能

作者:拾光

时间:2026-10-28

浏览:359

本文深入解析JavaScript中的装饰者模式,阐述如何通过动态包装对象来扩展其功能,同时保持原有接口不变。通过穿衣场景类比及具体代码示例,展示如何在不修改原类的前提下,灵活添加日志、权限校验等额外行为,体现开闭原则。

文章目录

装饰者模式概述

装饰者模式说明

该模式的核心在于通过一个包装类,动态地增强另一个类对象的功能。这种增强可以在原方法执行前或执行后进行,旨在为对象附加额外的行为。为了确保装饰类与被装饰类可以互换使用,两者必须拥有相同的访问接口。在动态面向对象编程中,这通常通过实现同一个接口(interface)来约束和保证。装饰类内部需要持有对被装饰类的引用,以便在装饰类的相应方法中调用被装饰类的方法,并在调用前后执行额外的修饰逻辑。

场景举例:

1. 生活类比:穿衣过程。想象一下日常穿搭:先穿一件衬衣,再套上一件西装外套,接着穿裤子、系领带,最后穿上皮鞋。每增加一件衣物,都是对之前穿着状态的一种装饰或增强。

2. 技术场景:功能扩展。假设有一个类包含写日志或用户登录的功能。在写入日志之前,可能需要先获取当前操作者的信息;或者在用户登录成功后,需要记录一条日志。写入日志前的额外操作(如获取信息)本质上仍服务于写日志这一目的;而登录成功后写日志,总体上也属于登录过程的信息记录环节。

因此,装饰者模式适用于实现两种相似操作的场景。它通过对被装饰者功能对象的扩展,实现了功能的叠加,但其本质仍保持在原方法相同的功能范围内。

基础代码实现

实例源码

1. 被装饰者类


代码如下:

function Wear() {
    
}
Wear.prototype.Shirt = function() {
 //穿了件衬衫
 console.log('穿上衬衫');
}

2. 装饰者类

代码如下:

function Decorator(wear) {
this.wear = wear;
}
Decorator.prototype.Shirt = function() {
 this.wear.Shirt();
 //穿了件衬衫后,我又加上了领带
}

3. 使用方法

代码如下:

var wear = new Wear();
var decorator = new Decorator(wear);
decorator.Shirt();

通过上述代码,实现了对 Wear 类中穿衬衫功能的动态扩展与装饰。使用者无需知晓原被装饰方法的具体执行细节,只需了解其功能目标,以及需要附加的额外功能即可。

其他说明

装饰者模式真正体现了面向对象设计原则中的“对扩展开放,对修改关闭”。所有期望的功能方法,都是在未修改[被装饰类Wear]的情况下,通过扩展[装饰者类Decorator]来实现的。

装饰者模式的一个主要特点,就是装饰者对被装饰者的引用,以实现对被装饰者的无修改装饰。

多重装饰模拟

模拟下:先穿衬衫,再穿领带,再穿西装的场景: 上面的被装饰者不变了:

2. 装饰者类:

代码如下:

function Decorator(wear) {
this.wear = wear;
}
Decorator.prototype.Shirt = function() {
this.wear.Shirt(); //这里只穿衬衫;
}

3. 创建类似继承 Decorator 子类的 穿领带类与穿西装类


代码如下:

function Decorator_Tie(decorator) {
this.decorator = decorator;
}    
Decorator_Tie.prototype.Shirt = function() {
this.decorator.Shirt(); //穿上衬衫
console.log('再戴上领带');
}
function Decorator_Western (decorator) {
 this.decorator = decorator;
}
Decorator_Western.prototype.Shirt = function() {
 this.decorator.Shirt();
 console.log('再穿上西装');
}

使用方法:


代码如下:

//先穿上衬衫
var wear = new Wear();
var decorator = new Decorator(wear);
//decorator.Shirt();
//再戴上领带
var tie = new Decorator_Tie(decorator);
//tie.Shirt();
//再穿上西装
var western = new Decorator_Western(tie);
western.Shirt();

这就是一个穿衣服装饰的模拟例子;

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章