框架(Framework)中常用设计模式分析
简介
概述
软件模式是在软件开发过程中对某些可重现问题的一些有效解决方法,软件模式的基础结构主要由四部分构成,包括问题描述【待解决的问题是什么】、前提条件【在何种环境或约束条件下使用】、解法【如何解决】和效果【有哪些优缺点】等。
模式分类
基于设计模式的特点,我们可以分为三大类,例如:
创建型模式(5种):
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式(7种):
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式(11种):
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
创建型模式设计与分析
简单工厂模式
如何理解简单工厂模式?
- 通过静态方法(相对比较多)或实例方法创建对象.
- 封装对象创建过程(基于条件的不同创建不同的具体产品)
简单工厂应用场景分析?
- JDBC(DriverManager.getConnection(……))
- HikariCP(HikariDataSource.getConnection())
- Mybatis(Configuration,…)
- SpringBoot(RedisConnectionFactory)
简单工厂中的对象角色?
- 抽象产品对象(例如MyBatis中Executor,…)
- 具体产品对象 (例如MyBatis中SimpleExecutor,…)
- 具体工厂对象(例如Configuration,…)
简单工厂应用分析?
- 优势:解耦(对象应用者与对象创建者之间的耦合),简单
- 劣势:可扩展性相对较差(创建产品的对象的工厂方法不够灵活)
工厂方法模式(Factory Method)
如何理解工厂方法模式?
- 创建型模式(负责创建对象)
- 工厂模式(平时所说的工厂模式就是工厂方法模式)
- 此模式的特点是基于抽象工厂扩展具体工厂然后创建产品对象。
工厂方法模式的应用场景分析?
- Mybatis (SqlSessionFactoryBean)
- Spring(DataSourceFactory,TransactionFactory)
- …
工厂方法模式角色分析?
- 抽象产品(Product)
- 具体产品(ConcreteProduct)
- 抽象工厂(Factory)
- 具体工厂(ConcreteFactory)
例如:
mybatis中创建SqlSession对象
- SqlSession(抽象产品)
- DefaultSqlSession(具体产品)
- SqlSessionFactory(抽象工厂)
- DefaultSqlSessionFactory(具体工厂)
Spring整合mybatis时,SqlSessionFactory对象过程分析。
- SqlSessionFactory (抽象产品)
- DefaultSqlSessionFactory(具体产品)
- FactoryBean(抽象工厂)
- SqlSessionFactoryBean(具体工厂)
工厂方法模式应用分析?
1)优势: 相对于简单工厂更加灵活,更加适合创建具备等级结构(继承关系)的产品。
2)劣势: 假如每个抽象产品都对应一个具体工厂,那么工厂类可能会比较多。
抽象工厂(Abstract Factory)
如何理解抽象工厂?
- 工厂方法模式用于创建具备一定等级结构的产品。
- 抽象工厂是多个工厂方法的综合应用,因为它要同时创建多个具备一定等级结构的产品,我们可以将这些产品理解产品族。
抽象工厂的应用场景?(产品族—>多个抽象产品)
- Spring(ClientHttpRequestFactory):了解消息头,消息体对象创建
- …
抽象工厂对象角色分析?
- 抽象产品(Product)
- 具体产品(ConcreteProduct)
- 抽象工厂(Factory)
- 具体工厂(ConcreteFactory)
例如:ClientHttpRequestFactory 抽象工厂的应用
- 抽象工厂 (ClientHttpRequestFactory)
- 具体工厂 (SimpleClientHttpRequestFactory)
- 抽象产品 (ClientHttpRequest,HttpHeaders,…)
- 具体产品 (SimpleStreamingClientHttpRequest,…)
抽象工厂应用分析?
- 优势:工厂方法模式可能会产生多个工厂类,基于抽象工厂可创建产品族对象,可以减少工厂类对象的个数,从而更好节省资源。
- 劣势:一旦有新的产品族的诞生,这个抽象工厂扩展起来就会比较复杂。
建造模式(Builder)
如何理解建造模式?
-
又称之为构建模式(施工队模式),通常用于构建相对比较复杂对象。例如,构建过程复杂,对象依赖关系复杂。
建造模式应用场景分析? -
Mybatis(SqlSessionFactoryBuilder,XmlConfigBuilder,XmlStatementBuilder)
-
Spring(XmlBeanDefinitionReader)
-
redis(RedisCacheManager)
建造模式对象角色分析?
- 抽象建造对象角色(Builder):可能是接口,也可能是抽象类,此角色也可以省略。
- 具体建造对象角色(ConcreteBuilder)
- 导演角色(Director): 持有建造者对象,可以省略
- 抽象产品角色(Product) 抽象产品角色,可以省略
- 具体产品角色(ConcreteProduct) 具体产品角色
建造模式应用分析?
- 优势:解耦对象的应用以及对象创建,通过建造者创建复杂产品对象,尤其是基于配置文件创建对象的场景。
- 劣势:要构建的对象结构假如频繁变化可能导致构建者对象的设计比较复杂。
单例模式(Singleton)
如何理解单例模式?
- 保证一个类的实例在”特定范围”只有一份(例如一个JVM内部,一个线程内部),并且提供一个全局访问点可以访问到这份实例。
单例模式的应用场景?
- Spring(Singleton作用域的Bean对象,AbstractBeanFactory的getSingleton方法)
- MyBatis(ErrorContext对象是每个线程一份此类实例)
- HikariCP(HikariPool)
- JDK (Runtime,…)
单例模式对象角色构成?
- 具体产品对象(例如Singleton)
单例模式应用分析
- 优势:科学使用资源,避免频繁创建,销毁对象时造成的资源浪费。
- 劣势:设计不够严谨会存在线程安全问题,可扩展性相对较差。
原型模式(Prototype)
对象的克隆(对象的一个拷贝),例如Cloneable接口
结构型模式设计及分析
适配器模式 (Adapter)
如何理解适配器模式?
- 适配器模式将一个接口转换成客户希望的另一个接口,以解决接口不兼容问题。
- 又名包装器(Wrapper)模式
- 分为类适配器,对象适配器。
适配器模式场景分析? - 生活中(一拖三充电头、HDMI 转 VGA)
- mybatis (Log接口)
- spring (HandlerAdapter,AdvisorAdapter)
适配器模式对象角色构成?
- Target(目标抽象类):抽象类或接口,也可以是具体类
- Adapter(适配器类): 负责对Adaptee和Target进行适配。
- Adaptee(适配者类):适配者即被适配的角色。
适配器模式应用分析?
- 优势:对客户端透明,扩展性好,复用性好
- 劣势:是一种补偿机制的实现,主要用于后期扩展。
装饰模式 (Decorator)
如何理解装饰模式?
- 油漆工模式
- 基于目标对象添加额外职责(功能扩展)
装饰模式场景分析?
- mybatis(Executor,Cache)
- spring(…)
装饰模式角色构成?
- Component: 抽象构件
- ConcreteComponent: 具体构件
- Decorator: 抽象装饰类
- ConcreteDecorator: 具体装饰类
装饰模式应用分析?
- 提供了相对继承更加灵活的功能扩展方式
- 实现相对复杂。
代理模式 (Proxy)
如何理解代理模式?
- 基于目标对象创建代理对象,并由代理对象控制目标对象的执行。
- 基于OCP原则扩展目标对象的功能。
代理模式场景分析?
- mybatis (为接口创建代理对象,拦截器应用)
- spring (AOP)
代理模式角色构成?
- Subject: 抽象主题角色
- Proxy: 代理主题角色
- RealSubject: 真实主题角色
代理模式应用分析?
- 优势:基于OCP进行控制,扩展目标对象
- 劣势:由于代理对象的创建可能会导致性能上的缺陷。
享元模式(Flyweight)
如何理解享元模式?
- 以共享的方式使用对象。
- 通过共享技术有效地减少对象创建,支持对象的复用。
享元模式应用场景分析?
- 整数池,字符串池
- 连接池,线程池
享元模式角色构成?
- 抽象享元角色:由抽象类、接口来担当。
- 具体享元角色:抽象类、接口对应的子类或实现。。
- 享元工厂角色:负责创建和管理享元角色。
- 客户端角色:维护对所有享元对象的引用。
享元模式应用分析?
- 优点:大大减少对象的创建,降低系统的内存,使效率提高。
- 缺点:提高了系统的复杂度
门面模式(Façade)
如何理解门面模式?
- 隐藏系统的复杂性,并向对外提供一个可以访问系统的门面接口。
- 简化对目标子系统相关类方法的调用,侧重于功能整合(多个小系统或小对象整合成一个功能丰富的大对象)
门面模式应用场景分析?
- 日志门面API,例如SLF4J
门面模式的角色构成?
- 门面角色:客户端调用这个角色的方法。
- 子系统角色:可以同时有一个或者多个子系统。
门面模式应用分析?
- 优点:减少系统相互依赖,提高灵活性和安全性。
- 缺点:增加子系统,需要修改门面类,容易引入风险。
组合模式(Composite)
如何理解组合模式?
- 又叫合成模式,体现的是整体部分关系。
组合模式应用场景分析?
- mybatis中的SqlNode(动态sql)
- spring mvc 中的HandlerMethodArgumentResolverComposite。
组合模式的角色构成?
- 组合部件(Component):它是一个抽象接口。
- 叶子(Leaf):在组合中表示子节点对象。
- 合成部件(Composite):表示自己还有孩子。
组合模式应用分析?
- 优点:减少系统相互依赖,提高灵活性和安全性。
- 缺点:增加子系统,需要修改门面类,容易引入风险。
桥接模式(Bridge)
如何理解桥接模式?
- 把抽象(abstraction)与行为实现(implementation)分离。
桥接模式应用场景分析? - JDBC (DriverManager Driver)
桥接模式的角色构成?
- 抽象角色(Abstraction):抽象类或接口。
- 具体抽象角色实现(RefinedAbstraction):扩充抽象类。
- 操作抽象角色(Implementor):抽象类或接口。
- 具体操作角色(ConcreteImplementor):具体实现类,实现或继承了操作抽象角色 。
桥接模式应用分析?
- 优点:解耦,使得抽象和实现可以独立扩展,进而提高其灵活性。
- 缺点:客户应用方必须知道选择哪一种类型的实现。
行为型模式设计及分析
策略模式(Strategy)
如何理解策略模式?
- 基于面向对象中封装变化的思想将算法进行封装。
- 基于多态特性实现策略的灵活变化(雕刻印刷到活字印刷)
- 策略模式中每个行为或算法之间没有关联。
策略模式场景分析? - MyBatis(Executor,Cache)
- Spring (Aop,Resource)
- Spring Cloud (Ribbon,IRule)
策略模式角色构成?
- Context: 环境类 (抽象策略持有者)
- Strategy: 抽象策略类 (定义了策略的抽象类或接口)
- ConcreteStrategy: 具体策略类(实现了具体策略的对象)
策略模式应用分析?
- 优势:稳定, 较为灵活,扩展性好,避免了大量的if else结构。
- 劣势:对外暴露了类所有的行为和算法,行为过多导致策略类膨胀。
模板方法模式(Template Method)
如何理解模板方法模式?
- 基于算法步骤进行封装(算法骨架)
- 算法步骤中的部分实现交给子类
模板方法模式场景分析?
- mybatis (SqlSessionTemplate,BaseExecutor)
- Spring (JdbcTemplate)
模板方法模式角色构成?
- 抽象产品(AbstractObject)
- 具体产品(ConcreteObject)
模板方法模式应用分析?
- 优势:提高代码的复用性。
- 劣势:对于静态方法而言不能实现多态特性。
观察者模式(Observer)
如何理解观察者模式?
- 定义了对象之间的一种一对多的依赖关系
- 对象状态发生变化,其所有依赖对象可以得到通知。
观察者模式场景分析? - Spring(ApplicationListener)
观察者模式角色构成分析?
- 目标对象角色(Subject)
- 具体目标对象角色(ConcreteSubject)
- 抽象观察者角色(Observer)
- 具体观察者角色(ConcreteObserver)
观察者模式应用优势、劣势分析?
- 优势:降低了目标对象与观察者对象之间的耦合。
- 劣势:目标对象观察者比较多的话,性能上会有影响。
迭代器模式(Iterator)
如何理解迭代器模式?
- 又称为游标(Cursor)模式。
- 提供一种方法,顺序访问聚合对象(集合)中的元素。
- 聚合对象只负责数据存储,而内部数据的迭代交给迭代器,以实现“单一职责”原则。
迭代器模式场景分析?
- Java (Iterator)
迭代器模式角色构成?
- 客户端角色(Client)
- 抽象聚合类(Aggregate)
- 具体聚合类(ConcreteAggreate)
- 抽象迭代器(Iterator)
- 具体迭代器(ConcreteIterator)
迭代器模式应用优势、劣势分析?
- 优势:支持不同方式遍历聚合对象,遵守了单一职责元素,开闭原则。
- 劣势:类的个数增加,增加了系统的复杂性。
状态模式(State)
如何理解迭代器模式?
-允许对象在内部状态发生改变时改变它的行为。
-将对象状态封装成独立的类,每个状态都有对应该状态下的事务,并可控制该状态到其他状态的转移。
-状态模式中的状态之间有关联,并且状态本身控制着状态转移。
状态模式应用场景分析?
- 对象依赖状态,行为随状态改变而改变的情景,或者存在大量的if else和分支结构等
- Spring状态机
状态模式角色构成?
- Context(环境类)环境类又称为上下文类,它是拥有多种状态的对象。
- State(抽象状态类)在抽象状态类中声明了各种不同状态对应的方法
- ConcreteState(具体状态类)每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。
状态模式应用优势、劣势分析? - 优势: 容易新加状态,封装了状态转移规则,每个状态可以被复用和共享,避免大量的if else结构。
- 劣势:该模式结构和实现相对复杂,状态过多导致增加类和对象个数。
命令模式(Command)
如何理解命令模式?
- 将请求封装为对象,使请求发出方和请求执行方责任分开,也就是解耦。
命令模式应用场景分析?
- 请求调用者需要与请求接收者解耦时,命令模式可以使调用者和接收者不直接交互。
- 系统随机请求命令或经常增加、删除命令时,命令模式可以方便地实现这些功能。
命令模式角色构成?
- 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
- 具体命令类(Concrete Command)角色:它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
- 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
- 调用者/请求者(Invoker)角色:是请求的发送者,它可拥有多个命令,并通过访问命令对象来执行请求,它不直接访问接收者。
命令模式应用优势、劣势分析? - 通过引入抽象接口降低系统的耦合度。
- 扩展性良好,增加或删除命令非常方便,满足“开闭原则”。
- 可能产生大量具体的命令类,这会增加系统的复杂性。
解释器模式(Interpreter)
如何理解解释器模式?
- 使用类定义语法,实用继承机制改变或扩展。
解释器模式应用场景分析? - 当语言的文法较为简单,且执行效率不是关键问题时。
- 当问题重复出现,且可以用一种简单的语言来进行表达时。
- 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如 XML 文档解释。
解释器模式角色构成? - 抽象表达式(Abstract Expression):定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
- 终结符表达式(Terminal Expression):是抽象表达式的子类
- 非终结符表达式(Nonterminal Expression):也是抽象表达式的子类
- 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能
- 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树。
解释器模式应用优势、劣势分析? - 扩展性好, 容易实现。
- 执行效率较低,会引起类膨胀。
访问者模式(Visitor)
如何理解访问者模式?
访问者模式应用场景分析?
访问者模式角色构成?
访问者模式应用优势、劣势分析?
职责链模式(Chain of Responsibility)
如何理解责任链模式?
责任链模式应用场景分析?
责任链模式角色构成?
责任链模式应用优势、劣势分析?
中介者模式(Mediator)
如何理解中介者模式?
中介者模式应用场景分析?
中介者模式角色构成?
中介者模式应用优势、劣势分析?
备忘录模式(Memento)
如何理解备忘录模式?
备忘录模式应用场景分析?
备忘录模式角色构成?
备忘录模式应用优势、劣势分析?
总结(Summary)
设计模式描述的是一种套路,一种经验的总结,对于编码初学者如何保证代码的的质量呢,个人觉得这些模式就是一种规范。
作者:雨田说码
来源链接:https://blog.csdn.net/maitian_2008/article/details/121314392
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。