我们都知道。能够使用两种方式给一个类或者对象加入行为。

一是使用继承。继承是给一个类加入行为的比較有效的途径。通过使用继承,能够使得子类在拥有自身方法的同一时候,还能够拥有父类的方法。可是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制添加行为的方式和时机。

二是使用关联。组合即将一个对象嵌入到还有一个对象中,由还有一个对象来决定是否引用该对象来扩展自己的行为。

这是一种动态的方式,我们能够在应用程序中动态的控制。

与继承相比,关联关系的优势就在于不会破坏类的封装性,且具有较好的松耦合性,能够使系统更加easy维护。可是它的缺点就在于要创建比继承很多其它的对象

一、装饰者的定义:

装饰着模式动态的将责任附加到对象上,若想要扩展功能,装饰着提供比继承更有弹性的替代方案。

二、装饰着模式的UML图:

Compoent类:抽象类,每一个组件能够单独使用它。或者包装起来使用

ConcreteCompoent类:动态载入新行为的对象。继承于Compoent

Decorator类:装饰着共同实现的接口,能够使抽象类

ConcreteDecorator1、ConcreteDecorator2类:装饰实例,装饰者包着Compent

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3NoaXJkZXk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

三、应用场景:

Startbuzz是以扩张速度最快的的咖啡连锁店。由于扩张太快。他们准备更新订单系统。以供应需求。他们原先的设计是这种。

购买咖啡时,能够要求在当中增加各种调料。比如:牛奶(Milk)、豆浆(Soy)、摩卡(Mocha)。Startbuzz会依据不同的调料收取不同的费用,所以订单必须考虑到调料部分。。

这是他们的第一次尝试。。。

解决方式:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb3NoaXJkZXk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

四、编写代码

Compotemt:Beverage类

	//@file:beverage.java
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}

ConcreteCompotemt:Espresso类

	//浓缩咖啡
//@file:Espresso.java
public class Espresso extends Beverage {
<span style="white-space:pre"> </span>public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1;
}
}

CondimentDecorator:HouseBlend类

	//@file:HouseBlend.java  、
//深烤烘焙
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
return 0.5;
}
}

Decorator:CondimentDecorator类

        //@file:CondimentDecorator.java
public abstract class CondimentDecorator extends Beverage{
abstract public String getDescription();
}

ConcreteDecorator:Milk类

	//file:Milk.java  牛奶味道的调料
public class Milk extends CondimentDecorator { Beverage beverage;
public Milk(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+"-Milk";
}
@Override
public double cost() {
return beverage.cost()+2.0;
}
}

ConcreteDecorator:Mocha类

//摩卡味道的调料
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+"-Mocha";
}
@Override
public double cost() {
return beverage.cost()+3.0;
}
}

ConcreteCDecorator:Soy类

	//豆浆味道的调料
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+"-Soy";
}
@Override
public double cost() {
return beverage.cost()+4.0;
}
}

開始下单啦!!!

public class OrderApp {
public static void main(String[] args) {
Beverage beverage1 = new HouseBlend();
beverage1 = new Milk(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Soy(beverage1);
System.out.println("beverage1 description:"+beverage1.getDescription()+"\ncost:"+beverage1.cost()); Beverage beverage2 = new Espresso();
beverage2= new Milk(beverage2);
beverage2 = new Mocha(beverage2);
System.out.println("beverage2 description:"+beverage2.getDescription()+"\ncost:"+beverage2.cost());
}
}

output:

beverage1 description:HouseBlend-Milk-Mocha-Soy

cost:9.5

beverage2 description:Espresso-Milk-Mocha

cost:6.0


版权声明:本文博主原创文章,博客,未经同意不得转载。

Java设计模式(三)-修饰模式的更多相关文章

  1. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  2. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  3. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  4. JAVA设计模式--装饰器模式

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

  5. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  6. 折腾Java设计模式之模板方法模式

    博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...

  7. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

  8. Java设计模式之工厂模式(Factory模式)介绍(转载)

    原文见:http://www.jb51.net/article/62068.htm 这篇文章主要介绍了Java设计模式之工厂模式(Factory模式)介绍,本文讲解了为何使用工厂模式.工厂方法.抽象工 ...

  9. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  10. Java 设计模式之建造者模式(四)

    原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...

随机推荐

  1. NPC

    这里的想说的NPC不是Non-Player-Controled,非玩家控制角色,而是Non-determinisitc Polynomial complete problem,它属于一类很特殊的问题, ...

  2. POJ 3286 How many 0&#39;s?

    题目大意: 计算[m,n]之间全部数字有多少个零. 解题思路: 能够用[0,m)之间和[0,n]之间有多少个零然后作差. 规律是计算全部位置在到当前数时有多少个零. 以下是代码:   #include ...

  3. Install Linux Kernel - AT91SAM9260EK

    两.AT91SAM9260EK 2.1下载 介绍页: http://www.at91.com/linux4sam/bin/view/Linux4SAM/LegacyLinuxKernel 下载页: a ...

  4. 1m网速是什么意思,1m带宽是什么意思

    1M网速下载速度应是多少?我怎么才50多KB?? 建议: 一般来说是90到100算正常.最高能达到120 带究竟该有多快 揭开ADSL真正速度之谜 常常使用ADSL的用户,你知道ADSL的真正速度吗? ...

  5. Visual Studio跨平台开发实战(1) - Hello Xamarin!

    原文 Visual Studio跨平台开发实战(1) - Hello Xamarin! 前言 应用程式发展的脚步, 从来没有停过. 从早期的Windows 应用程式, 到网路时代的web 应用程式, ...

  6. Android开发工具综述,开发人员必备工具

    安卓开发工具汇总.开发者必备.安卓开发过程中须要用到各种工具,作为一名安卓开发者,有木有感到亚历山大,那么多工具! 今天给大家汇总了一下安卓开发工具,安卓开发者必备利器. 1.Draw 9-Patch ...

  7. ASP.NET——验证码的制作

            我们在登陆站点,发表博客或者提交评论的时候,常常会遇到填写验证码这一项,当时感觉挺奇妙的样子,最终在牛腩新闻公布系统里接触到了,在这里小小的总结下.         用到的东东有三个: ...

  8. 递归遍历XML所有节点

    package xml; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.DocumentEx ...

  9. 原创游戏,金庸群侠传X 0.5公布

    首先说一下背景,我个人从小特别爱玩游戏,对小时候一款游戏<金庸群侠传>DOS版更是情有独钟,自己工作以后,利用业余时间自己整了一个原创的改编版丢网上(找图片.音乐.写剧情更是虐心之极,耗时 ...

  10. document.getElementById()使用方法

    document.getElementById使用 语法:oElement = document .getElementById ( sID ) 參数:sID――必选项. 字符串 (String) . ...