跳至主要內容

装饰模式

约 423 字

装饰模式

核心思想

装饰模式允许动态的向一个对象添加额外的功能,而不改变其结构。

典型用例

数据流增强

在处理数据流时,如读写文件或网络数据流,装饰模式可以用来动态地添加额外的功能,例如数据压缩、加密、编码转换等。

在这个例子中,具体装饰者类分别添加了加密和压缩的功能,可以灵活的组合装饰者以提供不同的功能组合。

// npm run code src/code/design-pattern/decorator/data-enhancement.ts

export {};

// 定义一个数据流接口作为所有具体数据流和装饰者的共同接口
interface DataStream {
    read(): string;
    write(data: string): void;
}

// 创建具体的数据流类
class FileDataStream implements DataStream {
    read(): string {
        // 从文件读取数据
        return "data from file";
    }

    write(data: string): void {
        // 向文件写入数据
        console.log(`Writing ${data} to file`);
    }
}

// 创建装饰者基类
abstract class DataStreamDecorator implements DataStream {
    protected wrappedStream: DataStream;

    constructor(wrappedStream: DataStream) {
        this.wrappedStream = wrappedStream;
    }

    read(): string {
        return this.wrappedStream.read();
    }

    write(data: string): void {
        this.wrappedStream.write(data);
    }
}

// 创建具体的装饰者类
class EncryptionDecorator extends DataStreamDecorator {
    read(): string {
        const data = this.wrappedStream.read();
        // 解密数据
        return `decrypted(${data})`;
    }

    write(data: string): void {
        // 加密数据
        this.wrappedStream.write(`encrypted(${data})`);
    }
}

class CompressionDecorator extends DataStreamDecorator {
    read(): string {
        const data = this.wrappedStream.read();
        // 解压缩数据
        return `decompressed(${data})`;
    }

    write(data: string): void {
        // 压缩数据
        this.wrappedStream.write(`compressed(${data})`);
    }
}

const fileStream = new FileDataStream();
const encryptedStream = new EncryptionDecorator(fileStream);
const compressedAndEncryptedStream = new CompressionDecorator(encryptedStream);

// 压缩并加密数据,然后写入文件
compressedAndEncryptedStream.write("data"); 

// 从文件读取数据,解密并解压缩
console.log(compressedAndEncryptedStream.read()); 

用户界面组件装饰

在图形用户界面框架中,装饰模式可以用于动态地添加或修改界面元素地行为或外观,如添加滚动条、边框或阴影效果。

// npm run code src/code/design-pattern/decorator/ui-component-decoration.ts

export {};

interface GUIComponent {
    draw(): void;
}

class TextBox implements GUIComponent {
    draw(): void {
        console.log("Drawing a text box");
    }
}

class Button implements GUIComponent {
    draw(): void {
        console.log("Drawing a button");
    }
}

class GUIComponentDecorator implements GUIComponent {
    protected component: GUIComponent;

    constructor(component: GUIComponent) {
        this.component = component;
    }

    draw(): void {
        this.component.draw();
    }
}

class ScrollbarDecorator extends GUIComponentDecorator {
    draw(): void {
        super.draw();
        console.log("Adding a scrollbar");
    }
}

class BorderDecorator extends GUIComponentDecorator {
    draw(): void {
        super.draw();
        console.log("Adding a border");
    }
}

class ShadowDecorator extends GUIComponentDecorator {
    draw(): void {
        super.draw();
        console.log("Adding a shadow effect");
    }
}

let textBox: GUIComponent = new TextBox();
textBox = new BorderDecorator(textBox);
textBox = new ShadowDecorator(textBox);

textBox.draw(); // 这将绘制一个有边框和阴影的文本框

let button: GUIComponent = new Button();
button = new ScrollbarDecorator(button);

button.draw(); // 这将绘制一个有滚动条的按钮

日志记录和监控

装饰模式可以为现在系统添加日志记录或监控功能,而不改变原有的代码逻辑。

// npm run code src/code/design-pattern/decorator/log-recording-and-monitoring.ts

export {};

class Service {
    performTask(): void {
        console.log("Performing a task");
        // ... 任务相关的代码 ...
    }
}

abstract class ServiceDecorator implements Service {
    protected wrapped: Service;

    constructor(service: Service) {
        this.wrapped = service;
    }

    performTask(): void {
        this.wrapped.performTask();
    }
}

class LoggingDecorator extends ServiceDecorator {
    performTask(): void {
        console.log("Logging: Task is starting");
        super.performTask();
        console.log("Logging: Task has finished");
    }
}

class MonitoringDecorator extends ServiceDecorator {
    performTask(): void {
        const startTime = new Date();
        super.performTask();
        const endTime = new Date();
        console.log(`Monitoring: Task took ${endTime.getTime() - startTime.getTime()} milliseconds`);
    }
}

let service = new Service();
service = new LoggingDecorator(service);
service = new MonitoringDecorator(service);

service.performTask(); 
// 这将输出:
// Logging: Task is starting
// Performing a task
// Logging: Task has finished
// Monitoring: Task took [执行时间] milliseconds

业务规则的扩展

在企业应用中,装饰模式可以动态地添加或修改业务规则或流程,而不需要修改现有的类。

// npm run code src/code/design-pattern/decorator/extensions-of-business-rules.ts

export {};

class BusinessProcess {
    execute(): void {
        console.log("Executing standard business process");
        // ... 标准业务流程的代码 ...
    }
}

abstract class BusinessProcessDecorator extends BusinessProcess {
    protected wrapped: BusinessProcess;

    constructor(businessProcess: BusinessProcess) {
        super();
        this.wrapped = businessProcess;
    }

    execute(): void {
        this.wrapped.execute();
    }
}

class AuditDecorator extends BusinessProcessDecorator {
    execute(): void {
        console.log("Audit: Before execution");
        super.execute();
        console.log("Audit: After execution");
    }
}

class ValidationDecorator extends BusinessProcessDecorator {
    execute(): void {
        console.log("Validation: Before execution");
        if (this.validate()) {
            super.execute();
        } else {
            console.log("Validation: Failed");
        }
    }

    private validate(): boolean {
        // ... 验证逻辑 ...
        return true; // 假设验证总是通过
    }
}

let process = new BusinessProcess();
process = new AuditDecorator(process);
process = new ValidationDecorator(process);

process.execute(); 
// 输出将包括审计和验证信息,以及执行标准业务流程

Web服务的中间件

在Web开发中,装饰模式可以用于添加中间件功能,而不需要改变核心逻辑。中间件是一种常见的用于处理诸如身份验证、错误处理和日志记录等跨切面关注点的机制。

// npm run code src/code/design-pattern/decorator/middleware.ts

export {};

interface WebService {
    handleRequest(request: string): string;
}

class BasicWebService implements WebService {
    handleRequest(request: string): string {
        // 处理请求的核心逻辑
        return `Response to ${request}`;
    }
}

abstract class MiddlewareDecorator implements WebService {
    protected wrappedService: WebService;

    constructor(service: WebService) {
        this.wrappedService = service;
    }

    handleRequest(request: string): string {
        return this.wrappedService.handleRequest(request);
    }
}

class AuthenticationMiddleware extends MiddlewareDecorator {
    handleRequest(request: string): string {
        console.log("Authentication Middleware: Checking authentication");
        // 添加身份验证逻辑
        return super.handleRequest(request);
    }
}

class ErrorHandlingMiddleware extends MiddlewareDecorator {
    handleRequest(request: string): string {
        try {
            return super.handleRequest(request);
        } catch (error) {
            return "ErrorHandling Middleware: An error occurred";
        }
    }
}

class LoggingMiddleware extends MiddlewareDecorator {
    handleRequest(request: string): string {
        console.log(`Logging Middleware: Received request ${request}`);
        const response = super.handleRequest(request);
        console.log(`Logging Middleware: Sending response ${response}`);
        return response;
    }
}

let service: WebService = new BasicWebService();
service = new AuthenticationMiddleware(service);
service = new ErrorHandlingMiddleware(service);
service = new LoggingMiddleware(service);

const response = service.handleRequest("user request");
console.log(response);

上次编辑于: