装饰模式
约 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);