装饰模式

1.概念

动态地为对象附加上额外的职责

其目的是包装一个对象,从而可以在运行时动态添加新的职责。每个装饰器都可以包装另一个装饰器,这样理论上来说可以对目标对象进行无限次的装饰。

2.装饰器类图

3.代码

一个早餐店经营两种主食:汉堡和吐司,一段时间后需要加个配料。

主要思路是:以主食(汉堡、吐司)为主体,然后再运行时以配料(火腿、起司)装饰为主食。其UML图为:



(1)抽象构建类————Breakfast.java,早餐的抽象父类

public abstract class Breakfast {
public String description="未知";
public String getDescription(){
return description;
}
public abstract Double cost();
}

(2)抽象装饰类————CondimentDecorator.java,是早餐抽象类的子类

public abstract class CondimentDecorator extends Breakfast{
Breakfast myfood;
public CondimentDecorator(Breakfast myfood){
this.myfood=myfood;
}
@Override
public String getDescription(){
return myfood.getDescription();
}
@Override
public Double cost(){
return myfood.cost();
}
}

(3)具体构建类————Toast.java、Burger.java

Toast.java

public class Toast extends Breakfast {
public Toast(){
description="吐司";
}
public Double cost(){
return 10d;
}
}

Burger.java

public class Burger extends Breakfast {
public Burger(){
description="汉堡";
}
@Override
public Double cost(){
return 15d;
}
}

(4)具体装饰类————Cheese.java、Ham.java

Cheese.java

public class Cheese extends CondimentDecorator {
public Cheese(Breakfast myfood) {
super(myfood);
} @Override
public Double cost() {
return super.cost() + 5;
} @Override
public String getDescription() {
return super.getDescription() + ",起司";
}
}

Ham.java

public class Ham extends CondimentDecorator {
public Ham(Breakfast myfood) {
super(myfood);
} @Override
public Double cost() {
return super.cost() + 10;
} @Override
public String getDescription() {
return super.getDescription() + ",火腿";
}
}

(5)客户端测试类

public class Decorator {
public static void main(String args[]) {
Breakfast breakfast1 = new Toast();
System.out.println("您点的餐点为:" + breakfast1.getDescription() + "。价格为:" + breakfast1.cost());
Breakfast breakfast2 = new Toast();
breakfast2 = new Ham(breakfast2);
breakfast2 = new Ham(breakfast2);
System.out.println("您点的餐点为:" + breakfast2.getDescription() + "。价格为:" + breakfast2.cost());
Breakfast breakfast3 = new Burger();
breakfast3 = new Ham(breakfast3);
breakfast3 = new Cheese(breakfast3);
breakfast3 = new Cheese(breakfast3);
System.out.println("您点的餐点为:" + breakfast3.getDescription() + "。价格为:" + breakfast3.cost());
}
}

结果

您点的餐点为:吐司。价格为:10.0
您点的餐点为:吐司,火腿,火腿。价格为:30.0
您点的餐点为:汉堡,火腿,起司,起司。价格为:35.0

详细见:Java设计模式

装饰者模式——Java设计模式的更多相关文章

  1. 设计模式之装饰者模式-java实例

    设计模式之装饰者模式 需求场景 我们有了别人提供的产品,但是别人提供的产品对我们来说还不够完善,我们需要对这个产品的功能进行补强,此时可以考虑使用装饰者模式. 我们已经有了产品,而且这个产品的功能非常 ...

  2. 悟空模式-java设计模式

    目前已定义的java设计模式细分下来有二十余种,这篇博客主要是想从大家所熟知的孙悟空入手,阐述各个设计模式的概念和优缺点,以及他们之间的联系. 在下面介绍的每个设计模式里,都会有与西游记相关的具体案例 ...

  3. DecoratorPattern(装饰器模式)-----Java/.Net

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

  4. 装饰者模式--Java篇

    装饰者模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更为灵活. 1.定义接口,可以动态的给对象添加职责. package com.lujie; p ...

  5. 工厂模式——java设计模式

    工厂模式 目录 何为工厂模式 工厂方法与抽象工厂 如何在Java EE中通过@Producers与@Inject注解实现工厂模式 如何创建自定义注解以及通过@Qualifier消除具体实现之间的歧义 ...

  6. 代理模式——java设计模式

    代理模式(Proxy Pattern) GoF中给出的代理模式的定义为: 代理模式给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问. 代理模式的英文叫做Proxy或Surrogate ...

  7. 生产者和消费者模式--java设计模式

    生产者和消费者: 就犹如在快餐店点餐一样,有多个打饭的,有不定时的人来买饭,买饭的人从快餐店自动取餐,如果快餐的库存数量达到下限值时,自动启动打饭的,补充盒饭. 通过while循环的方式,传入变量is ...

  8. Java设计模式之装饰者模式

    要实现装饰者模式,注意一下几点内容: 1.装饰者类要实现真实类同样的接口 2.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入) 3.装饰类对象在主类中接受请求,将请求发送给真实的对象(相 ...

  9. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

随机推荐

  1. SPRING框架中ModelAndView、Model、ModelMap区别及详细分析

    转载内容:http://www.cnblogs.com/google4y/p/3421017.html 1. Model Model 是一个接口, 其实现类为ExtendedModelMap,继承了M ...

  2. AngularJS $scope 继承性 作用 生命周期

    一.基本概念 作用域是一个指向应用模型的对象,相当于MVVM中的ViewModel,能绑定数据(属性)和行为(方法),能监控表达式和传递事件,是实现双向绑定的基础,是应用在 HTML (视图) 和 J ...

  3. 论EFMS模拟量部分采集电路的修改

    论1:电阻R11的作用 如图1是2014-3-11之前模拟量采集的部分硬件电路,图2是纠正后的正确电路. D5是SA20CA,TVS双向二极管,有效防止外接电源的浪涌冲击情况,保护电路.  D6是稳压 ...

  4. [php-array] PHP 数组的怪异之处

    // 指定加拿大的 index 为 0 $mobileNation = array( 86 => '中国 + 0086', 44 => '英国 + 0044', 1 => '美国 + ...

  5. Android-Java静态代码块&局部代码块

    静态代码块: 静态代码块什么时候执行,是由当前类被加载进内存的时候,什么时候当前类被加载进内存? 答:例如 描述好了Student对象,当 new Student(); 的时候,第一步:是把Stude ...

  6. Android-Kotlin简单计算器功能

    上一篇博客 Android-Kotlin-配置/入门 配置好了 AndroidStudio Kotlin 的环境: 选择包名,然后右键: 选择Class类型,会有class: 创建CounterCla ...

  7. C#如何在List里求某一列的數值的和SUM

    var X=Xlist.Sum(key => key.XXX);

  8. android.os.NetworkOnMainThreadException的解决方案

    06-24 18:04:36.857: E/AndroidRuntime(22251): FATAL EXCEPTION: main 06-24 18:04:36.857: E/AndroidRunt ...

  9. Redis-HA高可用方案Sentinel配置

    上一节中介绍了master-slave模式,在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的”读/写功能都将受影响,这在生产环境中显然 ...

  10. ovs stp

    环路拓扑 组成拓扑结构的脚本 构成连通脚本 ip netns add ns1 ovs-vsctl add-br br1 ovs-vsctl add-port br1 tap1 -- set Inter ...