装饰者
装饰模式的定义与特点
装饰(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
装饰(Decorator)模式的主要优点有:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
其主要缺点是:装饰模式会增加许多子类,过度使用会增加程序得复杂性。
装饰模式的应用场景
前面讲解了关于装饰模式的结构与特点,下面介绍其适用的应用场景,装饰模式通常在以下几种情况使用。
- 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
- 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。
- 当对象的功能要求可以动态地添加,也可以再动态地撤销时。
具体实现
//抽象煎饼类
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}
/**
* 基础煎饼类
*/
public class BaseBattercake extends Battercake{
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected int getPrice() {
return 5;
}
}
/**
* 附加材料抽象类
*/
public abstract class BattercakeDecorator extends Battercake{
private Battercake battercake;//静态代理,委派
public BattercakeDecorator(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();
}
}
/**
* 鸡蛋类
*/
public class EggDecorator extends BattercakeDecorator{
public EggDecorator(Battercake battercake) {
super(battercake);
}
@Override
protected void doSomething() {
}
@Override
protected String getMsg(){
return super.getMsg() + "1个鸡蛋";
}
@Override
protected int getPrice(){
return super.getPrice() + 1;
}
}
/**
* 香肠类
*/
public class SausageDecorator extends BattercakeDecorator{
public SausageDecorator(Battercake battercake) {
super(battercake);
}
@Override
protected void doSomething() {
}
@Override
protected String getMsg(){
return super.getMsg() + "1根烤肠";
}
@Override
protected int getPrice(){
return super.getPrice()+2;
}
}
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake;
battercake = new BaseBattercake();//路边买一个煎饼
battercake = new EggDecorator(battercake);//加一颗鸡蛋
battercake = new SausageDecorator(battercake);//加一根烤肠
battercake = new SausageDecorator(battercake);//再加一根烤肠
/**
* 跟静态代理最大的区别就是职责不同
* 静态代理不一定满足is-a 的关系
* 静态代理会做功能增强,使同一个职责变得不一样
*/
//装饰者模式更多的考虑扩展
System.out.println(battercake.getMsg()+"总价:"+battercake.getPrice());
}
}
上一张图来解释上面类的关系,这样可以更加直观的理解,其是如何对类进行装饰的