设计模式是为了解决某种问题而进行的代码设计,经过许多工程师反复的使用,最后形成了一种模式,它不针对于特定的语言,隶属于公共技术分类。因为作者是Java程序员,所以在编码实现中都使用Java语言。
设计模式通常包含以下几个部分。
首先是问题,它是为了解决什么问题而存在的。
其次为实际应用场景,如何解决特定场景下的问题,例如在单例模式时,存在多线程,多JVM等等的场景。
最后是实现方案,如何通过编程语言来编码实现。本文也通过这种结构来介绍设计模式,为了方便理解,在最后会研究一个优秀的示例,示例的取材来源于常用的框架,Java代码等等。
设计模式按照其功能,特点可以分为三类
创建型模式
创建型模式主要的功能就是创建对象。它可以分为两种类型,一种为创建对象的实例(以下简称创建分类),另外一种为复用现有对象的实例(以下简称复用分类)。它总共包含七种设计模式。
- 单例模式:在特定的环境中,保证对象只存在单个实例。隶属于创建分类。
- 工厂模式:为了创建对象树,工厂模式返回的都是对象树的根类。根据对象树的复杂程度,应用不同的工厂模式。当对象树下包含的种类数量较少时(通常可以枚举,例如扑克牌的花色,大小),使用简单工厂模式;当对象的种类比较多,并且拥有几种简单的分类时,并且每种类型下面又可以枚举时(例如手机,分为苹果,小米,华为,苹果下面又可以细分),可以使用工厂方法模式;当对象的数量比较巨大时,使用抽象工厂模式。隶属于创建分类。
- 构建者模式:为了创建复杂对象,在创建对象中,需要分步进行时,可以使用构建者模式。隶属于创建分类。
- 原型模式:通过已有对象的实例来创建新的实例对象,它的解决方案依赖于Cloneable接口,其他语言的实现方案可以自行研究。隶属于复用分类
- 对象池模式:为了复用已有对象的实例,而不用重新创建,它的应用非常广泛。隶属于复用分类。
结构型模式
结构型模式主要的特点是,在它的解决方案中,在不修改原有代码的基础上,添加新的类来实现。按照功能将其分为三种,第一种为解耦,适配器模式。组合模式。第二种为了满足新的需求,添加新的功能,装饰器模式,添加新的功能实现方式,桥接模式。第三种为了提高性能,减少内存的使用,享元模式,减少耗时资源的使用,代理模式。它们的格式一般都比较固定。它总共有六种设计模式。
- 适配器模式:为了实现原有类型和现有类型的解耦。这里的类型可以为接口或者是类,总共分为4种场景,当原有类型为接口,现有类型为接口;当原有类型为接口,现有类型为类;当原有类型为类,现有类型为接口;当原有类型为类,现有类型为类,每一种场景对应特定的结构。它的实现方案为添加XXAdapter来实现。
- 组合模式:对于对象使用者而言,为了统一处理对象与它的集合类型。对象的集合类型自身维护添加,删除,替换对象等等功能,它的实现方案为集合类型与对象实现相同的接口,对于接口中关于集合类型的方法,对象抛出异常或提示不支持的操作。
- 桥接模式:对于特定的功能,为了提供一种实现方案,并且可以在这些实现方案中相互切换。为了满足这样的需求,需要将对象与功能的实现方式进行解耦。它的实现方案为将对象的功能委托给某个接口类,当需要新的实现方式时,通过添加新的接口实现类来实现。
- 装饰器模式:为了满足需求,需要在原有的接口提供新的功能,它与桥接模式很相似,桥接模式是在原有的功能上提供新的实现方式,装饰器模式是提供新的功能,例如排序,需要添加二分法排序,可以使用桥接模式,添加一个二分法的接口实现类来满足需求。它的特点为原来的功能需要复用原来的实现,新的功能需要添加新的子类来实现。
- 享元模式:为了减少在创建对象时的内存消耗,将对象的公共属性封装在公共类型中,而私有属性封装在私有类型中,在创建对象时,通过创建私有对象,私有对象中引用公有对象,以此来达到共享公共属性的目的。通过减少公共属性占有的内存来减少内存的开销。
- 代理模式:代理模式的作用有两种,第一种为了提供性能,减少使用较大的资源,例如在网页在初始化的过程中,通常加载一个URL链接,而当用户点击时,此时去加载比较大的网络资源,通常为图片,视频等等,此时的代理类相当于实际类型的快捷方式,它的实现方案为静态代理。第二种为了添加公共操作,例如校验权限,记录日志等等,当调用实际对象的方法时,实际调用的是代理对象的方法,代理对象方法可以由自己定义,但是都拥有原来的方法。此时代理类相当于黑客,在原有方法中添加了自己的方法,此时实际对象并不知道代理对象的存在。不论是哪种情形,它的实现方案都是通过添加代理类。
行为型模式
它的主要特点是,它更贴近于生活,它的问题往往可以转换为实际的生活场景,它的解决方案中,各个对象往往对应生活中的各种角色。所以理解行为型模式时,模拟为生活场景会非常容易理解。它包含十一种设计模式。
- 职责链模式:处理请求,流程化的响应。可以理解为生活中的各种流程,例如医院挂号,公司报销流程。
- 命令模式:处理请求,响应。将请求方与实际的响应方进行解耦,将请求方的响应委托给第三者。例如生活中的点餐。快递员配送流程。
- 解释器模式:待补充
- 迭代器模式:为了遍历不同的集合类型。集合的类型可以为数组,List,Set等等。它不依赖于具体的集合类型,而依赖链式的数据结构。
- 中介者模式:待补充。
- 备忘录模式:记录对象被修改的每个状态。这个类比于实际开发中版本控制工具,记录文件被修改的每个状态。
- 观察者模式:将对象状态的变化发送给对象的订阅者。例如生活中的报纸订阅,网购时商品价格降低时通知消费者,微博订阅等等。
- 策略模式:与桥接模式很相似,为了实现不同的算法,并且可以在算法之间来回切换。例如生活中联系某个人,可以通过邮件,网络通讯工具,电话方式来通知,当一种方式不可行时,需要有别的选择。
- 模板模式:将设计与实现进行解耦,模拟为生活中架构师设计了代码,让程序员去实现具体的功能。
- 访问者模式:为了调用相同方法,而却拥有不同的对象类型,彼此之间没有继承的父子关系。可以理解为为了method不同的object。其中method表示方法,一般抽象为visit方法,object为各种不同的类型。例如对象的Comparable,迭代者模式可以说是一种特定的实现。
- 空对象模式:当实现一个功能时,可以有不同的选择。可以建立一种选择的顺序,例如Log4j在加载配置文件时。