装饰者模式

2018/03 06 22:03

以星巴克售卖各种各样的咖啡为例。售卖的咖啡有两部分组成:咖啡和配料。购买咖啡时,也可以要求在其中加入各种调料,例如:蒸奶,豆浆,摩卡或者覆盖奶泡。星巴克会根据所加入的调料收取不同的费用。所以订单系统必须考虑到这些调料部分。

设计原则:类应该对扩展开放,对修改关闭。即开闭原则

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

Beverage类(饮料)
[cc lang="java"]
public abstract class Beverage {
String description = "Unknown Beverage";

public String getDescription() {
return description;
}

public double cost(){
return 1.99D;
}
}
[/cc]

CondimentDecorator类(调料)
[cc lang="java"]
public abstract class CondimentDecorator extends Beverage {

public abstract String getDescription();

}
[/cc]
Espressonl类(浓缩咖啡)
[cc lang="java"]
public class Espresson extends Beverage {

public Espresson() {
super.description = "Espresson";
}

@Override
public double cost() {
return 3.30D;
}

}
[/cc]
HouseBlend类
[cc lang="java"]
public class HouseBlend extends Beverage {

public HouseBlend() {
super.description ="House";
}

@Override
public double cost() {
return 0.89D;
}

}
[/cc]
Mocha类(摩卡)
[cc lang="java"]
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 0.20D+super.cost();
}

}
[/cc]
Whip类(奶泡)
[cc lang="java"]
public class Whip extends CondimentDecorator {

Beverage beverage;

public Whip(Beverage beverage) {
this.beverage = beverage;
}

@Override
public String getDescription() {
return beverage.getDescription()+",Whip";
}

@Override
public double cost() {
return 0.40D+super.cost();
}

}
[/cc]
StarbuzzCoffee测试类
[cc lang="java"]
public class StarbuzzCoffee {
public static void main(String ages[]){
Beverage beverage = new Espresson();
System.out.println(beverage.getDescription()+"$"+beverage.cost());

Beverage beverage2 =new HouseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()+"$"+beverage2.cost());
}
}
[/cc]
 

真是世界的装饰者:Java I/O

Java I/O也引出装饰者模式的一个确定“缺点”:利用装饰者模式,常常造成设计中有大量的小类,数量实在太多,可能回造成使用此API程序员的困扰。但是,现在了解装饰者的工作原理,以后当使用别人的大量装饰的API时,就可以很容易地辨别出他们的装饰者类是如何组织,以方便用包装的方式取得想要的行为。

编写自己的Java I/O装饰者

编写一个装饰者,把输入流内的所有大写字符转换成小写

LowerCaseInputStream类
[cc lang="java"]
public class LowercaseInputSteam extends FilterInputStream{

public LowercaseInputSteam(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 = 0; i < b.length; i++) { b[i] = (byte)Character.toLowerCase((char)b[i]); } return result; } } [/cc] InputTest测试类 [cc lang="java"] public class InputTest { public static void main(String[] args) { int c; try { InputStream in = new LowercaseInputSteam( new BufferedInputStream( new FileInputStream("D:/Workspaces/Java/Eclipse/Test/src/test.txt"))); while ((c = in.read()) >= 0) {
System.out.print((char)c);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
[/cc]

--转载请注明: https://www.guangboyuan.cn/%e8%a3%85%e9%a5%b0%e8%80%85%e6%a8%a1%e5%bc%8f/

发表回复

(必填)