文章目录
1. 定义
装饰器模式是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)
2. 适用场景
- 用于扩展一个类的功能或给一个类添加附加职责
- 动态的给一个对象添加功能,这些功能可以再动态的撤销
3. 代码实现
一个小伙在上班路上看到一个卖煎饼的摊位,过去买个煎饼,需要加鸡蛋和香肠
当前的代码智能支持加鸡蛋, 火腿,如果还想加生菜或其他的,只需要增加对应的装饰器就可以了,不需要对原有代码做修改
3.1 基础抽象类
/**
* 煎饼抽象类
*/
public abstract class BatterCake {
/**
* 煎饼信息
* @return
*/
protected abstract String getMsg();
/**
* 煎饼价格
* @return
*/
protected abstract int getPrice();
}
3.2 基础对象
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;
/**
* 普通煎饼
*/
public class BaseBatterCake extends BatterCake{
/**
* 煎饼信息
* @return
*/
protected String getMsg() {
return "煎饼";
}
/**
* 煎饼价格
* @return
*/
protected int getPrice() {
return 5;
}
}
3.3 装饰器
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;
/**
* 普通煎饼装饰器
*/
public abstract class BatterCakeDecorator extends BatterCake{
private BatterCake batterCake;
public BatterCakeDecorator(BatterCake batterCake) {
this.batterCake = batterCake;
}
/**
* 煎饼信息
* @return
*/
protected String getMsg() {
return this.batterCake.getMsg();
}
/**
* 煎饼价格
* @return
*/
protected int getPrice() {
return this.batterCake.getPrice();
}
}
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;
/**
* 加鸡蛋装饰器
*/
public class EggDecorator extends BatterCakeDecorator{
public EggDecorator(BatterCake batterCake) {
super(batterCake);
}
@Override
protected String getMsg() {
return super.getMsg() + "+一个鸡蛋";
}
@Override
protected int getPrice() {
return super.getPrice() + 1;
}
}
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;
/**
* 加香肠装饰器
*/
public class SausageDecorator extends BatterCakeDecorator{
public SausageDecorator(BatterCake batterCake) {
super(batterCake);
}
@Override
protected String getMsg() {
return super.getMsg() + "+一根香肠";
}
@Override
protected int getPrice() {
return super.getPrice() + 2;
}
}
3.4 测试类
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;
public class BatterCakeTest {
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());
}
}
4. 源码分析
4.1 java.io中IO流
IO流总结起来就是大桶套小桶
public class FilterInputStream extends InputStream {
.....
protected FilterInputStream(InputStream in) {
this.in = in;
}
}
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
}
4.2 Spring中TransactionAwareCacheDecorator
public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
public TransactionAwareCacheDecorator(Cache targetCache) {
Assert.notNull(targetCache, "Target Cache must not be null");
this.targetCache = targetCache;
}
}
5. 装饰器模式与适配器模式对比
对比项 | 装饰器模式 | 适配器模式 |
---|---|---|
形式 | 是一种非常特别的适配器模式 | 没有层级关系,装饰器模式有层级关系 |
定义 | 装饰器与被装饰这都要实现同一个接口,主要目的是为了扩展之后依旧保留OOP关系 | 适配器和被适配者没有必然联系,通常是采用继承或代理的形式进行包装 |
关系 | 满足is-a关系 | 满足has-a的关系 |
功能 | 注重覆盖,扩展 | 注重兼容,转换 |
设计 | 前置考虑 | 后置考虑 |