23种设计模式之装饰者模式

装饰者模式

定义及特点

装饰者模式 是不改变原类文件和使用继承的情况下,动态的扩展对象的一个功能,通过创建一个包装对象,也就是装饰来包裹真实的对象。它遵循了开闭原则,对扩展开放,对修改关闭。有以下几个特点:

  • 装饰对象和真实对象有相同的接口,这样就方便了装饰对象和真实对象之间的交互
  • 装饰对象包含了一个真实对象的引用
  • 装饰对象接受了来自所有客户端的请求,并转发给真实对象
  • 装饰对象可在转发这些请求之前或之后添加一些附件功能

使用场景

  1. 扩展一个类的功能
  2. 动态给一个对象添加功能,同时也可动态撤销
  3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实

优缺点

优点:

  1. 装饰者模式与继承关系的目的都是要扩展对象的功能,但是装饰者可以提供比继承更多的灵活性
  2. 装饰者模式可使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合

缺点:

  1. 灵活使用的同时,增加了类的复杂性
  2. 类的数量繁多,过度使用会使程序变得复杂
  3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

角色组成

  1. 抽象构件(Component)角色: 给出一个抽象接口,以规范准备接收附加责任的对象。
  2. 具体构件(Concrete Component)角色: 定义一个将要接收附加责任的类
  3. 装饰(Decorator)角色: 持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
  4. 具体装饰(Concrete Decorator)角色: 负责给构件对象添加上附加的责任。

代码示例

星巴克订单问题:

  1. 咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
  2. 调料:Milk、Soy(豆浆)、Chocolate
  3. 要求具有良好的扩展性,改动方便、维护方便
  4. 计算不同种类的费用:客户可单点咖啡,要也可以点单品咖啡+调料组合

具体代码实现: https://gitee.com/ldj123/design-patterns.git

IO流,装饰者模式的实现

    DataInputStream dis = new DataInputStream(new FileInputStream("d://abc.txt"));
    System.out.println(dis.read());
    dis.close();

说明:

  1. InputStream是抽象类 ,类似代码实现中的Drink
  2. FileInputStream 是InputStream的子类 类似代码实现中的DeCaf,LongBlack
  3. FilterInputStream 是InputStream的子类 类似代码实现中的Decorator 修饰者
  4. DataInputStream 是FilterInputStream 的子类 具体的修饰者 类似代码实现中Soy
  5. FilterInputStream 类有protected volatile InputStream in 即被修饰者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值