1、装饰者模式定义:
- 抽象定义:在不改原有对象的基础上,将功能附加到原对象上,并且不能影响源代码逻辑,实现比继承更优雅的替代方案。
2、装饰者模式应用场景:
- 用于扩展一个类的功能。
- 为类添加附加职责。
- eg:咖啡店,起初只提供原味coffee,随着用户逐渐增多,客户的需求开始在原味coffe中加糖咖啡,加奶咖啡等等。
3、装饰者模式优点:
- 装饰者模式是继承的补充,比继承更灵活,不改变原对象的情况下动态的扩展对象的功能,实现功能的可插拔。
- 灵活的通过不同的装饰类及这些装饰类排列组合,实现不同的效果。
- 装饰者遵循开闭原则。
4、装饰者模式缺点:
- 增加代码量,更多的类,增加程序的复杂度。
- 多层装饰时会更加复杂。
5、装饰者模式实战:
eg:咖啡店,起初只提供原味coffee,随着用户逐渐增多,客户的需求开始在原味coffe中加糖咖啡,加奶咖啡等等。
未使用装饰者模式代码如下:
/**
* @description: 抽象组件
* @since 2019-11-10
*/
public interface IDrink {
/**
* 花费
* @return
*/
BigDecimal cost();
/**
* 详情
* @return
*/
String info();
}
/**
* @description: 具体组件
* @create: 2019-11-10
**/
public class Coffee implements IDrink {
@Override
public BigDecimal cost() {
return new BigDecimal("10");
}
@Override
public String info() {
return "原味Coffee";
}
}
/**
* @description: v1 加糖的coffee
* @create: 2019-11-10
**/
public class CoffeeAddMilk implements IDrink {
@Override
public BigDecimal cost() {
return new BigDecimal("20");
}
@Override
public String info() {
return "加milk的Coffee";
}
}
/**
* @description: v1 加冰糖的coffee
* @create: 2019-11-10
**/
public class CoffeeAddSuger implements IDrink {
@Override
public BigDecimal cost() {
return new BigDecimal("15");
}
@Override
public String info() {
return "加冰糖的Coffee";
}
}
/**
* @description: v1 测试代码
* @create: 2019-11-10
**/
public class App {
public static void main(String[] args) {
com.biudefu.decorate.v1.Coffee cafe = new com.biudefu.decorate.v1.Coffee();
System.out.println(cafe.info()+"---->"+cafe.cost());
// 想和加糖的coffee
CoffeeAddMilk milk = new CoffeeAddMilk();
System.out.println(milk.info()+"---->"+milk.cost());
// 想加冰糖的coffee
CoffeeAddSuger suger = new CoffeeAddSuger();
System.out.println(suger.info()+"---->"+suger.cost());
// 接下来客户的需求又变了,要及加糖又加milk的,是不是又要创建一个CoffeeAddSugerAndMilk???
}
}
V2版本采用装饰者模式进行改良:
类关系图
/**
* @description: 抽象组件
* @since 2019-11-10
*/
public interface IDrink {
/**
* 花费
* @return
*/
BigDecimal cost();
/**
* 详情
* @return
*/
String info();
}
/**
* @description: 抽象装饰器
* @create: 2019-11-10
**/
public abstract class AbstractDecorator implements IDrink {
private IDrink drink;
public AbstractDecorator(IDrink drink) {
this.drink = drink;
}
@Override
public BigDecimal cost() {
return drink.cost();
}
@Override
public String info() {
return drink.info();
}
}
/**
* @description: 具体组件
* @create: 2019-11-10
**/
public class Coffee implements IDrink{
@Override
public BigDecimal cost() {
return new BigDecimal("10");
}
@Override
public String info() {
return "原味Coffee";
}
}
/**
* @description: 具体装饰类
* @create: 2019-11-10
**/
public class MilkDecorator extends AbstractDecorator {
public MilkDecorator(IDrink drink) {
super(drink);
}
@Override
public BigDecimal cost() {
return super.cost().add(new BigDecimal("10"));
}
@Override
public String info() {
return super.info()+",加入了牛奶🥛!";
}
}
/**
* @description: 具体装饰类
* @create: 2019-11-10
**/
public class SugerDecorator extends AbstractDecorator {
public SugerDecorator(IDrink drink) {
super(drink);
}
@Override
public BigDecimal cost() {
return super.cost().add(new BigDecimal("5"));
}
@Override
public String info() {
return super.info()+",加入了冰糖🍬!";
}
}
/**
* @description: 装饰器,启动类
* @create: 2019-11-10
**/
public class App {
public static void main(String[] args) {
// 原味coffee
Coffee cafe = new Coffee();
System.out.println(cafe.info() + "---->" + cafe.cost());
// 原味coffee 添加 牛奶
MilkDecorator milk = new MilkDecorator(cafe);
System.out.println(milk.info() + "---->" + milk.cost());
// 原味coffee继续添加 冰糖
SugerDecorator s = new SugerDecorator(milk);
System.out.println(s.info() + "---->" + s.cost());
// 原味coffee与milk、suger 灵活搭配:原味coffee+milk、原味coffee+suger、原味coffee+milk
// +suger ,而且将来了如果coffee中加tea,只需要扩展一个TeaDecorator即可
}
}
6、装饰者模式在源代码中的应用:
-
inputStream中:
image.png -
spring中:
待补充~ -
mybatis中:
image.png
Mybatis缓存对象的默认类型为PerpetualCache:
image.png装饰PerpetualCache的标准装饰器共有8个(全部在 org.apache.ibatis.cache.decorators包中):
- FifoCache:先进先出算法,缓存回收策略
- LoggingCache:输出缓存命中的日志信息
- LruCache:最近最少使用算法,缓存回收策略
- ScheduledCache:调度缓存,负责定时清空缓存
- SerializedCache:缓存序列化和反序列化存储
- SoftCache:基于软引用实现的缓存管理策略
- SynchronizedCache:同步的缓存装饰器,用于防止多线程并发访问
- WeakCache:基于弱引用实现的缓存管理策略
网友评论