TypeScript 设计模式之【装饰模式】

news/2024/11/17 1:53:12/

文章目录

  • **装饰模式**:为你的对象穿上华丽的外衣
  • 装饰者的魔法
    • 装饰模式有什么利与害?
    • 如何使用装饰者来美化你的对象
    • 代码实现案例
    • 装饰模式的主要优点
    • 装饰模式的主要缺点
    • 装饰模式的适用场景
    • 总结

在这里插入图片描述

装饰模式:为你的对象穿上华丽的外衣

嘿程序员,你有一件普通格子衬衫,它很舒适,但有时候你可能想让它看起来更特别一些。你可以给它加上一些别针、徽章或者刺绣,让它变得与众不同。

这就像是在编程中使用装饰模式,你可以在不改变原始对象的情况下,为它添加新的功能或者修改它的行为。装饰模式就像是一位时尚设计师,能够为你的对象设计出各种华丽的"外衣"!

在这里插入图片描述

装饰者的魔法

装饰模式就像是给你的对象穿上一层又一层的"衣服",每一层都可以添加新的功能或者修改现有的行为,而且你可以随时添加或移除这些"衣服",非常灵活。

装饰模式有什么利与害?

装饰模式的优点是它可以在不修改原始代码的情况下扩展对象的功能,就像你可以给衬衫添加各种装饰而不需要改变衬衫本身。它遵循开闭原则,对扩展开放,对修改关闭。缺点是如果过度使用,会导致代码中出现大量小对象,使系统变得复杂难懂。

如何使用装饰者来美化你的对象

装饰涉及角色

  • 组件(Component):定义可以动态添加职责的对象的接口

  • 具体组件(ConcreteComponent):定义可以添加额外职责的对象

  • 装饰(Decorator):维持一个指向Component对象的引用,并定义一个与Component接口一致的接口。

  • 具体装饰(ConcreteDecorator):向组件添加职责。

装饰步骤

  1. 创建一个基础组件接口

  2. 实现具体的基础组件

  3. 创建一个装饰器基类,实现了组件接口并包含一个组件引用

  4. 创建具体的装饰器类,继承自装饰器基类并添加新的行为

  5. 使用这些装饰器来包装组件,从而动态地添加新的功能

选择合适的装饰器,你就能轻松地为你的对象添加各种功能,让它变得更加强大和灵活!

代码实现案例

typescript">// 组件接口-衬衫
interface Shirt {// 获取外表   getDescription(): string;// 获取成本getCost(): number;
}// 具体组件-普通衬衫
class BasicShirt implements Shirt {getDescription(): string {return "普通格子衬衫";}getCost(): number {return 100;}
}// 装饰器基类
abstract class ShirtDecorator implements Shirt {protected shirt: Shirt;constructor(shirt: Shirt) {this.shirt = shirt;}getDescription(): string {return this.shirt.getDescription();}getCost(): number {return this.shirt.getCost();}
}// 具体装饰器:别针
class PinDecorator extends ShirtDecorator {getDescription(): string {return `${this.shirt.getDescription()}, 加上别针`;}getCost(): number {return this.shirt.getCost() + 20;}
}// 具体装饰器:徽章
class BadgeDecorator extends ShirtDecorator {getDescription(): string {return `${this.shirt.getDescription()}, 加上徽章`;}getCost(): number {return this.shirt.getCost() + 15;}
}// 具体装饰器:刺绣
class EmbroideryDecorator extends ShirtDecorator {getDescription(): string {return `${this.shirt.getDescription()}, 加上刺绣`;}getCost(): number {return this.shirt.getCost() + 50;}
}// 使用装饰器
let shirt: Shirt = new BasicShirt();
console.log(shirt.getDescription()); // 输出: 普通格子衬衫
console.log(shirt.getCost()); // 输出: 100shirt = new PinDecorator(shirt);
console.log(shirt.getDescription()); // 输出: 普通格子衬衫, 加上别针
console.log(shirt.getCost()); // 输出: 120shirt = new BadgeDecorator(shirt);
console.log(shirt.getDescription()); // 输出: 普通格子衬衫, 加上别针, 加上徽章
console.log(shirt.getCost()); // 输出: 135shirt = new EmbroideryDecorator(shirt);
console.log(shirt.getDescription()); // 输出: 普通格子衬衫, 加上别针, 加上徽章, 加上刺绣
console.log(shirt.getCost()); // 输出: 185

在这里插入图片描述

装饰模式的主要优点

  1. 灵活性强:通过组合不同的装饰器来创建各种不同的行为

  2. 遵循开闭原则:在不修改现有代码的情况下添加新的功能

  3. 比继承更加灵活:动态地添加或删除职责,而不是在编译时就确定

  4. 支持递归组合:用多个装饰器包装一个组件

装饰模式的主要缺点

  1. 可能会创建很多小对象:每个装饰器都是一个新的对象,如果过度使用可能会导致系统变得复杂。
  2. 装饰层次增多时会更复杂:如果有太多的装饰类,或许会让系统变得难以理解和维护
  3. 可能会导致错误配置:由于可以动态地添加装饰器,或许会因为错误的配置导致意外的行为

装饰模式的适用场景

  1. 需要在运行时动态地给对象添加额外的职责,而不希望改变原有对象的结构
  2. 希望通过组合而不是继承来扩展对象的功能
  3. 系统中有大量独立的扩展,为支持每种组合将产生大量的子类,使得子类数目呈爆炸性增长。

总结

装饰模式是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。这种模式在不修改现有对象结构的情况下动态地扩展对象的功能,它具有很强的灵活性和可扩展性,但也会导致系统中出现大量小对象。合理使用装饰模式,可以让你的代码更加灵活,更易于维护和扩展。

喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!

下期预告:TypeScript 设计模式之【外观模式】


http://www.ppmy.cn/news/1531200.html

相关文章

Linux网络——HTTPS详解

文章目录 HTTPS加密 常见加密方式对称加密非对称加密非对称对称数据指纹 证书CA认证数字签名非对称证书对称 中间人 HTTPS 这也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层 为什么要加密呢,这主要是因为如果不对传输主体加密,当…

webstorm新建一个新vue项目用命令解决

在WebStorm中直接通过命令新建一个Vue项目,通常意味着你需要先确保你的电脑上安装了Node.js和npm(或yarn),然后全局安装Vue CLI。Vue CLI是一个基于Vue.js进行快速开发的完整系统,提供了从零开始搭建Vue项目所需的所有…

Linux驱动开发(速记版)--并发与竞争

第十八章 并发与竞争 18.1 并发与竞争 18.1.1 并发 早期计算机 CPU单核心时,由于 CPU执行速度快于I/O操作,常因等待 I/O而空闲。 为提高 CPU利用率,引入了并发执行理论。并发通过算法在CPU执行I/O等待时切换至其他任务,使多个任…

Mybatis映射文件详解-mapper.xml文件

在Mybatis中,Mapper XML文件是用于定义SQL语句和Java方法之间映射关系的核心配置文件。通过这些文件,开发者可以将数据库中的表与Java对象进行映射,实现数据的持久化操作。本文将详细介绍Mybatis映射文件的相关知识,包括其结构、标…

js 如何监听 body 内容是否改变

如果您想监听body内容的变化,并作出响应,可以使用MutationObserver。以下是一个简单的例子,它会在body内容变化时在控制台输出一条消息: // 创建一个观察者对象 const observer new MutationObserver(function(mutations, obser…

001、restful设计规范

https://www.kancloud.cn/kancloud/rest-api-design-safety/78113 https://www.kancloud.cn/kancloud/http-api-design/78123 https://www.kancloud.cn/kancloud/http-api-guide/56268 restful接口设计规范 按照restful接口设计规范 GET (SELECT)&…

flutter 设置字体大小,适应各种屏幕

起因, 目的: 来源就是客户需求。 从个人角度来说,我讨厌 flutter, 和 java 一样, 都是 臃肿,繁琐,死板. 1. 过程: 根据用户的屏幕尺寸,把子元素大小, 字体的大小,都设置为百分比&…

Mac pnpm安装

安装pnpm的时候一定要把npm更新到最新版 不然pnpm下载不成功。 (更新npm):sudo npm install -g npm (安装pnpm:) sudo npm install -g pnpm 检验安装是否成功:pnpm --version 项目内安装依赖:pnpm install / 运行项目&…