装饰模式(Decorator Pattern)
代理模式:动态地给一个对象添加一些额外的职责,它比生成子类方式更为灵活。
- 优点:在某些时候装饰模式比继承(inheritance)要更加灵活

装饰模式的组成
(1)抽象组件:定义一个抽象接口,来规范准备附加功能的类
(2)具体组件:将要被附加功能的类,实现抽象构件角色接口
(3)抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口
(4)具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。
应用场景
- Spring Session
- Mybatis的一级二级缓存
- I/O 流(基于字符流[InputStream/OutputStream] 和 字节流[Reader/Writer]作为基类,eg:new FileInputStream(new File()),以下为Reader的类图)

装饰模式与责任链模式区别
责任链模式的实现原理
- 每个被调用者都持有下一个被调用者的引用,客户端只需要发起第一个调用者即可完成所有的操作。
- new A()-->new B()-->new C()====>A-->B-->C
装饰模式的实现原理
- 持有被装饰的对象,需具备被装饰者的行为,对其行为进行补充增强
- new A(new B(new C()))====>C-->B-->A
自定义注解实现多级缓存
a.注解定义
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExtJaryeCache {
}
b.注解使用
@RequestMapping("/getUser")
@ExtJaryeCache
public UserEntity getUser(Integer userId) {
return userMapper.findByUser(userId);
}
c.注解拦截
@Aspect
@Component
@Slf4j
public class ExtAsyncAop {
@Autowired
private JaryeCacheUtils jaryeCache;
/**
* 使用Aop拦截我们的方法上是否使用缓存注解
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around(value = "@annotation(com.jarye.aop.ExtJaryeCache)")
public Object doAround(ProceedingJoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
// 获取目标方法
Method targetMethod = methodSignature.getMethod();
// // 拼接缓存的key
String key = targetMethod.getName() + Arrays.toString(targetMethod.getParameterTypes()) +
Arrays.toString(joinPoint.getArgs());
return jaryeCache.getCacheEntity(key,Object.class,joinPoint);
}
}
d.装饰模式核心方法
public <T> T getCacheEntity(String key,Class<T> t, ProceedingJoinPoint joinPoint) {
// 先查询二级缓存
T redisUser = redisUtils.getEntity(key, t);
if (redisUser != null) {
return (T) redisUser;
}
// 如果一级缓存存在数据
T jvmUser = super.getCacheEntity(key,t,joinPoint);
if (jvmUser == null) {
return null;
}
// 将该缓存数据放入到二级缓存中
redisUtils.putEntity(key, jvmUser);
return (T) jvmUser;
}
public <T> T getCacheEntity(String key, Class<T> t,ProceedingJoinPoint joinPoint) {
// 先查询我们的一级缓存(Jvm内置)
UserEntity jvmUser = JvmMapCacheUtils.getEntity(key, UserEntity.class);
if (jvmUser != null) {
return (T) jvmUser;
}
// 查询我们的db 通过aop直接获取到我们的目标对象方法
try {
Object resultDb = joinPoint.proceed();
// 数据库DB有的情况 将该内容缓存到当前Jvm中
JvmMapCacheUtils.putEntity(key, resultDb);
return (T) resultDb;
} catch (Throwable throwable) {
throwable.printStackTrace();
return null;
}
}
装饰模式(Decorator Pattern)的更多相关文章
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式-装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 装饰模式(Decorator pattern)
装饰模式(Decorator pattern): 又名包装模式(Wrapper pattern), 它以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式以对客户透明的方式动态的给 ...
- 设计模式系列之装饰模式(Decorator Pattern)
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...
- 装饰模式Decorator Pattern
1.主要优点 装饰模式的主要优点如下: (1) 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加. (3) 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类 ...
- 设计模式——装饰模式(Decorator Pattern)
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. UML图: 模型类: Component类: package com.cnblog.clarck; /** ...
- 使用C# (.NET Core) 实现装饰模式 (Decorator Pattern) 并介绍 .NET/Core的Stream
该文章综合了几本书的内容. 某咖啡店项目的解决方案 某咖啡店供应咖啡, 客户买咖啡的时候可以添加若干调味料, 最后要求算出总价钱. Beverage是所有咖啡饮料的抽象类, 里面的cost方法是抽象的 ...
随机推荐
- map+area标签
map标签是用于定义一个客户端的图像映射即带有可点击区域的一幅图像,配合area标签 area 元素永远嵌套在 map 元素内部.area 元素可定义图像映射中的区域 例:要实现一幅地图上鼠标点击或者 ...
- Java学习的第五十六天
1.例11.5引用保护成员 public class Cjava { public static void main(String[]args) { Student1 s1=new Student1( ...
- [Luogu P1119] 灾后重建 (floyd)
题面 传送门:https://www.luogu.org/problemnew/show/P1119 Solution 这题的思想很巧妙. 首先,我们可以考虑一下最暴力的做法,对每个时刻的所有点都求一 ...
- uniapp使用axios以及封装错误重试解决方案
在uniapp中,使用axios进行请求时,uniapp无法使用axios的适配器,需要基于uni.request来定义适配器. 安装完成axios后在项目utils目录下建一个axios文件夹 文中 ...
- Linux系统下安装配置JDK(rpm方式及tar.gz方式)
以前都是在Windows环境进行开发的,最近因工作需要:学习在Linux系统下搭建开发环境,自此记录搭建过程,以方便查阅. 本文借鉴了 Angel挤一挤 .小五 两位的博客. 准备材料: JDK下载链 ...
- python_登陆验证文件上传下载_socket
client.py import os import sys import json import struct import socket # 下载--接收文件 def download(sk): ...
- minishell的实现
直接上各个模块的代码,注释都在文档代码中,非常详细,加上最后的Makefile文件完全可以自行运行看懂: main函数一个文件main.c 1 /* 2 minishell实现的功能:简单命令解析.管 ...
- python之《线程与进程》
多线程的应用场景 不适用cpu操作密集型任务, 适合io操作密集型任务 同一进程中的数据是互通的,因为python多线程是假多线程,我们要用到多核就需要开多个进程来实现,但是坏处是数据不能互通 线程: ...
- ceph unfound objects 处理
ceph Vol 45 Issue 1 1.unfound objects blocking cluster, need help! Hi, I have a production cluster o ...
- 这 12 款 IDEA 插件你用过几款?
搞 Java开发用什么软件,当然是神器idea了,那么,idea的插件对于你来说就是必不可少的了,不仅可以提高自己的编码效率,还可以减轻工作时的枯燥烦闷.接下来就来说说,我平时敲代码用的什么插件吧. ...