装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
角色:
- 抽象组件(Component):可以是一个接口或抽象类,其充当被装饰类的原始对象,规定了被装饰类的行为;
- 具体组件(ConcreteComponent):实现或继承成抽象组件的一个具体对象,也即被装饰对象
- 抽象装饰器(Decorator):装饰器的抽象,其内部必然有一个属性指向Component抽象组件,这是强制的通用行为。当然,如果系统中装饰逻辑单一,并不需要实现许多装饰器,那么我们就可以直接省略该类或接口,直接实现一个具体装饰器;
- 具体装饰器(ConcreteDecorator):Decorator的具体实现类,理论上,每个具体装饰器都扩展了抽象组件的一种功能;
我们经常会再路边买煎饼,可以加鸡蛋与香肠。我们不能每种情况都建立相关类去获取信息与价钱,这时候就可以使用装饰器模式
抽象组件:
package com.jdwa.decorator;
/**
* 煎饼
*/
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}
具体组件(即不加东西)
package com.jdwa.decorator;
/**
* 煎饼基础套餐
*/
public class BaseBattercake extends Battercake{
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected int getPrice() {
return 5;
}
}
抽象装饰器:
package com.jdwa.decorator;
/**
* 煎饼扩展套餐的抽象
*/
public abstract class BattercakeDerocator extends Battercake {
private Battercake battercake;
public BattercakeDerocator(Battercake battercake){
this.battercake = battercake;
}
protected abstract void doSomething();
@Override
protected String getMsg() {
return this.battercake.getMsg();
}
@Override
protected int getPrice() {
return this.battercake.getPrice();
}
}
具体装饰器:
package com.jdwa.decorator;
public class EggDecorator extends BattercakeDerocator {
public EggDecorator(Battercake battercake){
super(battercake);
}
@Override
protected void doSomething() {
System.out.println("加一个鸡蛋");
}
@Override
protected String getMsg() {
return super.getMsg()+"+1个鸡蛋";
}
@Override
protected int getPrice() {
return super.getPrice()+1;
}
}
package com.jdwa.decorator;
public class SausageDecorator extends BattercakeDerocator{
public SausageDecorator(Battercake battercake){
super(battercake);
}
@Override
protected void doSomething() {
System.out.println("一个香肠");
}
@Override
protected String getMsg() {
return super.getMsg()+"+1根香肠";
}
@Override
protected int getPrice() {
return super.getPrice()+2;
}
}
测试代码如下:
package com.jdwa.decorator;
public class Client {
public static void main(String[] args) {
//一个煎饼
Battercake battercake = new BaseBattercake();
//加一个鸡蛋
battercake = new EggDecorator(battercake);
//再加一个鸡蛋
battercake = new EggDecorator(battercake);
//加一跟香肠
battercake = new SausageDecorator(battercake);
System.out.println(battercake.getMsg() + "--->" + battercake.getPrice() + "元");
}
}
结果如下:
煎饼+1个鸡蛋+1个鸡蛋+1根香肠--->9元
网友评论