专栏首页java程序员思维Head First 设计模式之装饰器模式,因为参与,所以认同

Head First 设计模式之装饰器模式,因为参与,所以认同

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

装饰器模式解决的问题

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

装饰器模式角色

Component(抽象组件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。

ConcreteComponent(具体组件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。

Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。

ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。

使用场景

咖啡店里咖啡中可以加不同的配料,摩卡、牛奶、糖、奶泡。手抓饼可以有不同的搭配,可以增加香肠、培根、里脊肉等等,计算增加不同的配料需要多少钱?

代码实现

之前我们讲过策略模式,如果使用策略模式,需要穷举列出所有的组合,种类越多,对于程序员来说是一种灾难性的打击。装饰器模式是一种不错的选择,能够很好的解决问题,增加一种配料或者装饰,只需要增加一个具体的装饰类即可,满足开闭原则。

/**
 *
 * 装饰器模式
 * 抽象组件 -- 对应Coffee类
 */
public interface Coffee {
 public double cost();
}
/**
 *
 * 具体组件 --无咖啡因
 *
 * 无咖啡因咖啡 8元
 *
 */
public class Decaf implements Coffee{
 public double cost() {
 return 8;
 }
}
/**
 * Created by zengjianlu on 2018/2/23.
 *
 * 具体组件--浓咖啡
 *
 * 浓咖啡 10元
 */
public class Espresso implements Coffee{
 public Espresso(){
 System.out.println("1杯浓咖啡 10元");
 }
 public double cost() {
 return 10.0;
 }
}
/**
 *
 *装饰类
 *
 */
public class Decorator implements Coffee{
 private Coffee coffee;
 public Decorator(Coffee coffee) {
 this.coffee = coffee;
 }
 public double cost() {
 return coffee.cost();
 }
}
/**
 * 加摩卡 3元
 */
public class Mocha extends Decorator{
 public Mocha(Coffee coffee) {
 super(coffee);
 System.out.println("增加摩卡 3元");
 }
 public double cost(){
 return super.cost() + 3;
 }
}
/**
 * 加糖 两元
 */
public class Sugar extends Decorator{
 public Sugar(Coffee coffee) {
 super(coffee);
 System.out.println("增加糖 2元");
 }
 public double cost(){
 return super.cost() + 2;
 }
}

定义一个抽象组件Coffee,两个具体组件,Decaf和Espresso,定义了装饰类Decorator,实现了抽象组件接口,拥有了抽象组件的行为。

以上代码,价格都是固定的,如果想要动态管理,可以通过数据库Mysql,或者动态配置中心Apollo进行管理。

/**
 * 买了一杯浓咖啡 加摩卡 加糖
 * 测试类
 */
public class Test {
 public static void main(String[] args) {
 Coffee coffee = new Espresso();
 coffee = new Mocha(coffee);
 coffee = new Sugar(coffee);
 System.out.println("一共:" + coffee.cost());
 }
}

运行结果:

优缺点

优点:动态的给一个对象添加一些额外的职责,就扩展功能而言,比生成子类方式更为灵活。

缺点:装饰器模式虽然从数量级上减少了类的数量,但是为了要装饰,仍旧会增加很多的小类这些具体的装饰类的逻辑将不会非常的清晰,不够直观,容易令人迷惑。

生活中的装饰模式

房子装修,地板可以用瓷砖、木板,冰箱、电视可以使用不同的品牌。房子的主人可以根据自己的喜好,添加不同的装饰品,具有很强的灵活性。

服饰搭配,去逛商店,买衣服时,可以搭配不同小饰品,比如眼镜、帽子、围巾等等,有时候你只想买个衬衫,导购员可能会给你推荐一件毛衣,或者一件裤子,让你一起搭配,如果你自己也比较喜欢的话,可能三件都会购买。

我的启发

装饰器模式,让我们参与其中,自由的组合,形成自己的独特风格。因为参与,所以认同。

设计模式系列历史:

Head first 设计模式之策略模式,来源于生活,用之于生活

Head First 设计模式之观察者模式,你我都是发布者和订阅者

Head First 设计模式之单例模式,每个人都是唯一

本文分享自微信公众号 - java程序员思维(java_python_go),作者:曾建路

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java设计模式之迭代器模式,顾客永远的上帝

    迭代器模式(Iterator Pattern)提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。这种类型的设计模式属于行为型模式。

    用户4361942
  • java设计模式之工厂模式

    工厂模式(Factory Pattern)提供了一种创建对象的方式,创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,属于创建...

    用户4361942
  • java设计模式之代理模式,看我72

    代理模式(Proxy Pattern)一个类代表另一个类的功能,通过代理对象访问目标对象,可以在目标对象实现的基础上,增强额外的功能。

    用户4361942
  • 3. 站在使用层面,Bean Validation这些标准接口你需要烂熟于胸

    通过前两篇文章的叙述,相信能勾起你对Bean Validation的兴趣。那么本文就站在一个使用者的角度来看,要使用Bean Validation完成校验的话我...

    YourBatman
  • Android热更新之微信Tinker集成(接入Bugly热更新)

    最近公司项目中需要集成热更新功能,由于刚开始接入的时候踩了很多坑,所以现在记录一下集成的过程.

    SoullessCoder
  • 使用SQL Server作业设置定时任务

    1.开启SQL Server Agent服务   使用作业需要SQL Agent服务的支持,并且需要设置为自动启动,否则你的作业不会被执行。 以下步骤开启服务:...

    Java中文社群-磊哥
  • 利用easyui实现增删改查(四):搜索数据

    以上的搜索框就有easyui的样式,现在给这个搜索框一个点击事件:在写easyui样式的代码里面加一个点击事件

    一天不写程序难受
  • 【Chromium中文文档】Chromium如何展示网页

    这个文档从底层描述了Chromium是如何展示网页的。请确认你已经读过多进程架构这篇文章。你会特别想要了解主要组件的框架。你也可能对多进程资源加载感兴趣,以了解...

    梦里茶
  • Python 爬虫之Selenium终极绝招

    这里简单解释一下什么是Selenium,它其实是一个网站前端压力测试框架,更通俗的说,它能直接操作浏览器,试想一下,网页是在浏览器里面加载的,如果我们能用代码操...

    arcticfox
  • 在B站看猫片被老板发现?不如按下F12学学HTTP

    HTTP 全称超⽂文本传输协议,也就是HyperText Transfer Protocol。 其中我们常见的文本,图片,视频这些东西都可以用超文本进行表示,而...

    9号同学

扫码关注云+社区

领取腾讯云代金券