java设计模式--装饰者模式
来源:互联网 发布:便携式移动数据采集器 编辑:程序博客网 时间:2024/06/11 01:26
装饰者模式
假设给我个题目,现在Coffe bar 有四种beverage,such as HouseBlend(0.89$$),Dark Roast(0.99$), Espreso(1.99$), Decaf(1.05$),供我选择,每种beverage,你可以选择加Milk(0.1$),Mocha(0.2$),Soy(0.15$),Whip(0.2$),要我来设计一个程序来实现。
于是我就码出了如下程序:
package Decorator;public abstract class Beverage { String description = "Unknown Beverage"; private boolean milk=false; private boolean mocha=false; private boolean soy=false; private boolean whip=false; public boolean hasMilk(){ return milk; } public void setMilk(boolean milk){ this.milk = milk; } public boolean hasMocha(){ return mocha; } public void setMocha(boolean mocha){ this.mocha = mocha; } public boolean hasSoy(){ return soy; } public void setSoy(boolean Soy){ this.soy = Soy; } public boolean hasWhip(){ return whip; } public void setWhip(boolean Whip){ this.whip = Whip; } public String getDescription() { return description; } public double cost(){ double condimentCost = 0.0; if(hasMilk()){ condimentCost+=0.1; } if(hasMocha()){ condimentCost+=0.2; } if(hasSoy()){ condimentCost+=0.15; } if(hasWhip()){ condimentCost+=0.1; } return condimentCost; }}
package Decorator;public class DarkRoast extends Beverage { public DarkRoast(){ description = "Most Excellent Dark Roast"; } public double cost(){ return 0.99+super.cost(); }}package Decorator;public class Decaf extends Beverage{ public Decaf(){ description = "Most Excellent Decaf"; } public double cost(){ return 1.05+super.cost(); }}package Decorator;public class Espresso extends Beverage{ public Espresso(){ description = "Most Excellent Espresso"; } public double cost(){ return 0.99+super.cost(); }}package Decorator;public class HouseBlend extends Beverage{ public HouseBlend(){ description = "Most Excellent House Blend"; } public double cost(){ return 0.89+super.cost(); }}
package Decorator;public class Client { public static void main(String[] args) { Beverage bg = new HouseBlend(); bg.setMilk(true);//add milk bg.setMocha(true);//add mocha System.out.println(bg.getDescription()); System.out.println(bg.cost()); }}/*Most Excellent House Blend1.19*/
piece of cake!!
不过转念一想,如果我想再加上一种原料,是不是就有点麻烦了!比如honey(0.1$),这时我就要手动修改beverage这个类了,貌似麻烦了一点;
package Decorator;public abstract class Beverage { String description = "Unknown Beverage"; private boolean milk=false; private boolean mocha=false; private boolean soy=false; private boolean whip=false; private boolean honey=false; public boolean hasMilk(){ return milk; } public void setMilk(boolean milk){ this.milk = milk; } public boolean hasMocha(){ return mocha; } public void setMocha(boolean mocha){ this.mocha = mocha; } public boolean hasSoy(){ return soy; } public void setSoy(boolean Soy){ this.soy = Soy; } public boolean hasWhip(){ return whip; } public void setWhip(boolean Whip){ this.whip = Whip; } public boolean hasHoney(){ return honey; } public void setHoney(boolean honey){ this.honey= honey; } public String getDescription() { return description; } public double cost(){ double condimentCost = 0.0; if(hasMilk()){ condimentCost+=0.1; } if(hasMocha()){ condimentCost+=0.2; } if(hasSoy()){ condimentCost+=0.15; } if(hasWhip()){ condimentCost+=0.1; } if(hasHoney()){ condimentCost+=0.1; } return condimentCost; }}
如果我有上百种原料,想一想,beverage这个类肯定会更复杂,且不符合抽象的原则。那应该怎么办呢?
想到这里我们第一反应就是这些原料最好继承某个基类,这样可以方便添加;那原料和beverage怎么关联呢? 就产生了下图那个装饰者模式的基本形式,beverage类可以灵活的添加原料
所有的ConcreteDecorator类似 于这里的原料均继承于Decorator这个抽象类,这个抽象类又继承于beverage这个基类。
如下图:
package headfirst.decorator.starbuzz;public abstract class Beverage { String description = "Unknown Beverage"; public String getDescription() { return description; } public abstract double cost();}
package headfirst.decorator.starbuzz;public class DarkRoast extends Beverage { public DarkRoast() { description = "Dark Roast Coffee"; } public double cost() { return .99; }}
package headfirst.decorator.starbuzz;public class Decaf extends Beverage { public Decaf() { description = "Decaf Coffee"; } public double cost() { return 1.05; }}
package headfirst.decorator.starbuzz;public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } public double cost() { return 1.99; }}
package headfirst.decorator.starbuzz;public class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89; }}
package headfirst.decorator.starbuzz;public abstract class CondimentDecorator extends Beverage { public abstract String getDescription();}
package headfirst.decorator.starbuzz;public class Milk extends CondimentDecorator { Beverage beverage; public Milk(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Milk"; } public double cost() { return .10 + beverage.cost(); }}
package headfirst.decorator.starbuzz;public class Mocha extends CondimentDecorator { Beverage beverage; public Mocha(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Mocha"; } public double cost() { return .20 + beverage.cost(); }}
package headfirst.decorator.starbuzz;public class Soy extends CondimentDecorator { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Soy"; } public double cost() { return .15 + beverage.cost(); }}
package headfirst.decorator.starbuzz;public class Whip extends CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Whip"; } public double cost() { return .10 + beverage.cost(); }}
package headfirst.decorator.starbuzz;public class StarbuzzCoffee { public static void main(String args[]) { Beverage beverage = new Espresso(); System.out.println(beverage.getDescription() + " $" + beverage.cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Soy(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); System.out.println(beverage3.getDescription() + " $" + beverage3.cost()); }}/*OutputEspresso $1.99Dark Roast Coffee, Mocha, Mocha, Whip $1.49House Blend Coffee, Soy, Mocha, Whip $1.34*/
这时我想扩充原料的类型时,我只有再继承一个原料类就可以了,比如Honey(0.1$)
package headfirst.decorator.starbuzz;public class Honey extends CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Honey"; } public double cost() { return .10 + beverage.cost(); }}
装饰者模式在Java I/O实例中的应用:
package headfirst.decorator.io;import java.io.*;public class LowerCaseInputStream extends FilterInputStream { public LowerCaseInputStream(InputStream in) { super(in); } public int read() throws IOException { int c = super.read(); return (c == -1 ? c : Character.toLowerCase((char)c)); } public int read(byte[] b, int offset, int len) throws IOException { int result = super.read(b, offset, len); for (int i = offset; i < offset+result; i++) { b[i] = (byte)Character.toLowerCase((char)b[i]); } return result; }}
package headfirst.decorator.io;import java.io.*;public class InputTest { public static void main(String[] args) throws IOException { int c; try { InputStream in = new LowerCaseInputStream( new BufferedInputStream( new FileInputStream("test.txt"))); while((c = in.read()) >= 0) { System.out.print((char)c); } in.close(); } catch (IOException e) { e.printStackTrace(); } }}
参考文献
- Head First Design Pattern
- 大话设计模式
- Thinking in Java
0 0
- Java设计模式-装饰者设计模式
- java设计模式---装饰者设计模式
- Java 装饰者设计模式
- Java设计模式--装饰者
- Java设计模式:装饰者模式(Decorator)
- java设计模式之装饰者模式
- 【Java设计模式】装饰者模式
- Java设计模式之装饰者模式
- JAVA系列-设计模式-装饰者模式
- java设计模式之装饰者模式
- Java 设计模式 装饰者模式
- Java设计模式之装饰者模式
- Java设计模式之装饰者模式
- java设计模式------装饰者模式
- Java设计模式之装饰者模式
- java设计模式--装饰者模式
- Java 设计模式 装饰者模式
- java设计模式 ----装饰者模式
- 2015年5月11日-2015年5月15日一周总结
- visu studio编程中L、TEXT、_TEXT、_T 用法说明
- TCP/IP 建立连接的过程?(3-way shake)
- 搜索引擎——知识梳理
- Swift 常量、变量定义使用 String和简单控件的使用
- java设计模式--装饰者模式
- jira安装破解等相关信息
- Java类加载器
- c#中DllImportAttribute用法汇总
- JAVA中的反射机制
- JAVA正则表达式语法
- Android Webview
- 解析提高PHP执行效率的50个技巧
- 欢迎使用CSDN-markdown编辑器