首页 > 编程知识 正文

java源码分享网站,枚举单例模式优缺点

时间:2023-05-04 17:58:44 阅读:135277 作者:2603

一.装修人模式简介

装饰者模式定义:在不改变原始对象的情况下附加功能比生成子类更灵活。

适用的场景:动态地向对象添加或撤消功能。

优点:可以在不改变原始对象的情况下动态扩展功能。 能够按所需顺序执行扩展的多个功能,实现不同的效果。

缺点:更多的类使程序变得复杂

类型:结构类型。

类图:

源代码分析中的典型应用

Java I/O的装饰者模式

Spring Session的装饰者模式

Mybatis缓存中的装饰者模式

二.系统增加日志,安全、限流示例

可以提取一般系统的安全性、日志、流限制等与业务无关的代码,在Controller前后用切面进行改造。 模板方法模型可以部分解决这个问题。

公共类基础辅助{

logger logger=logger factory.getlogger (base command.class );

公共语音执行

//记录日志

Logger.debug(.start . );

//过滤跨站点脚本攻击

paramXssAspect (;

//限制费率

doRateLimit (;

doBusiness (;

Logger.debug(…end…);

}

公共业务语音业务(;

}

classplaceorderaspectextendsbaseaspect {

@Override

公共void do business (

//订单操作

}

}

classpayorderaspectextendsbaseaspect {

@Override

公共void do business (

//支付操作

}

}

父母班已经写了“一团糟”的非业务代码。 只需保留一个抽象方法等子类进行实现。 副班很干净。 只要关注业务逻辑就可以了。

这种方式的最大缺点是父类定义一切。 要执行这些非业务代码,子类只能无条件接受,比如按什么顺序执行。 如果有不限制速度的子类,就不能将其删除。

利用装饰者模型,可以灵活地解决上述问题。

//顶级抽象组件

接口I aspect {

字符串下载错误(;

}

//基本上是装饰过的类,做一些公共处理

classaspectimplimplementsiaspect {

@Override

公共字符串下载代理(

return '裸体跑步代码. ';

}

}

abstractclassabstractdecoratorimplementsiaspect {

//很重要,将抽象组件组合到自己的类中

私有I aspect aspect;

用publicabstractdecorator (iaspectaspect ) IAspect做自己

this.aspect=aspect;

}

@Override

公共字符串下载代理(

return this.aspect.dohandleraspect (;

}

}

日志添加、安全和流限制功能:

classloggeraspectextendsabstractdecorator {

publicloggeraspect { iaspectaspect }

辅助(aspect );

}

@Override

公共字符串下载代理(

return super.doHandlerAspect ('日志.';

}

}

classparamxssaspectextendsabstractdecorator {

publicparamxssaspect (iaspectaspect ) {

辅助(aspect );

}

@Override

公共字符串下载代理(

return super.doHandlerAspect()+"+过滤危险字符.";

}

}

class LimitAspect extends AbstractDecorator{

public LimitAspect(IAspect aspect){

super(aspect);

}

@Override

public String doHandlerAspect() {

return super.doHandlerAspect()+"+限流.";

}

}

测试一下:

public class Test {

public static void main(String[] args) {

IAspect aspect = new LimitAspect(new ParamXssAspect(new LoggerAspect(new AspectImpl())));

System.out.println(aspect.doHandlerAspect());

}

}

运行结果:

------

裸跑代码.+记录日志.+过滤危险字符.+限流.

------

通过上面可以看出,装饰者模式可以任意次序组装功能,是不是很灵活?另外,也可以把上述三个功能封装成注解@Log、@ParamXss、@AccessLimit,实现可拔插。如果读者想看注解功能完整实现,可以参考我的这个项目: SpringBoot+JWT+Shiro+MybatisPlus实现Restful快速开发后端脚手架

三、源码中的装饰者模式

3.1、Java IO中是体现最明显的装饰者模式。

它基于字符流(InputStream/OutputStream) 和 字节流(Reader/Writer)作为基类,下面画出InputStream、Reader的部分类图:

这里总结几种常用流的应用场景:

流名称

应用场景

ByteArrayInputStream

访问数组,把内存中的一个缓冲区作为 InputStream 使用,CPU从缓存区读取数据比从存储介质的速率快10倍以上

StringBufferInputStream

把一个 String 对象作为。InputStream。不建议使用,在转换字符的问题上有缺陷

FileInputStream

访问文件,把一个文件作为 InputStream ,实现对文件的读取操作

PipedInputStream

访问管道,主要在线程中使用,一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯

SequenceInputStream

把多个 InputStream 合并为一个 InputStream . “序列输入流”类允许应用程序把几个输入流连续地合并起来

DataInputStream

特殊流,读各种基本类型数据,如byte、int、String的功能

ObjectInputStream

对象流,读对象的功能

PushBackInputStream

推回输入流,可以把读取进来的某些数据重新回退到输入流的缓冲区之中

BufferedInputStream

缓冲流,增加了缓冲功能

3.2、Spring Session中的ServletRequestWrapper(Response也一样)的装饰者模式。

public class ServletRequestWrapper implements ServletRequest {

private ServletRequest request;//组合抽象接口到自己的类中

public ServletRequestWrapper(ServletRequest request) {//可以构造自己

if(request == null) {

throw new IllegalArgumentException("Request cannot be null");

} else {

this.request = request;

}

}

public ServletRequest getRequest() {

return this.request;

}

public void setRequest(ServletRequest request) {

if(request == null) {

throw new IllegalArgumentException("Request cannot be null");

} else {

this.request = request;

}

}

//省略...

}

3.3、Spring Cache中的TransactionAwareCacheDecorator的装饰者模式。

其实从类名就可以看出。

public class TransactionAwareCacheDecorator implements Cache {

private final Cache targetCache;//把Cache组合到自己类中

public TransactionAwareCacheDecorator(Cache targetCache) {//通过Cache构造自己

Assert.notNull(targetCache, "Target Cache must not be null");

this.targetCache = targetCache;

}

public T get(Object key, Class type) {

return this.targetCache.get(key, type);

}

public void put(final Object key, final Object value) {

// 判断是否开启了事务

if (TransactionSynchronizationManager.isSynchronizationActive()) {

// 将操作注册到 afterCommit 阶段

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {

public void afterCommit() {

TransactionAwareCacheDecorator.this.targetCache.put(key, value);

}

});

} else {

this.targetCache.put(key, value);

}

}

// ...省略...

}

3.4、Mybatis中的装饰者。

Cache为抽象构件类,PerpetualCache为具体构件类,decorators包下的类为装饰类,这里没有抽象装饰类。

参考:

《码农翻身》gldgq

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。