装饰模式
一、定义
装饰模式是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
装饰模式在我们生活中应用比较多如给煎饼加鸡蛋;给蛋糕加上一些水果;给房子装修等,为对象扩展一些额外的职责。
和静态代理最大的区别就是职责不同,静态代理不一定要满足is-a的关系,静态代理会做功能增强,同一个职责变得不一样,装饰器更多考虑是扩展
二、适用场景
1.用于扩展一个类的功能或给一个类添加附加职责
2.动态的给一个对象添加功能,这些功能可以在动态的撤销
3.我的理解就是扩展,插件
三、说明
1.需要先定义一个基础装饰类,有点类似静态代理,以组合的方式实现装饰,还要继承目标对象,重写继承类的方法(要装饰的方法),再提供一些钩子或者装饰需要的方法
2.还需要其他装饰可以继承这个基础装饰类,并实现基础装饰类的钩子
3.跟静态代理最大区别就是职责不同,静态代理不一定要满足is-a 的关系
4.静态代理会做功能增强,同一个职责变得不一样
5.装饰器更多考虑是扩展
四、实例
煎饼,加鸡蛋,加香肠,可以加多个鸡蛋,加多个香肠。
类图
煎饼的抽象Battercake,不是抽象也没关系
/**
* <p>
* 煎饼的抽象Battercake
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}
基本的煎饼(或者叫基础套餐)BaseBattercake
/**
* <p>
* 基本的煎饼(或者叫基础套餐)BaseBattercake
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
public class BaseBattercake extends Battercake{
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected int getPrice() {
return 5;
}
}
扩展套餐的抽象装饰者BattercakeDecotator
/**
* <p>
* 扩展套餐的抽象装饰者BattercakeDecotator
* 这个就是装饰者
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
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();
}
}
鸡蛋装饰者EggDecorator
/**
* <p>
* 鸡蛋装饰者EggDecorator
* 加鸡蛋
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
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;
}
}
香肠装饰者SausageDecorator
/**
* <p>
* 香肠装饰者SausageDecorator
* 加鸡蛋
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
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;
}
}
客户端测试
/**
* <p>
* 客户端测试
* </p>
*
* @author: longWarren
* @time: 2020/08/31
*/
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);
//跟静态代理最大区别就是职责不同
//静态代理不一定要满足is-a 的关系
//静态代理会做功能增强,同一个职责变得不一样
//装饰器更多考虑是扩展
//这里的battercake.getMsg()和battercake.getPrice()会一直向上调用
System.out.println(battercake.getMsg() + ",总价:" + battercake.getPrice());
}
}