结构型模式之装饰者模式

装饰者模式是一种结构型设计模式,用于在不修改对象原有结构的情况下动态添加职责。它通过抽象构件类、具体构件类、抽象装饰类和具体装饰类的组合,实现功能的灵活扩展。相较于继承,装饰者提供了更佳的扩展性,避免了类爆炸问题。在Java IO流中广泛应用,如BufferedReader等。装饰者模式与代理模式相似,但主要区别在于装饰者增强目标对象,而代理模式则更多用于控制访问。
摘要由CSDN通过智能技术生成

源代码

装饰者模式

装饰者模式可以在不改变现有对象结构的情况下,动态的给该对象增加一些职责(就是加一些额外的功能)。

结构

  1. 抽象构件类(Component):定义一个抽象类或接口来规范那个要加额外功能的对象。
  2. 具体构件类(ConcreteComponent):实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰类(Decorator):继承或实现抽象接口,并且包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰类(ConcreteDecorator):实现抽象装饰类的具体方法,并给具体构件类添加职责。

案例

去快餐店点菜,我们可以点一个炒饭,然后加个蛋,加个牛肉。点一份炒饭就是具体构建类,加个蛋,加个牛肉就是额外添加的职责。
当然我们也可以使用继承的方式,让一个蛋炒饭继承炒饭,牛肉炒饭继承炒饭。但是这样的类或过多,而且扩展性不好。
类图如下,最关键的点就是ExtFood抽象类,他既继承了FastFood又引用了FastFood。

public class test {
    public static void main(String[] args) {
        Rice rice=new Rice();
        System.out.println(rice.getName()+":" +rice.cost());
        Egg egg=new Egg(rice);
        System.out.println(egg.getName()+":" +egg.cost());
        Beef beef=new Beef(egg);
        System.out.println(beef.getName()+":" +beef.cost());
    }
}

输出:
炒饭:10.0
炒饭加鸡蛋:11.0
炒饭加鸡蛋加牛肉:16.0

优点

  • 装饰者模式可以带来比继承更加灵活的扩展功能,使用更加方便。可以通过组合不同的具体装饰类来获得又不同功能的多样化的结果。遵守了开闭原则。继承是静态的附加责任(写死的),装饰者是动态的附加责任。
  • 具体装饰类和具体构件类可以互相独立扩展不会耦合。(可以添加火腿肠、炒面啥的)。装饰者模式可以动态扩展实现类的功能。

使用场景

  1. 当不能或不方便使用继承的方式对系统进行扩展时。
    • 比如系统里面有大量独立的扩展,这样为了支持他们的组会就会有爆炸多的子类。
    • final类
  2. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  3. 对象的功能需要动态的添加和拆卸时。(鸡蛋卖完了,就把鸡蛋类删掉)

JDK中的案例

IO流中的包装类使用了装饰者模式。BufferedXXXXX
BufferedWriter的类图,关键在右边的既继承又聚合。

和代理模式的区别

  • 相同点

    • 都要实现和目标类相同的目标对象。
    • 都要在类里面声明目标对象。
    • 都可以在不修改目标类的情况下扩展目标方法。
  • 不同点

    • 装饰者是为了增强目标对象,代理模式是为了保护和隐藏对象
    • 装饰者中声明的目标对象是外界传进来的,代理模式的是在类里面创建的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值