龙空技术网

面试官问装饰者模式在JDK和Mybatis中是怎么用的?本文教你如何答

Java识堂 1164

前言:

而今姐妹们对“java开发收银系统”大致比较注重,姐妹们都需要知道一些“java开发收银系统”的相关内容。那么小编同时在网络上汇集了一些对于“java开发收银系统””的相关文章,希望你们能喜欢,我们一起来了解一下吧!

本文为小编原创文章,首发于Java识堂,一个高原创,高收藏,有干货的微信公众号,一起成长,一起进步,欢迎关注

介绍

有一个卖煎饼的店铺找上了你,希望你能给她们的店铺开发一个收银系统,已知一个煎饼的价格是8元,一个鸡蛋的价格是1元,一根香肠的价格是2元。

你二话不说写出了如下代码

测试一下,正常工作

但是这样会造成一个问题,煎饼的搭配种类很多。比如,加1根香肠的煎饼,加2个鸡蛋的煎饼,加2个鸡蛋和1根香肠的煎饼,如果对每一种可能都写一个实现,会造成类爆炸。

这个时候你就应该想到用装饰者模式了。来看看如何改造上面的代码

如果有人想买加2个鸡蛋和1根香肠的煎饼,实现方式如下

可以看到当要添加新的功能时,我们可以使用继承,在子类中添加新能的扩展实现。但有时候继承是不可行的,因为有些类是被final修饰的。而且待添加的新功能存在多种组合,使用继承的方式会导致大量子类的的出现。

而装饰者模式则是通过组合的方式来替代继承,为对象添加功能

看一下上述代码的UML图

从上图就可以画出装饰者模式的UML图如下

Component(组件):组件接口或抽象类定义了全部组件实现类以及所有装饰器实现的行为。

ConcreteComponent(具体组件实现类):具体组件实现类实现了Component接口或抽象类。通常情况下,具体组件实现类就是被装饰器装饰的原始对象,该类提供了Component接口中定义的最基本的功能,其他高级功能或后序添加的新功能,都是通过装饰器的方式添加到该类的对象之上的。

Decorator(抽象装饰器):所有装饰器的父类,它是一个实现了Component接口的类,并在其中封装了一个Component对象,也就是被装饰的对象。而这个被装饰的对象只要是Component类型即可,这就实现了装饰器的组合和复用

ConcreteDecorator(具体的装饰器):该实现类要向被装饰对象添加某些功能

java io包

从上图可以看出,InputStream是组件,FileInputStream,ByteArrayInputStream是具体组件实现类,FilterInputStream是抽象装饰器,LineInputStream是具体的装饰器。

InputStream和OutputStream,Reader和Writer体系都用到了装饰者模式,不再概述。

举个例子,我们进行IO操作时,经常写如下代码,你是否意识到这个用到了装饰者模式呢?

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("D:/test.txt")));

当我们意识到这个用到装饰器模式时,想增加新功能时,就直接查找是否有相应的具体装饰器即可,或者自己实现一个装饰器,而不是陷入迷茫。

举个例子,我们想把从文件中读入的内容都转为小写时,只要自己继承FilterInputStream,实现相应的功能即可

D:/test.txt的文件内容如下

THIS is JUST for TEST

测试类

Mybatis缓存模块

Mybatis的缓存模块中,使用了装饰器模式的变体,其中将Decorator接口和Componet接口合并为一个Component接口,类间结构如下

Mybatis的Cache接口就是上图中的Component

public interface Cache { // 省略一部分方法 String getId(); void putObject(Object key, Object value); Object getObject(Object key); Object removeObject(Object key);}

看一下Cache接口的实现类

仔细看包名,由包名就可以看到PerpetualCache扮演着ConcreteComponent(具体组件实现类)的角色,其余的都是装饰类,为什么要弄这么多装饰类呢?

举个例子,我们可以在二级缓存中配置缓存回收策略。

可配置的选项有

LRU:最近最少使用,移除最长时间不被使用的对象

FIFO:先进先出,按对象进入缓存的顺序来移除它们

SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象

WEAK:弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象

再看上面的装饰类和这个配置选项的名字是不是很类似,Mybatis根据你配置的缓存回收策略来选择相应的装饰类,完成扩展功能。

知道其他应用场景的小伙伴欢迎留言

原创不易,欢迎转发

标签: #java开发收银系统