问题引入
实现在一份咖啡中加入摩卡(Mocha),再加上奶泡(Whip),并且计算咖啡总共的价钱。
模式定义
动态的将责任附加到对象上。若要扩展功能,装饰着提供了比继承更有弹性的替代方案。
认识模式
在被装饰者的前面或者后面加上附加的一些行为,从而扩展被装饰者的功能,接口没变,但是增强了性能。
问题解决
使用继承同一父类或者实现相同的接口,使装饰者和被装饰者具有相同的类型,从而实现多重的装饰效果!
直接上代码
1>Beverage饮料类,所有的类都继承自它,从而具有相同的类型
package my.oschina.net.design.decorator;
public abstract class Beverage {
String description = "";
public String getDescription()
{
return description;
}
public abstract double cost();
}
2>Coffe类(被装饰者)
package my.oschina.net.design.decorator;
/**
* 纯coffe每份0.9元
* @author Eswin
*
*/
public class Coffe extends Beverage{
public Coffe()
{
description = "coffe";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.9;
}
}
3>第一个装饰者(说实话它也是被装饰者,因为它还是会被另外的装饰者装饰)
package my.oschina.net.design.decorator;
/**
* Mocha每份0.5元
* @author Eswin
*
*/
public class Mocha extends Beverage{
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
public String getDescription()
{
return beverage.getDescription() + " + Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return beverage.cost() + 0.5;
}
}
4>第二个装饰者(它也是被装饰者,因为它还是会被另外的装饰者装饰)
package my.oschina.net.design.decorator;
/**
* Whip每份1.0元
* @author Eswin
*
*/
public class Whip extends Beverage{
Beverage beverage;
public String getDescription()
{
return beverage.getDescription() + " + Whip";
}
public Whip(Beverage beverage)
{
this.beverage = beverage;
}
@Override
public double cost() {
// TODO Auto-generated method stub
return beverage.cost() + 1.0;
}
}
5>Test一下
package my.oschina.net.design.decorator;
public class TestDecorator {
public static void printCoffe(Beverage beverage)
{
System.out.println("Coffe==>" + beverage.getDescription());
System.out.println("Coffe_Price==>" + beverage.cost());
}
public static void main(String[] args)
{
System.out.println("纯Coffe");
Beverage beverage = new Coffe();
printCoffe( beverage);
System.out.println("Coffee加上一份Mocha");
beverage = new Mocha(beverage);
printCoffe( beverage);
System.out.println("Coffee加上两份Mocha");
beverage = new Mocha(beverage);
printCoffe( beverage);
System.out.println("再加上一份Whip");
beverage = new Whip(beverage);
printCoffe( beverage);
}
}
模式延伸
你想起了java中各种各样的I/O流了吗?仔细想想,是不是用到了装饰器模式?
模式要点
1、继承同一父类或者实现相同的接口,从而使装饰者与被装饰者具有相同的类型;
2、在被装饰者中保存被装饰着对象的引用,然后在被装饰者方法的前后加上代码扩展功能。