谈谈设计模式

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

什么是设计模式?

设计模式是软件设计中前人对相同表征的问题,抽象出的可重复利用的解决方案。也是编码中针对特定场景问题的最佳实践。理解和掌握设计模式,不但可以提高我们编码的效率和质量,同时可以节省开发人员之间沟通的时间成本。

面试官:谈谈你知道的设计模式?

经典回答

设计模式大致可分为以下三类:

  • 1.创建型模式,是对对象创建过程的各种问题和解决方案的总结,这其中包括 工厂模式单例模式构建器模式原型模式

  • 2.结构型模式,是针对软件设计结构的总结,它关注于类,对象继承,组合方式的实践经验。常见的结构型模式有 桥接模式适配器模式装饰器模式代理模式组合模式外观模式享元模式等。

  • 3.行为型模式,是从类或者对象之间的交互,职责划分等角度总结的模式。比较常见的行为型模式有 策略模式解释器模式命令模式观察者模式迭代器模式模板方法模式访问者模式

知识拓展

上面是比较典型的回答,但是我们在回答的时候最好附上一些实例,比如说,装饰器模式,我们可以举例 Java I/O 框架,InputStream 是一个抽象类,标准库还提供了 FileInputStream, BufferedInputStream, ByteArrayInputStream 等各种不同的拓展类,这些子类从不同的角度对 InputSteam 进行了功能拓展,也是经典的装饰器模式应用案例。

如何识别装饰者模式?

识别代码中是否使用装饰者模式,可以通过识别类设计特征来进行判断,也就是其类的构造函数以相同的抽象类或者接口为输入函数。因为装饰器模式本质上是包装同类型实例,来达到 “装饰” 的作用。

例如,BufferedInputStream 经过包装,为输入流增加缓存的功能:

public BufferedInputStream(InputStream in)

下图简单总结了 InputStream 的装饰器模式实践类图:

接下来再来说说创建型模式。其中工厂模式更是在代码中随处可见,这里举个相对不同的 API 设计实践。如 JDK 最新版本的 HTTP/2 Client API, 下面这个 HttpRequest 创建过程就是典型的构造器模式,通常还会被设计成 fluent 风格 的 API, 你也可以叫做方法链。

HttpRequest request = HttpRequest.newBuilder(new URI(uri))
					 .header(headerAlice, valueAlice)
					 .headers(headerBob, value1Bob,
					  headerCarl, valueCarl,
					  headerBob, value2Bob).GET()
					 .build();

使用构造器模式有什么好处?

通过使用构造器模式,我们可以比较优雅的解决构建比较复杂对象的麻烦。试想一下,如果我们不使用构造器,则需要通过构造函数来实现对象的构建,这样我们需要为每一种可能的输入参数的组合编写对应的构造函数,这样会使代码的可阅读性和可维护性变得很差。

设计模式中的单例模式,也是经常被考官问到的一个知识点,具体可参考我的另一篇博文 《Java 面试之单例模式》

上面说了不少代码实践,下面一起来看看主流开源框架, 如 Spring 等是如何在 API 设计中使用设计模式的:

  • BeanFactoryApplicationContext 应用了工厂模式;

  • Bean 的创建中,Spring 为不同的 scope 定义的对象,提供了单例和原型等模式的实现;

  • AOP 模块则是使用了 代理模式, 装饰器模式,适配器模式等;

  • 各种事件监听器,则是使用了观察者模式;

  • Spring JdbcTemplte 等则是应用了模板模式。

总结

今天我们主要谈及什么是设计模式,以及设计模式大致分为三种类型,并从装饰器模式,构造器模式,单例模式入手举例说明。又说了 Spring 框架中,常见模块中用到的设计模式。最后,需要注意的是,设计模式是个好东西,但也不能滥用和过度设计,需要从实际业务为出发点。