1.什么是装饰模式?
不改变原有的代码实现增强。
Mybatis、Hibernate二级缓存都属于开发者自己去实现扩展的功能。
2.装饰模式的优缺点
优点:
1、装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
2、通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
3、装饰者完全遵守开闭原则。
缺点:
1、会出现更多的代码,更多的类,增加程序复杂性。
2、动态装饰时,多层装饰时会更复杂。
3.装饰模式的使用场景
多级缓存设计、mybatis中一级与二级缓存、IO流/发送短信
对接短信接口 阿里云—发送短信失败的情况下自动切换短信平台
阿里云—最开始基本功能
腾讯云----额外增强
华为云—额外增强
4.装饰模式定义
1、抽象组件:定义一个抽象接口,来规范准备附加功能的类
2、具体组件:将要被附加功能的类,实现抽象角色接口
3、抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
4、具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
5.装饰模式的架构图
6.案例(多级缓存)
6.1 创建查询缓存的接口
package com.xhs.pattern.decorate.service;
public interface ComponentCacheService {
T getCache(String key);
}
6.2 创建查询一级缓存的实现类
package com.xhs.pattern.decorate.service.impl;
import com.xhs.pattern.decorate.service.ComponentCacheService;
import com.xhs.pattern.utils.JvmMapCacheUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class JvmComponentCacheServiceImpl implements ComponentCacheService {
@Override
public T getCache(String key) {
// 查询一级缓存 jvm缓存
String entity = JvmMapCacheUtils.getEntity(key, String.class);
log.info("---------------查询一级缓存---------------");
if (entity == null) {
return null;
}
return (T) entity;
}
}
6.3 创建抽象装饰类(扩展功能)
package com.xhs.pattern.decorate.service;
public interface AbstractDecorateService extends ComponentCacheService {
}
6.4 创建二级缓存实现类
package com.xhs.pattern.decorate.service.impl;
import com.xhs.pattern.decorate.service.AbstractDecorateService;
import com.xhs.pattern.utils.JvmMapCacheUtils;
import com.xhs.pattern.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RedisDecorateServiceImpl extends JvmComponentCacheServiceImpl implements AbstractDecorateService {
@Override
public T getCache(String key) {
// 先查询一级缓存
String cache = super.getCache(key);
if (cache != null) {
return (T) cache;
}
// 一级缓存中没有数据查询二级缓存
// 可以是redis,也可以是mysql
String string = RedisUtil.getString(key);
log.info("---------------查询二级缓存---------------");
if (string == null) {
return null;
}
// 写入一级缓存
JvmMapCacheUtils.putEntity(key, string);
return (T) string;
}
}
6.5 创建测试的controller进行验证
package com.xhs.pattern.decorate.controller;
import com.xhs.pattern.decorate.service.impl.RedisDecorateServiceImpl;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class DecorateController {
@Resource
private RedisDecorateServiceImpl redisDecorateService;
@PostMapping("/decorate")
public String decorate(String key) {
String cache = redisDecorateService.getCache(key);
return cache;
}
}
7.查询测试
7.1 第一次查询
7.2 第二次查询
controller层注入最后一级缓存
多级缓存继承上一级缓存的类实现抽象装饰类
参照蚂蚁课堂第十一期
源码地址:https://gitee.com/xhs101/design-pattern-service.git



