Java面试题精选:设计模式(二)

ops/2024/12/14 17:18:49/

1、装饰器模式与代理模式的区别

1)代理模式(Proxy Design Pattern )
原始定义是:让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许将请求提交给对象前后进行一些处理。

代理模式的适用场景

  • 功能增强
    当需要对一个对象的访问提供一些额外操作时,可以使用代理模式
  • 远程(Remote)代理
    实际上,RPC框架也可以看做一种代理模式,GoF的《设计模式》一书中把它称作远程代理。通过远程代理,将网络通信、数据编解码等细节隐藏起来。客户端在使用RPC服务的时候,就像使用本地函数一样,无需了解与服务器交互的细节。除此之外,RPC服务的开发者只需要开发业务逻辑,就像开发本地使用的函数一样,不需要关注与客户端的交互细节
  • 防火墙(Firewall)代理
    当将浏览器配置成使用代理功能时,防火墙就将你的浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把它转给你的浏览器。
  • 保护(Protect or Access)代理
    控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

2)装饰器模式(decorator pattern)
原始定义是:动态的给一个对象添加一些额外的职责. 就扩展功能而言,装饰器模式提供了一种比使用子类更加灵活的替代方案.

装饰器模式的适用场景

  • 快速动态扩展和撤销一个类的功能场景。 比如,有的场景下对 API 接口的安全性要求较高,那么就可以使用装饰模式对传输的字符串数据进行压缩或加密。如果安全性要求不高,则可以不使用。
  • 不支持继承扩展类的场景。 比如,使用 final 关键字的类,或者系统中存在大量通过继承产生的子类。

装饰器模式与代理模式的区别
对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。
对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。
他们之间的边界确实比较模糊,两者都是对类的方法进行扩展,具体区别如下:

  1. 装饰器模式强调的是增强自身;
    代理模式强调要让别人帮忙去做一些与自身没有太多关系的职责(如记录日志、设置缓存)。代理模式是为了实现对对象的控制,因为被代理的对象一般是难以直接获得或者对象内部不想暴漏
  2. 装饰器模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案
    代理模式是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用
  3. 装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制

2 JDK 类库常用的设计模式有哪些?

(1) 抽象工厂

  • javax.xml.parsers.DocumentBuilderFactory抽象类
  • public static DocumentBuilderFactory newInstance()方法
  • 类功能:使得应用程序可以通过XML文件,获得一个能生成DOM对象的解析器。
  • 方法功能:获取一个DocumentBuilderFactory的新实例。这一静态方法会创建一个新的工厂实例。

(2)建造者模式

  • java.lang.StringBuilder,这是一个final类。
  • public StringBuilder append(String str)方法,这一方法是对父类的覆写。
  • 类功能:用于一个不可更改的字符序列。
  • 方法功能:根据现有字符序列和追加字符,通过系统拷贝方法System.arraycopy生成一个新的字符序列。

(3)工厂模式

  • java.text.NumberFormat抽象类。
  • public final static NumberFormat getInstance()方法。
  • 类功能:用于数字格式的抽象基类。
  • 方法功能:返回一个“对当前默认场景下的一个通用数字格式”的NumberFormat。显然属于工厂模式的使用。

(4)原型模式

  • java.lang.Object
  • protected native Object clone() 方法
  • 类功能:所有类的父类
  • 方法功能:根据现有实例,返回一个浅拷贝对象。

(5)单例模式

  • java.lang.RunTime类
  • public static Runtime getRuntime()
  • 类功能:每一个运行的java应用都会有一个唯一的RunTime类的实例,这个实例使得应用程序在运行期间能够受到运行环境的影响。
  • 方法功能:返回一个和当前java应用关联的RunTime对象。

6)适配器模式

  • java.util.Arrays。
  • public static List asList(T… a)方法。
  • 类功能:此类包含了大量对数组操作的方法。
  • 方法功能:将一个引用类型的数组转为一个List。从而可以使用List类的操作来操作数组对象,但是有一点要注意:就是不能使用add(),remove()操作,因为返回的list底层是基于数组的,数组结构是不能更改的。 list类就是这里的适配器,通过这个适配器,对数组的直接操作变为间接操作。

3 Mybatis框架中使用的设计模式有哪些?

(1)建造者模式

  • 在Mybatis环境的初始化过程中,SqlSessionFactoryBuilder会调用 XMLConfigBuilder读取所有的 MybatisMapConfig.xml和所有的 *Mapper.xml文件,构建Mybatis运行的核心对象 Configuration对象,然后将该 Configuration对象作为参数构建一个 SqlSessionFactory对象。

(2)工厂模式

  • 在Mybatis中比如 SqlSessionFactory使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂模式。
    image.png
  • SqlSession可以认为是一个Mybatis工作的核心的接口,通过这个接口可以执行执行SQL语句、获取Mappers、管理事务。类似于连接MySQL的 Connection对象。

(3)单例模式
在Mybatis中有两个地方用到单例模式,ErrorContextLogFactory,其中 ErrorContext是用在每个线程范围内的单例,用于记录该线程的执行环境错误信息,而 LogFactory则是提供给整个Mybatis使用的日志工厂,用于获得针对项目配置好的日志对象。

java">public class ErrorContext {private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<>();​​    private ErrorContext() {  }public static ErrorContext instance() {        ErrorContext context = LOCAL.get();       if (context == null) {            context = new ErrorContext();            LOCAL.set(context);        }        return context;    }}

(4)代理模式

  • 代理模式可以认为是Mybatis的核心使用的模式,正是由于这个模式,我们只需要编写 Mapper.java接口,不需要实现,由Mybatis后台帮我们完成具体SQL的执行。

(5)适配器模式
在Mybatsi的logging包中,有一个Log接口,该接口定义了Mybatis直接使用的日志方法,而Log接口具体由谁来实现呢?Mybatis提供了多种日志框架的实现,这些实现都匹配这个Log接口所定义的接口方法,最终实现了所有外部日志框架到Mybatis日志包的适配。
image.png

4 Spring框架中使用的设计模式有哪些?

1)简单工厂

BeanFactory。Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。

2)工厂方法

FactoryBean接口

实现了FactoryBean接口的bean是一类叫做factory的bean。其特点是,spring会在使用getBean()调用获得该bean时,会自动调用该bean的getObject()方法,所以返回的不是factory这个bean,而是这个bean.getOjbect()方法的返回值。

3)单例模式

Spring依赖注入Bean实例默认是单例的。

Spring的依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创建。

4)适配器模式

SpringMVC中的适配器HandlerAdatper。

HandlerAdatper使得Handler的扩展变得容易,只需要增加一个新的Handler和一个对应的HandlerAdapter即可。

因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类,让适配器代替controller执行相应的方法。这样在扩展Controller时,只需要增加一个适配器类就完成了SpringMVC的扩展了。

5)装饰器模式

Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。

动态地给一个对象添加一些额外的职责。

就增加功能来说,Decorator模式相比生成子类更为灵活。

6)代理模式

AOP底层,就是动态代理模式的实现。

7)观察者模式

Spring 基于观察者模式,实现了自身的事件机制也就是事件驱动模型,事件驱动模型通常也被理解成观察者或者发布/订阅模型。

8)策略模式

Spring框架的资源访问Resource接口。该接口提供了更强的资源访问能力,Spring 框架本身大量使用了 Resource 接口来访问底层资源。

Rsource 接口是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。

Resource 接口本身没有提供访问任何底层资源的实现逻辑,针对不同的底层资源,Spring 将会提供不同的 Resource 实现类,不同的实现类负责不同的资源访问逻辑。


http://www.ppmy.cn/ops/141866.html

相关文章

关于C/C++中typedef为一个类型(包括结构体类型)同时定义多个别名、定义指针类型别名的语法

C/C中可以用关键词typedef为一个类型定义别名&#xff0c;而且可以一次定义多个别名哟&#xff0c;别名与别名之间用逗号分隔&#xff0c;并且一般别名和类型的指针类型也可以同时被定义哟。 目录 示例1-为int类型定义三个别名示例2-为int类型同时定义一般别名和指针类型别名示…

离开wordpress

wordpress确实挺好用的 插件丰富 主题众多 收费的插件也很多 国内的做主题的也挺好 但是服务器跑起来各种麻烦伤脑筋 需要花在维护的时间太多了 如果你的网站持续盈利 你就会更担心访问质量访问速度 而乱七八糟的爬虫黑客 让你的服务器不堪重负 突然有一天看到了静态站…

力扣9. 回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而…

python编程Day13-异常介绍捕获异常抛出异常

异常 介绍 1, 程序在运行时, 如果Python解释器遇到到一个错误, 则会停 止程序的执行, 并且提示一些错误信息, 这就是异常. 2, 程序停止执行并且提示错误信息这个动作, 通常称之为: 抛出 (raise) 异常 # f open(aaaa.txt) # FileNotFoundError: [Errno 2] No such file or dire…

计网_虚拟局域网VLAN

2024.12.08&#xff1a;计算机网络虚拟局域网VLAN学习笔记 虚拟局域网VLAN VLAN背景&#xff08;认真看&#xff09;VLAN定义&#xff08;最大的好处是隔离广播域&#xff09;VLAN以太网帧格式的扩展 VLAN背景&#xff08;认真看&#xff09; 以太网使用的是广播信道&#xff0…

取消网络请求

1. 使用 fetch 的取消请求 fetch 使用 AbortController 提供取消请求的功能。 示例代码 let currentController null;function fetchWithCancel(url) {// 如果有上一个请求&#xff0c;则取消它if (currentController) {currentController.abort();}// 创建新的 AbortContr…

【vue2】el-select,虚拟滚动(vue-virtual-scroller)

需求背景​​​​​​ vue2+element-ui项目中,当el-select中数据量较大时(超出5000个dom节点),会导致页面加载和渲染卡顿、el-select下拉列表延迟展开。 在现在的el-select的基础上使用分页或者虚拟列表的形式去处理大量的下拉菜单,可以保证页面的正常渲染及el-select的…

全局搜索正则表达式(grep)

一.grep简介 grep 全程Globally search a Regular Expression and Print&#xff0c;是一种强大的文本搜索工具&#xff0c;它能使用特定模式匹配&#xff08;包括正则表达式&#xff09;搜索文本&#xff0c;并默认输出匹配行。Unix的grep家族包括grep和egrep 二.grep的工作…