装饰者模式的介绍
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
实际中的装饰者模式的例子:比如 java.io包的实现
装配者模式通用的UML类图
利用到的新原则
- 类应该对扩展开放,对修改关闭
饮料和配料的例子
例子里面cost()的图形理解
- Beverage(抽象抽象的组件类)
public abstract class Beverage {
String description = "Unknown description";
public String getDescription() {
return description;
}
public abstract double cost();
}
- CondimentDecorator(调料共同实现的接口 抽象类)
public abstract class CondimentDecorator extends Beverage {//调料抽象类
@Override
public abstract String getDescription();
}
- Espresso(具体饮料类 被装饰者继承Beverage抽象类)
public class Espresso extends Beverage {
public Espresso(){
description = "beverage.Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
- HouseBlend (具体饮料类 被装饰者继承Beverage抽象类)
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "House Blend Coffee";
}
@Override
public double cost() {
return 0.89;
}
}
- DarkRoast (具体饮料类 被装饰者继承Beverage抽象类)
public class DarkRoast extends Beverage {
public DarkRoast(){
description = "beverage.DarkRoast Coffee";
}
@Override
public double cost() {
return 0.99;
}
}
- Mocha(具体调味类 装饰者继承CondimentDecorator装饰者抽象类)
public class Mocha extends CondimentDecorator {//具体装饰者
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",beverage.Mocha";
}
@Override
public double cost() {
return 0.2+beverage.cost();
}
}
- Soy(具体调味类 装饰者继承CondimentDecorator装饰者抽象类)
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",beverage.Soy";
}
@Override
public double cost() {
return 0.14+beverage.cost();
}
}
- Providecoffee测试类(具体如何通过装饰者模式实现饮料的配料添加和价格的计算)
public class Providecoffee {//测试类
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()+" "+beverage.cost()+"¥");
Beverage darkRoast = new DarkRoast();//制造出一个饮料对象
darkRoast = new Mocha(darkRoast);//用mocha调料装饰饮料对象
darkRoast = new Mocha(darkRoast);//再用mocha调料装饰饮料的对象
darkRoast = new Soy(darkRoast);//最后再用soy调料装饰饮料的对象
System.out.println(darkRoast.getDescription()+" "+darkRoast.cost()+"¥");//暗含者递归的思想打印饮料的添加和价格
}
}
装饰者模式的总结
- 继承是一种扩展形式,但不是一定是最佳的方案。
- 装饰者模式可以进行扩展
- 装饰者模式意味着一群装饰者包装具体的组件
- 装饰者会导致设计中出现许多小对象,太多了的话会让程序变得很复杂。
本文参考 :《Head First 设计模式》