定义
装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)属于结构型模式。
适用场景:
1、用于扩展一个类的功能或给一个类添加附加职责。
2、动态的给一个对象添加功能,这些功能可以再动态的撤销。
生活场景
1、煎饼+鸡蛋+香肠+豆皮等等,其中原有对象是煎饼,无论加了什么改变不了煎饼的本质。
2、人+夏天衣服+秋天衣服+冬天西服,其中原有对象是人,不管穿什么都是人。
代码演示
改造前代码
package com.decorator;
/**
* 煎饼
*/
public class Battercake {
public String getMsg(){
return "煎饼";
}
public int getPrice(){
return 5;
}
}
package com.decorator;
/**
* 煎饼+鸡蛋
*/
public class BattercakeWithEgg extends Battercake {
@Override
public String getMsg() {
return super.getMsg()+"+1个鸡蛋";
}
@Override
public int getPrice() {
return super.getPrice()+1;
}
}
package com.decorator;
public class BattercakeWithEggAndSausage extends Battercake {
@Override
public String getMsg() {
return super.getMsg()+"+1根香肠";
}
@Override
public int getPrice() {
return super.getPrice()+2;
}
}
package com.decorator;
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake = new BaseBattercake();
System.out.println(battercake.getMsg() + ",总价格:" + battercake.getPrice());
Battercake battercakeWithEgg = new BattercakeWithEgg();
System.out.println(battercakeWithEgg.getMsg() + ",总价格:" + battercakeWithEgg.getPrice());
Battercake battercakeWithEggAndSausage = new BattercakeWithEggAndSausage();
System.out.println(battercakeWithEggAndSausage.getMsg() + ",总价格:" +
battercakeWithEggAndSausage.getPrice());
}
}
执行结果:
存在问题:
目前的程序无法实现个性化的定制,比如买2个煎饼+香肠,最好是可以动态的增加或减少客户的需求。
改造后代码
package com.decorator;
/**
* 煎饼
*/
public abstract class Battercake {
public abstract String getMsg();
public abstract int getPrice();
}
package com.decorator;
public class BaseBattercake extends Battercake {
@Override
public String getMsg() {
return "煎饼";
}
@Override
public int getPrice() {
return 5;
}
}
package com.decorator;
public class BattercakeDecorator extends Battercake {
private Battercake battercake;
public BattercakeDecorator(Battercake battercake){
this.battercake = battercake;
}
@Override
public String getMsg() {
return battercake.getMsg();
}
@Override
public int getPrice() {
return battercake.getPrice();
}
}
package com.decorator;
public class EggDecorator extends BattercakeDecorator {
public EggDecorator(Battercake battercake){
super(battercake);
}
@Override
public String getMsg() {
return super.getMsg()+"+1个鸡蛋";
}
@Override
public int getPrice() {
return super.getPrice() + 1;
}
}
package com.decorator;
public class SausageDecorator extends BattercakeDecorator {
public SausageDecorator(Battercake battercake){
super(battercake);
}
@Override
public String getMsg() {
return super.getMsg() + "+1 根香肠";
}
@Override
public int getPrice() {
return super.getPrice() + 2;
}
}
package com.decorator;
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake;
battercake = new BaseBattercake();
battercake = new EggDecorator(battercake);
battercake = new EggDecorator(battercake);
battercake = new SausageDecorator(battercake);
System.out.println(battercake.getMsg()+",总价:"+battercake.getPrice());
}
}
执行结果:
改造后的代码可以灵活定制加几个鸡蛋从测试代码就能看出来,更灵活的实现了原有功能的扩展。
贴上类图: