在 “软件设计要素初探” 一文,尝试从软件设计的总体角度,综合讨论了软件设计的各类要素。本文讨论基础设计模式。 <br/>html
###概述###java
设计模式是实现特定需求的接近代码层面的设计套路,一般用于梳理和表达对象之间较为复杂的依赖和交互关系,将错综复杂的容易膨胀的难以理解和扩展的条件判断逻辑解开成一系列对象的清晰可理解的易扩展的交互结构。不一样的设计模式之间有一些形式上的类似点,区分在于关注点不一样。git
设计模式是软件设计的入门指南,其主要理念是: **面向接口的编程,组合与委托优先于继承。**理解设计模式的关键点:关注点及目标用途、协做对象、静态结构及动态交互。 <br/>github
###基础模式###正则表达式
经常使用的基础设计模式有:算法
####工厂模式####编程
- 工厂模式(FactoryMethod):根据不一样条件为客户端建立实现相同接口和功能的实例,而客户端使用的是统一的功能接口。有点相似策略模式,不过工厂模式建立的是具有状态和行为的实例,而策略模式则是对行为和算法建模。典型示例有 Spring Bean 工厂。 不少模式也须要联合工厂模式,好比策略模式、模板方法模式等。
<br/>设计模式
####单例模式####数组
- 单例模式(Singleton):为某类服务建立惟一的全局访问点。多线程环境下需考虑并发建立问题,可以使用枚举。典型示例有 Spring Component/Service 。
<br/>缓存
####生成器模式####
- 生成器模式(Builder):复杂对象的建立,须要多个步骤或组合多个子部件完成,而且在这些步骤或组件完成以前,不容许该实例的生成。一般会私有化构造器,在构造的每一步骤中会设置某些属性并返回其自身,便于链式调用,提供一个build方法生成知足某种实例建立契约的最终实例。好比汽车制造,就适用生成器模式。
可参阅 lombok 库的 @Builder 注解。 <br/>
####抽象工厂模式####
- 抽象工厂模式(AbstractFactory): 系统含有多个相互协做的不一样功能和特性的组件,每一个组件可定制为不一样的种类和风格。抽象工厂为每一个组件的建立提供相对应的抽象工厂的建立接口,而由具体的工厂实现对应的组件建立接口。即有:XXXComponent 对应 XXXAbstractFactory , XXXAbstractFactory 含有一个 createXXXComponent 的建立接口,这里 XXXComponent, XXXAbstractFactory 都是接口而不是实现。抽象工厂用于建立协做的多个组件实例的接口骨架。
<br/>
####原型模式####
- 原型模式(Prototype): 从现有对象实例快速生成和定制化对象实例,而不须要建立大量子类。原型模式特别适合于定制化。好比,现有一个房间对象,要建立含有炸弹的房间对象;这些房间对象的房间属性都是同样的,而这些炸弹多是不一样种类,也多是相同种类只是颜色不一样,使用普通的继承结构和初始化操做会产生大量的相同的赋值代码。此时使用原型模式很是恰当。经过一个含有普通炸弹的房间对象做为原型进行克隆,而后设置炸弹的种类和属性便可。原型模式使用有两点:须要一个原型管理器进行原型注册和查找;根据场景正确地实现浅拷贝和深拷贝。为原型静态或动态地增长属性和行为,能够轻易地为全部从该原型衍生的对象添加属性和行为。Javascript语言提供了原型机制。
<br/>
####适配器模式####
- 适配器模式(Adapter):复用现有类或对象的功能,实现客户端须要的接口。有类适配器和对象适配器两种。类适配器继承现有类,能够从新定义部分行为;对象适配器使用现有类的对象实例并委托实现给该对象,可灵活使用多个现有对象。一般使用对象适配器。
<br/>
####组合模式####
- 组合模式(Composite): 具备层次性结构的单个对象与组合对象具备一致的接口,客户端可以使用统一的接口操做局部和总体。树形组件是典型示例。
可参阅: “设计模式之组合模式:实现复合搜索条件构建” <br/>
####外观模式####
- 外观模式(Facade):为复杂子系统提供简单易用的接口,屏蔽实现的复杂性。库的API,Java的正则对象(Compiler,Matcher)是典型的外观模式应用。
<br/>
####装饰器模式####
- 装饰器模式(Decorator):具备相同接口的对象能够在运行时动态组合成具备复合行为的对象。能够在运行时为现有对象动态添加任意复杂的额外行为。典型示例有 JavaIO框架。函数式编程是实现装饰器模式的强大机制。
可参阅:“Java函数接口实现函数组合及装饰器模式” ,“使用IntelljIDEA生成接口的类继承图及装饰器模式” <br/>
####代理模式####
- 代理模式(Proxy): 为对象或服务提供间接访问机制。提供间接访问的缘由可能有:隐藏源对象或源服务的部署细节(远程代理);源对象建立开销很大,只有须要的时候才建立(虚代理);访问源对象须要某种权限或同步互斥(保护代理);须要为访问源对象和源服务增长额外的行为(智能代理)。代理对象与源对象一般有一致的接口,并持有源对象的引用。
<br/>
####桥接模式####
- 桥接模式(Bridge):抽象部分与实现部分各具备独立的继承层次结构分开变化发展,使用桥接器将抽象继承层次与实现继承层次链接起来,实现并不直接继承抽象类,而是抽象类持有实现类的引用。一般适用于这样的场景:建立一个标准协议的接口框架,而接口框架的实现能够有多种选择,客户端能够根据须要选择不一样的实现。桥接器一般与抽象工厂模式、单例模式组合使用。典型应用有JDBC的接口与实现、日志API接口与实现。
<br/>
####享元模式####
- 享元模式(Flyweight):大量不可变小对象的共享与管理。好比基础类型里的经常使用的26个字符对象、256个小整数对象、化学元素及原子等。可以使用缓存技术实现。为了尽量节省内存开销,须要识别享元对象中的外部状态并从中移除,使得享元对象的共享达到最大化。享元模式可与抽象工厂模式、组合模式联合使用。应用示例有使用面向对象技术建立的文档编辑器。
<br/>
####模板方法模式####
- 模板方法模式(TemplateMethod):预先定义处理流程,对于流程中某些环节的具体处理留给具体业务去完成。模板方法模式应指明哪些是钩子操做(可选重定义的,有默认实现),哪些是抽象操做(必须重定义的,没有默认实现)。对于抽象操做,可使用统一命名前缀来识别,好比mustDoXXX. 典型示例有 Java容器框架。
可参阅:“设计模式之模板方法模式:实现可扩展性设计(Java示例)” <br/>
####策略模式####
- 策略模式(Strategy):为特定任务提供多种实现算法,并在不一样场景下可灵活切换而对客户端透明。好比批量拉取数据的顺序策略(简单而略慢)以及并发策略(快速而略复杂)。使用策略模式时,客户端可持有策略实现对象的接口或者策略实现对象的模板接口参数。具体应用例子有排序,提供多种排序策略,客户端可根据须要采用所须要的排序实现(简单性、稳定性、性能、内存占用、多关键字、内存排序、文件排序)。
可参阅:“设计模式之策略模式:分离不一样实现(Java示例)” <br/>
####观察者模式####
- 观察者模式(Observer):每一个对象都有一系列观察者,当对象发生更新时推送更新给观察者,由观察者决定具体行为。一般引伸为订阅-消费模式。GUI应用是观察者模式的典型应用之一。
可参阅: “设计模式之观察者模式:实现配置更新实时推送” <br/>
####职责链模式####
- 职责链模式(ResponsibiltyChain):将可以处理某种请求的多个对象串联成一条处理链,请求沿着处理链传递给这些对象,对请求的发送者隐藏处理请求的实现细节(请求的发送者不须要知道谁真正处理这个请求)。 责任链上的请求处理对象能够在运行时动态增减。责任链的实现中,链的构造和请求的传递既可使用全局控制器来配置、生成和控制(集中式策略),也能够经过链上的对象来负责引用和传递(分散式策略)。须要构造两种接口:请求接口和请求处理对象的接口,而请求处理对象则须要实现请求接口。请求处理对象的顺序也值得斟酌,一般是从特殊到广泛的顺序。异常捕获和处理机制便是职责链模式的具体应用例子之一。
<br/>
####命令模式####
- 命令模式(Command):将行为封装到通用接口中,经过命令调用。相似回调接口,可使用函数式编程实现。具体应用例子有JDBCTemplate。
可参阅: “统计方法运行时间【Java实现】” <br/>
####迭代器模式####
- 迭代器模式(Iterator):为复杂的组合对象结构返回迭代器,安全访问其中的元素,隐藏复杂的结构细节。典型示例有Java容器的迭代器,JDBC的ResultSet。
<br/>
####状态模式####
- 状态模式(State): 一个对象具备多种状态,其某种复杂行为取决于状态及状态变迁(代码实现一般是一个大的Switch-If语句)。此时,能够单独将状态及行为抽离出来建模,并将对象的行为委托状态对象完成。若状态行为比较简单,可使用具备行为的枚举或表来实现;若状态行为比较复杂,则须要使用状态抽象类及具体状态子类来实现。状态对象可持有对象的引用,便于访问所须要的信息。状态子类没有实例属性,能够实现为单例类。常见的应用有:TCP链接状态管理、虚拟机状态管理、订单状态管理。
<br/>
####中介者模式####
- 中介者模式(Mediator):有多个基础服务方,多个业务方;每一个业务方都有本身须要定制化的东西。若是全部业务方直接与各个基础服务方打交道,会致使“服务方-业务方”的依赖关系激增(乘法关系),交互也变得复杂。引入中介者对象做为服务方和业务方的调度调控,每一个基础服务方和业务方只须要与中介者交互,而不须要知道具体的服务方和业务方。中介者对象将交互行为集中化,简化了依赖关系数量(加法关系)。 中介者对象在应用组织架构中俗称“中台”。
<br/>
####解释器模式####
- 解释器模式(Interpret):若是特定问题可使用一种简单的语言来描述,那么能够定义一种文法,以及对应的解释器。将问题的求解归结为根据文法构造句子,而后使用解析器来解释句子生成结果。适用于领域语言设计和实现。典型例子有用于字符串匹配的正则表达式解析以及JSON解析。
可参阅: “Java实现图案打印: 记法与解释器” <br/>
####访问模式####
- 访问模式(Visitor):一个复杂的复合对象含有多个子对象 A,B,C, 对于每一个子对象都须要定义操做 op1, op2, op3, ... , opN ,而每一个子对象的操做 opi 均可能是不同的。 所有操做的定义放在这个复合对象里,将使得这个复合对象异常的庞大臃肿。使用访问器模式,能够将这些操做抽离出来。每种操做都是一个访问器ConcreteVisitor,能够定义访问接口visitA,visitB,visitC ; 每一个子对象以及该复合对象都有一个 accept(Visit) 的方法。复合对象的 accept 实现将委托给遍历子对象的 accept 。 Visitor 主要用于为复合对象定义可扩展的新操做。当定义一个新操做时,只须要增长一个新的ConcreteVisitor,而不须要改动现有的其余类。若是子对象变化频繁,那么每一个 Visitor 都要增长一个 visitorX 的方法,Visitor模式就不适用了。
<br/>
####备忘录模式####
- 备忘录模式(Memento):历史状态存储、撤销与回退。
<br/>
###模式组合### **组合是力量之源。**每一个设计模式都有某个关注点,而这些关注点是相互协做的;具备协做关系的模式也是能够组合的。能够阅读《面向模式的软件架构》系列学习基础模式如何组合而获得更大的实用架构模式。这里引用《设计模式:可复用面向对象软件的基础》的图: <br/>
###模式示例### 可参考我的工程 ALLIN 下的 src/main/java/zzz/study/patterns 包下的文件。 <br/>