Java设计模式中的装饰者模式

 更新时间:2022年07月19日 10:02:14   作者:爱学习的大鱼​​​​​​​  
这篇文章主要介绍了Java设计模式中的装饰者模式,装饰者模式即Decorator Pattern,装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能

模式介绍

23种设计模式之一,英文叫Decorator Pattern,又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

UML类图

类图解析:

  • Componet:主体
  • ConcreateComponent:主体具体实现类
  • Decorator:装饰者
  • ConcreteDecorate:装饰者具体实现类

装饰者模式案例

背景介绍:有一家咖啡店,店中有许多品种的咖啡(ShortBlack、Decaf、Espresso…),咖啡可以添加不同口味(Chocolate、Milk、Soy等),采用装饰者模式可以很好的解决该问题

装饰者下单 (2份巧克力+1份牛奶+LangBlack) 如下图所示:

类结构图

Drink、Coffee及其子类代码如下:

public abstract class Drink {
    private String des;//描述
    private float price = 0.0f;
    /**
     * 计算价格的方法
     * @return
     */
    public abstract float cost();
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
}
public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}
public class ShortBlack extends Coffee{
    public ShortBlack() {
        setDes("浓缩咖啡");
        setPrice(4);
    }
}
public class Espresso extends Coffee{
    public Espresso() {
        setPrice(6);
        setDes("意大利咖啡");
    }
}
public class LongBlack extends Coffee{
    public LongBlack() {
        setPrice(5);
        setDes("美式咖啡");
    }
}

Decorator及其子类

public class Decorator extends Drink {
    private Drink drink;
    public Decorator(Drink drink) { // 聚合
        this.drink = drink;
    }
    @Override
    public float cost() {
        // 调料的价格 + 咖啡的价格
        return super.getPrice() + drink.cost();
    }
    @Override
    public String getDes() {
        return super.getDes() + " && " + drink.getDes();
    }
}
public class Chocolate extends Decorator{
    public Chocolate(Drink drink) {
        super(drink);
        setDes("巧克力");
        setPrice(3);
    }
}
public class Milk extends Decorator{
    public Milk(Drink drink) {
        super(drink);
        setDes("牛奶");
        setPrice(2);
    }
}
public class Soy extends Decorator{
    public Soy(Drink drink) {
        super(drink);
        setDes("豆浆");
        setPrice(1.5f);
    }
}

CoffeeBar测试类

public class CoffeeBar {
    public static void main(String[] args) {
        // 点一份咖啡
        Drink order = new LongBlack();
        System.out.println(order.cost() + "$\t" + order.getDes());

        // 加一份牛奶
        order = new Milk(order);
        System.out.println(order.cost() + "$\t" + order.getDes());

        // 加两份巧克力
        order = new Chocolate(order);
        System.out.println(order.cost() + "$\t" + order.getDes());
        order = new Chocolate(order);
        System.out.println(order.cost() + "$\t" + order.getDes());
    }
}

实现结果:

装饰者模式优点

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

装饰者模式缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

到此这篇关于Java设计模式中的装饰者模式的文章就介绍到这了,更多相关Java装饰者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java基于链表实现栈的方法详解

    Java基于链表实现栈的方法详解

    这篇文章主要介绍了Java基于链表实现栈的方法,结合实例形式详细分析了Java基于链表实现栈的原理、操作步骤与相关注意事项,需要的朋友可以参考下
    2020-03-03
  • SpringBoot2开发从0开始Spring Initailizr初始化

    SpringBoot2开发从0开始Spring Initailizr初始化

    这篇文章主要为大家介绍了SpringBoot2从0开始lombok、devtools、Spring Initailizr的开发技巧,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 使用JAR包中MANIFEST.MF的注意事项

    使用JAR包中MANIFEST.MF的注意事项

    这篇文章主要介绍了使用JAR包中MANIFEST.MF的注意事项,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java String类常用方法梳理总结

    Java String类常用方法梳理总结

    这篇文章主要介绍了Java String类常用方法梳理总结,类 String 中包括用于检查各个字符串的方法,比如用于比较字符串,搜索字符串,更多相关内容需要的朋友可以参考一下
    2022-06-06
  • 为什么Java项目中别用!=null做判空

    为什么Java项目中别用!=null做判空

    本文主要介绍了为什么Java项目中别用!=null做判空,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 关于@DS注解切换数据源失败的原因实战记录

    关于@DS注解切换数据源失败的原因实战记录

    项目配置了多个数据源,需要使用@DS注解来切换数据源,但是却遇到了问题,下面这篇文章主要给大家介绍了关于@DS注解切换数据源失败原因的相关资料,需要的朋友可以参考下
    2023-05-05
  • SpringCloud之Feign示例详解

    SpringCloud之Feign示例详解

    本篇文章主要介绍了SpringCloud之Feign示例详解,详细的介绍了Feign简介和使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • SpringBoot如何统一JSON信息返回

    SpringBoot如何统一JSON信息返回

    这篇文章主要介绍了SpringBoot如何统一JSON信息返回问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 解决springboot 2.x集成log4j2调试日志无法关闭的问题

    解决springboot 2.x集成log4j2调试日志无法关闭的问题

    这篇文章主要介绍了解决springboot 2.x集成log4j2调试日志无法关闭的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 微信小程序与Java后端接口交互

    微信小程序与Java后端接口交互

    本文主要介绍了微信小程序与Java后端接口交互,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论