装饰器模式属于结构型模式的一种,装饰器模式是在不改变原来对象的条件下增加功能,装饰器模式不改变原来对象的结构,仅仅是增加相应的功能。
下面就以咖啡店的例子,咖啡中可以增加糖或者牛奶,如果使用继承的话需要有糖-咖啡类 也有牛奶-咖啡类 也有糖-牛奶-咖啡类 造成类爆炸,如果组合方式可以很好解决这个问题。
public interface Drink {
double price();
String des();
}
public abstract class Coffee implements Drink{
protected double price;
protected String des;
public Coffee(double price,String des){
this.price = price;
this.des = des;
}
@Override
public double price() {
return this.price;
}
@Override
public String des() {
return this.des;
}
}
public class BlackCoffee extends Coffee{
public BlackCoffee(double price, String des) {
super(price, des);
}
@Override
public double price() {
return this.price+1.0;
}
@Override
public String des() {
return this.des+" 黑色";
}
}
public abstract class DecorateCoffee implements Drink {
protected Drink drink;
public DecorateCoffee(Drink drink) {
this.drink = drink;
}
}
public class MilkDecorate extends DecorateCoffee{
public MilkDecorate(Drink drink) {
super(drink);
}
/**
* 增加一块钱
* @return
*/
@Override
public double price() {
return drink.price()+1.0;
}
@Override
public String des() {
return drink.des()+" 牛奶";
}
}
public class SugarDecorate extends DecorateCoffee{
public SugarDecorate(Drink drink) {
super(drink);
}
@Override
public double price() {
return drink.price()+1.0;
}
@Override
public String des() {
return drink.des()+" 糖";
}
}
测试的客户端类:
public class Client {
public static void main(String[] args) {
Drink drink = new MilkDecorate(new SugarDecorate(new BlackCoffee(1.0,"咖啡")));
System.out.println(drink.price());
System.out.println(drink.des());
}
}