装饰模式

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. kepware http接口 c语言(libcrul)开发

    列出所有变量 CURL *hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET"); ...

  2. python常用算法题

    一: #计算平均数,中位数和众数 #coding:utf-8 #计算平均数,中位数和众数 import random lst = [random.randint(0,10) for i in rang ...

  3. 在Ubuntu上安装pyenv

    因为找到一个域名枚举的脚本使用Python3编写的,而我一直习惯的是使用Python2.7,在自己的Windows7上再安装个Python怕混了,于是想着在VPS上装个Python的版本管理工具,也方 ...

  4. javaweb获取项目路径的方法

    在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是WebRoot/WEB-INF/classes 当然你也可以用System.getPro ...

  5. SPFA_queue_链式前向星最短路 & HDU2433

    题目大意:看完之后,觉得不肯能让我暴力,比较好想的就是初始化——每个点都求个最短路spfa,sum数组记录每个点到各个点的最短路之和,ans作为总和,之后一一删除边u-v,求关于u的最短路,如果dis ...

  6. npm 及安装

    一.npm nodejs使开发者摆脱了浏览器的束缚,一系列基于nodejs的应用和工具不断出现,无论是在node应用的开发,还是使用中,包管理都扮演着一个很重要的作用.NPM(node package ...

  7. 取得cxgrid的表格的值,仔细看下面的代码

    procedure TfrmMain.cxGridDBTableView_List_PSSJCustomDrawCell(Sender: TcxCustomGridTableView; ACanvas ...

  8. delphi IsIPAdress 非正则表达式验证IP的方法

    function IsIPAdress(const Value:String):Boolean; var n,x,i: Integer; Posi:Array[..]of Integer; Oktet ...

  9. 一些LinuxC的小知识点(二)

    一.read系统调用       系统调用read的作用是:从与文件描述符filedes相关联的文件里读入nbytes个字节的数据,并把它们放到数据区buf中.它返回实际读入的字节数.这可能会小于请求 ...

  10. ASP.NET自定义错误页并返回正确的500、404状态码

    在项目中,我们常常需要自定义错误页面,但往往返回的状态码都变成了200,对SEO很不友好.我尝试过在百度上寻找解决方案,但找到的资料中说的方法都试过了,发现都是无法返回正确的状态码的. 最后,只好自已 ...