设计模式--装饰者模式

装饰者模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。
先来引入一个例子:星巴克咖啡店扩张速度过快,他们要更新自己的菜单,他们原来的设计是有一个咖啡的基类Beverage
package test.headfirst.pattern;

public abstract class Beverage {
public String description;
//设置饮料的描述
public void setDescription(String description) {
this.description = description;
}
//饮料的价格
abstract double cost();
}
然后子类继承Beverage类,实现自己的cost方法和描述。当然购买咖啡的时候也可以加入调料之类的东西。如果牛奶,豆浆,奶泡。
然后就这样,咖啡加牛奶类,咖啡加豆浆类,咖啡加奶泡类。。。等等,多少种咖啡,对应多少种调料。然后咖啡类和调料类组成一个笛卡尔积。
简直是类爆炸。
然后可以想着在Beverage基类中添加调料的布尔值,TRUE代表添加该调料,FALSE代表不添加该调料。然而这种方法,也有缺陷。例如:如果咖啡店要加入
一种新的调料,那么我们只能修改基类的代码。这就违反了对扩展开放,对修改关闭的原则。如果有顾客想要加两份牛奶调料的咖啡也是不能实现的。这显然是
不合理的。
下面引入装饰者涉及模式。
/**
* 饮料实现类
*/
public class HouseBlend extends Beverage{
public HouseBlend(){
description="House Blend Coffe";
}
double cost() {

return .99;
}

}
/**
* 调料父类抽象类
*/
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();//所有的调料类都必须实现的方法
}
/**
* 调料具体实现类
*/
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage berverage){
this.beverage = berverage;
}
@Override
public String getDescription() {
description = beverage.description+" mocha";
return description;
}

@Override
double cost() {
return .20+beverage.cost();
}

}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
Beverage b = new HouseBlend();
b = new Mocha(b);
System.out.println(b.description);
System.out.println(b.cost());
}
}
可以看出利用装饰者模式完全能解决上面的问题,同时也符合对扩展开放,对修改关闭的原则。
在Java I/O 中你会发现有很多读写操作类,字符流,字节流。要想理解各个类之间的关系也不是简单的事情。
但是细想你会发现I/O中利用了装饰者模式。例如:
LineNumberInputStream li = new LineNumberInputStream(new BufferedInputStream(new FileInputStream(new File(""))));这些类都是装饰的InputStream对象。
装饰者设计模式要点:
继承属于扩展形式之一,但不见的是道道弹性涉及的最佳方式。
在我们的设计中,应该允许行为可以被扩展,而无需修改现有代码。
组合和委托可以用于在运行时动态地加上新行为。
除了继承,装饰者模式也可以让那个我们扩展行为。
装饰者模式意味着一群装设着类,这些类用来包装具体组件。
装饰者类反映出被装饰的组件类型(事实上他们具有相同的类型,都经过接口或继承实现)。
装饰者可以在被装饰者的行为前面与后面加上自己的行为,甚至将装饰者的行为整个取代掉,而达到特定的目的。
你可以用无数个装饰者包装一个组件。
装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
装饰者会导致设计中出现许多的对象,如果过度使用,会让程序变得复杂。

 

posted @ 2014-05-21 20:35  942391815  阅读(211)  评论(0编辑  收藏  举报