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中的装饰者模式