装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。

这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。模拟一个人从想吃饭、找饭店、享受美食、结束吃饭的过程

代码展示:

首先创建一个被修饰的接口 Eat

package decorator;
//吃饭接口
public interface Eat {//吃饭方法void eat();
}

创建一个被修饰者并且有自己的状态

package decorator;public class Person implements Eat {@Overridepublic void eat() {System.out.println("======我饿了======");}
}

创建一个修饰者的抽象类

package decorator;public abstract class LikeEat implements Eat {private Eat eat;public LikeEat(Eat eat) {this.eat=eat;}@Overridepublic void eat() {eat.eat();}}

创建五个修饰类的扩展类(即--扩展修饰),分别拥有自己特定的状态,丰富被修饰的类

public class FindInMap extends LikeEat {public FindInMap(Eat eat) {super(eat);}public void userMap(){System.out.println("打开地图寻找美食");}@Overridepublic void eat() {super.eat();userMap();}
}public class GotoRestaurant extends LikeEat {public GotoRestaurant(Eat eat) {super(eat);}public void onWay(){System.out.println("去往饭店的路上");}@Overridepublic void eat() {super.eat();onWay();}}public class InRestaurant extends LikeEat {public InRestaurant(Eat eat) {super(eat);}public void selectFoot(){System.out.println("到达饭店选择食物");}@Overridepublic void eat() {super.eat();selectFoot();}}public class EatFoot extends LikeEat {public EatFoot(Eat eat) {super(eat);}public void eating(){System.out.println("享用美食中");}@Overridepublic void eat() {super.eat();eating();}}public class endEat extends LikeEat {public endEat(Eat eat) {super(eat);}public void afterEat(){System.out.println("=====美食结束=====");}@Overridepublic void eat() {super.eat();afterEat();}
}

创建测试类,测试修饰效果

public class EatTest {public static void main(String[] args) {Eat person = new Person();likeEat likeEat = new endEat(new EatFoot(new InRestaurant(new GotoRestaurant(new FindInMap(person))))) ;likeEat.eat();}
}

运行结果:

总结:
A、LikeEat抽象类中,持有Eat接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
B、LikeEat抽象类的子类(具体装饰者),里面都有一个构造方法调用super(eat),这一句就体现了抽象类依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是Eat接口,只要是该Eat的实现类都可以传递进去,即表现出

          likeEat likeEat = new endEat(
                    new EatFoot(
                      new InRestaurant(
                        new GotoRestaurant(
                          new FindInMap(person)))))

这种结构的样子。所以当调用likeEat.eat()的时候,又因为每个具体装饰者类中,都先调用super.eat();方法,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。

C、具体被装饰者,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
D、装饰者模式的设计原则为:

  对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。

 使用装饰器模式--------《模拟一个电话套餐选择场景》

 创建套餐账单的基本信息-----需要被修饰 的抽象类

package order;public abstract class Order {String name;public String getOrder(){return name;}public abstract int price();
}

创建基账单的信息类,未修饰时有自己的初始状态-----被修饰对象

package order;public class BuyOrder extends Order {public BuyOrder(){name = "您选的套餐是:基本套餐";}public String getOrder(){return super.getOrder();}public int price(){return 10;}
}

 创建修饰基类-----一切修饰的扩展是在此基础上扩展的

package order;
//额外套餐的基础类
public abstract class BuyOrder00 extends Order {public abstract String getOrder();
}

 创建修饰类的扩展类------套餐的详细修饰情况(语音+流量+短信)

package order;public class BuyOrderNet extends BuyOrder00 {private Order order;public BuyOrderNet(Order order) {super();this.order = order;}@Overridepublic String getOrder() {return order.getOrder()+"+上流流量套餐";}@Overridepublic int price() {return order.price()+20;}}package order;public class BuyOrderTalk extends BuyOrder00 {private Order order;public BuyOrderTalk(Order order) {super();this.order = order;}@Overridepublic String getOrder() {return order.getOrder()+"+语音套餐";}@Overridepublic int price() {return order.price()+15;}}package order;public class BuyOrderMSG extends BuyOrder00 {private Order order;public BuyOrderMSG(Order order) {super();this.order = order;}@Overridepublic String getOrder() {return order.getOrder()+"+短信套餐";}@Overridepublic int price() {return order.price()+10;}}

 测试用户选择的不同套餐情况

public class OrderTest {public static void main(String[] args) {Order order = new BuyOrder();System.out.println(order.getOrder()+"\t月资费是:"+order.price());BuyOrder00 order1 = new BuyOrderTalk(order);System.out.println(order1.getOrder()+"\t月资费是:"+order1.price());BuyOrder00 order2 = new BuyOrderNet(order);System.out.println(order2.getOrder()+"\t月资费是:"+order2.price());BuyOrder00 order3 = new BuyOrderMSG(order);System.out.println(order3.getOrder()+"\t月资费是:"+order3.price());BuyOrder00 order4 = new BuyOrderMSG(order2);System.out.println(order4.getOrder()+"\t月资费是:"+order4.price());BuyOrder00 order5 = new BuyOrderMSG(order1);System.out.println(order5.getOrder()+"\t月资费是:"+order5.price());BuyOrder00 order6 = new BuyOrderNet(order1);System.out.println(order6.getOrder()+"\t月资费是:"+order6.price());BuyOrder00 order7 = new BuyOrderNet(new BuyOrderMSG(new BuyOrderTalk(order)));System.out.println(order7.getOrder()+"\t月资费是:"+order7.price());}}

 运行结果

建议多打几个断点观察流程情况,一边更好的理解装饰器模式的工作流程

转载于:https://www.cnblogs.com/kuoAT/p/6951706.html

java设计模式之 装饰器模式相关推荐

  1. (设计模式七)java设计模式之装饰器模式

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

  2. java设计模式之装饰器模式

    一.装饰器模式简介 装饰器模式可以动态给一个对象添加一些额外的职责,同时又不改变其结构.就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.这种模式创建了一个装饰 ...

  3. Java 设计模式之装饰器模式

    装饰器模式用于给原有对象增加新功能的场景, 拿食物冰淇淋,香草巧克力作为例子,给冰淇淋加香草,或者加巧克力,或者加香草和巧克力. 首先定义一个食物接口: /*** 装饰类和被装饰类共同继承的抽象类* ...

  4. java设计模式之装饰器模式(包装器模式)

    显然设计模式往往追求开闭原则,所以往往是面向接口编程,那么万事万物就是先写接口,把需求弄出来,这里以一辆车子在陆地上跑为基础,对它进行装饰,使它可以具备更多的"功能",达到装饰的效 ...

  5. 设计模式学习----装饰器模式

    这两天本来是自在学习java collection Framework的Fail Fast底层机制,看到核心的部分时,突然意识到设计模式的问题,上大学到现在我还没有真正理解过设计模式的概念,于是用了大 ...

  6. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  7. 【设计模式】装饰器模式的使用

    问题来源 我们在进行软件系统设计的时候,有一些业务(如下图,一些通用的非功能性需求)是多个模块都需要的,是跨越模块的.把它们放到什么地方呢? 最简单的办法就是把这些通用模块的接口写好,让程序员在实现业 ...

  8. go设计模式之装饰器模式

    go设计模式之装饰器模式 再写这篇文章时,我已经看了很多其他人发表的类似文章,大概看了这么多吧. 亓斌的设计模式-装饰者模式(Go语言描述) jeanphorn的Golang设计模式之装饰模式 七八月 ...

  9. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

最新文章

  1. 怎么删除XP中无法删除的文件
  2. 字节跳动算法工程师总结:java接口实验报告总结
  3. mysql 创建师徒_mysql基础整理
  4. vue 组件之间函数传递_组件之间相互传递参数
  5. 实战分享之专业领域词汇无监督挖掘
  6. Neutron 分布式虚拟路由(Neutron Distributed Virtual Routing)
  7. java如何添加同名的xml节点_jaxb怎么解析多个同名元素
  8. openssl创建私有ca
  9. Java基础---集合的概述---list、set、map、泛型、collections
  10. mysql表连接_SELECT中的多表连接
  11. SpringBoot 解决“不支持发行版本xx”的问题
  12. java httpclient 包_java实现http请求之HttpClient
  13. NotePad++ 调试PHP代码中文显示乱码
  14. raw,qcow2虚拟磁盘挂载
  15. 和秋叶一起学PPT之绘制表格(课时七)
  16. 如何才能实现文字转语音播放?只要这三个步骤就能快速搞定!
  17. ThingJS图表整合
  18. html+css 炫彩流光按钮
  19. Guzzle中的异步请求
  20. 2021年中国互联网企业100强(附名单)

热门文章

  1. 在vb中实现真正锁定的带自定义菜单的文本控件
  2. 10种K线组合给出买进信号
  3. 智能一代云平台(三十三):log4j日志研究
  4. 英语总结系列(二十四):历经GCT的一月
  5. 网络中的哪些事儿(四)之路由器中的有趣Ping实验
  6. 路透社:美国打算限制英伟达等与中国人工智能界合作
  7. 加州出台严格无人车路测新政:要求各公司尽快申请部署许可
  8. NASA无人机障碍赛:专业选手Vs.人工智能,赌一赌谁赢?
  9. CentOS7 系统升级,删除centos7开机界面多余选,升级至最新的内核
  10. 一次大意引发的“大”故障