Decorator Pattern
问题
我开了一家蛋糕店,蛋糕最普通的是面包奶油蛋糕(MilkCake),你可以根据自己的喜好,在这个普通的蛋糕上添加你喜欢的一些装饰,我们提供的有:
草莓:Strawberry=$8
巧克力:Chocolate=$11
苹果:Apple=$5
橘子:Orange=$3
....
普通蛋糕:$100
现在我需要做一个草莓巧克力蛋糕,需要多少钱?
方案一
//MilkCake类
package com.pattern.decorator;
public class MilkCake {
private float milkCake=100;
public float cost(){
return milkCake;
}
}
//StrawberryChocolateCake
package com.pattern.decorator;
public class StrawberryChocolateCake extends MilkCake{
private float strawberry=8;//草莓价格
private float chocolate=11;//巧克力的价格
@Override
public float cost() {
return super.cost()+strawberry+chocolate;//加上草莓巧克力后的蛋糕的价格
}
}
//Test
package com.pattern.decorator;
public class Test {
public static void main(String[] args) {
StrawberryChocolateCake strawberryChocolateCake=new StrawberryChocolateCake();
float money=strawberryChocolateCake.cost();
System.out.println(money);
}
}
问题
有人想要一个巧克力奶油蛋糕,我需要改源码
草莓价格改了,我还需要改源码
...
这样的话,太折腾人了
问题的解决
装饰者模式
动态的将责任附加到对象上,如要扩展,装饰者提供了比继承更有弹性的替代方案
方案二
package com.pattern.decorator1;
public interface Cake {
public abstract float cost();
}
package com.pattern.decorator1;
/**
* 基本的蛋糕-牛奶蛋糕-100元哟!
*/
public class MilkCake implements Cake{
private float milkCake=100;
@Override
public float cost() {
return milkCake;
}
}
package com.pattern.decorator1;
/**
* 蛋糕装饰者,如果你是装饰者,你就需要继承此类方能给蛋糕装饰
*/
public abstract class CakeDecorator implements Cake{
}
package com.pattern.decorator1;
/**
* 草莓蛋糕是装饰普通蛋糕的,继承CakeDecorator
*/
public class StrawberryCake extends CakeDecorator{
private Cake cake;//标识装饰给那一块蛋糕的
private float strawberry=8;//草莓的价格
public StrawberryCake(){
}
/**
* 如果需要草莓来装饰蛋糕,就把你的蛋糕放进来吧!!!
*/
public StrawberryCake(Cake cake){
this.cake=cake;
}
/**
* 算出草莓装饰后的蛋糕的总价
*/
@Override
public float cost() {
return cake.cost()+strawberry;
}
}
package com.pattern.decorator1;
/**
* 巧克力蛋糕是装饰普通蛋糕的,继承CakeDecorator
*/
public class ChocolateCake extends CakeDecorator{
private Cake cake;//标识装饰给那一块蛋糕的
private float chocolate=11;//巧克力的价格
public ChocolateCake(){
}
/**
* 如果需要巧克力来装饰蛋糕,就把你的蛋糕放进来吧!!!
*/
public ChocolateCake(Cake cake){
this.cake=cake;
}
/**
* 算出草莓装饰后的蛋糕的总价
*/
@Override
public float cost() {
return cake.cost()+chocolate;
}
}
package com.pattern.decorator1;
public class Test {
public static void main(String[] args) {
MilkCake cake=new MilkCake();
float money1=cake.cost();
System.out.println(money1);//普通蛋糕100
StrawberryCake strawberryCake=new StrawberryCake(cake);
float money2=strawberryCake.cost();
System.out.println(money2);//草莓蛋糕108
ChocolateCake chocolateCake=new ChocolateCake(strawberryCake);
float money3=chocolateCake.cost();
System.out.println(money3);//巧克力草莓蛋糕119
}
}
Java.io中的装饰者模式