装饰模式(Decorator Pattern)
装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。关系图如下:
例子:咖啡和配料
咖啡和配料的通用接口
深焙咖啡
摩卡
奶泡
测试
测试结果
刚接触装饰模式会感觉和继承没什么区别,继承也可以实现,但是仔细一想,比如:咖啡有n中,配料有m种,那么就可能有n*m种喝法,如果用继承,得有n*m个子类,而用装饰模式就只需要n个咖啡子类和m个配料子类。所以,装饰模式用在组合情况下非常方便。
装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。关系图如下:
例子:咖啡和配料
咖啡和配料的通用接口
public interface Beverage {
public String getDescription();
public double cost();
}
深焙咖啡
public class DarkRoast implements Beverage{
@Override
public String getDescription() {
return "深焙咖啡";
}
@Override
public double cost() {
return 0.99;
}
}
摩卡
public class Mocha implements Beverage{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",摩卡";
}
@Override
public double cost() {
return beverage.cost()+0.2;
}
}
奶泡
public class Whip implements Beverage{
Beverage beverage;
public Whip(Beverage beverage){
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",奶泡";
}
@Override
public double cost() {
return beverage.cost()+0.1;
}
}
测试
public class Demo {
public static void main(String[] args) {
Beverage beverage=new DarkRoast();
beverage=new Mocha(beverage);
beverage=new Whip(beverage);
System.out.println("description:"+beverage.getDescription());
System.out.println("cost:"+beverage.cost());
}
}
测试结果
description:深焙咖啡,摩卡,奶泡
cost:1.29
刚接触装饰模式会感觉和继承没什么区别,继承也可以实现,但是仔细一想,比如:咖啡有n中,配料有m种,那么就可能有n*m种喝法,如果用继承,得有n*m个子类,而用装饰模式就只需要n个咖啡子类和m个配料子类。所以,装饰模式用在组合情况下非常方便。