简介
概述
软件模式是在软件开发过程中对某些可重现问题的一些有效解决方法,软件模式的基础结构主要由四部分构成,包括问题描述【待解决的问题是什么】、前提条件【在何种环境或约束条件下使用】、解法【如何解决】和效果【有哪些优缺点】等。
模式分类
基于设计模式的特点,我们可以分为三大类,例如:
创建型模式(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)分离。
桥接模式应用场景分析? - MVC
- JDBC (DriverManager Driver)
桥接模式的角色构成?
- 抽象角色(Abstraction):抽象类或接口。
- 具体抽象角色实现(RefinedAbstraction):扩充抽象类。
- 操作抽象角色(Implementor):抽象类或接口。
- 具体操作角色(ConcreteImplementor):具体实现类,实现或继承了操作抽象角色 。
桥接模式应用分析?
- 优点:解耦,使得抽象和实现可以独立扩展,进而提高其灵活性。
- 缺点:客户应用方必须知道选择哪一种类型的实现。
行为型模式设计及分析
策略模式(Strategy)
如何理解策略模式?
- 基于面向对象中封装变化的思想将算法进行封装。
- 基于多态特性实现策略的灵活变化(雕刻印刷到活字印刷)
策略模式场景分析?
- MyBatis(Executor,Cache)
- Spring (Aop,Resource)
- Spring Cloud (Ribbon,IRule)
策略模式角色构成?
- Context: 环境类 (抽象策略持有者)
- Strategy: 抽象策略类 (定义了策略的抽象类或接口)
- ConcreteStrategy: 具体策略类(实现了具体策略的对象)
策略模式应用分析?
- 优势:稳定,可扩展性好。
- 劣势:可能导致系统中类过于庞大。
模板方法模式(Template Method)
如何理解模板方法模式?
- 基于算法步骤进行封装(算法骨架)
- 算法步骤中的部分实现交给子类
模板方法模式场景分析?
- mybatis (SqlSessionTemplate,BaseExecutor)
- Spring (JdbcTemplate)
模板方法模式角色构成?
- 抽象产品(AbstractObject)
- 具体产品(ConcreteObject)
模板方法模式应用分析?
- 优势:提高代码的复用性。
- 劣势:对于静态方法而言不能实现多态特性。
观察者模式(Observer)
如何理解观察者模式?
- 定义了对象之间的一种一对多的依赖关系
- 对象状态发生变化,其所有依赖对象可以得到通知。
观察者模式场景分析? - Spring(ApplicationListener)
观察者模式角色构成分析?
- 目标对象角色(Subject)
- 具体目标对象角色(ConcreteSubject)
- 抽象观察者角色(Observer)
- 具体观察者角色(ConcreteObserver)
观察者模式应用优势、劣势分析?
- 优势:降低了目标对象与观察者对象之间的耦合。
- 劣势:目标对象观察者比较多的话,性能上会有影响。
迭代器模式(Iterator)
…
状态模式(State)
…
命令模式(Command)
…
解释器模式(Pattern)
…
访问者模式(Interpreter)
…
职责链模式(Chain of Responsibility)
…
中介者模式(Mediator)
…
备忘录模式(Memento)
…
总结(Summary)
设计模式描述的是一种套路,一种经验的总结,对于编码初学者如何保证代码的的质量呢,个人觉得这些模式就是一种规范。