Design Pattern

小记设计模式

在软件构造的过程中,尽可能地重用代码,保持源代码地简洁是开发人员应有的追求之一。为达成这个目标,开发人员在框架上、在编码上都下足了功夫。而设计模式,即Design Patterns,则是开发人员将常用的设计方案与设计思想提炼后的产物。通过学习设计模式,我们能够快速领略先人的开发经验,助力与自己的软件开发。此处我就以尽可能简洁的方式,快速概述22种设计模式。

Creational patterns

Creational patterns,即创建型设计模式,目的在于分离创建与使用。

Static Factory

静态工厂模式,建立工厂类,使用静态方法生成对象,可以隐藏对象的实际生成。对于生成种不同类的情况,需要传入参数,在内部进行逻辑判断。追加新类时不符合开闭原则。

Factory

工厂模式,同样建立工厂类,仅作为接口,而由其具体子类来实现建造逻辑,实现不同类的生成。追加新类仅需要增加对应子类,符合开闭原则。

Abstract Factory

明晰产品等级结构(满足统一接口的不同类)与产品族(一系列不同接口),抽象工厂不仅仅生成一个类对象,而是生成在每个产品族中同产品等级结构的一些列产品。抽象工厂是工厂模式最为普适的形式,其对产品等级结构满足开闭,对产品族则不满足。

Builder

有时所需的对象中可能还包含许多其他对象,我们不希望在业务逻辑中手动生成一系列对象,再将其组装起来,此时可以将对应业务逻辑打包入一个类中,就称之为生成器

Singleton

对于配置类、连接池等在程序运行时不需要变动或希望全局唯一的类,我们可以通过私有化其构造方法,暴露单例构造方法,静态化实例字段,并在第一次调用构造方法时实例化静态实例字段,之后的调用都指向静态实例字段即可。单例模式实现了全局唯一,但是却将生成代码与业务逻辑混合,每次修改业务逻辑都需要修改类,不满足开闭。

Prototype

编码过程中时长需要复制对象,但这意味着需要将类内部的所有字段结构暴露出来,使得封装泄露,原型方法的思路在于将复制的过程封装在被复制对象的类内部,尤其自己进行复制过程。

Structural patterns

Structural patterns,结构型设计模式,其主要目的为更好地处理对象与对象直接的接口,使多个类之间可以实现更低的耦合。

Adapter

Adaptor,即适配器模式,顾名思义,适配器模式像一个电源适配器一样,作为中间类,将原本不适配的两个电器与电源/类联系到一起。

比如A类中的某个方法要调用B类中的方法来获取数据,然而B类中获取数据的方法与A类所调用的方法不同名。于是,设计类C,持有B类的引用,同时符合A类的调用接口,并在内部通过调用B类来实现A类接口,其间可以进行数据类型的转换等,实现适配。这称为对象适配器,在支多重继承的语言中,也可以由C同时继承A、B来实现,称为类适配器。这么一来,无需修改A、B的代码,而通过引入中间类C解决了兼容性问题。符合了开发封闭原则。

Decorator

Decorator,即装饰器模式。
在开发过程中,常常遇到一个类需要多种附加功能的场合,然而多种附加功能不一定同时用到。常规来想可以组合接口,分别实现,但是这将带来组合爆炸。

装饰器模式给出了相应的解决方案:

  1. 给出抽象接口类(向外暴露)
  2. 给出实现类,可一可多,实现非附加功能;给出抽象装饰器类:
    1. 保有抽象类的引用
    2. 通过接受一个抽象类对象初始化
  3. 给出具体装饰器类;通过调用其内附加代码与类引用实现附加功能
  4. 使用时,新建实现类,通过传递引用,新建装饰器类的对象,获取其引用(此过程可嵌套)。
  5. 使用附加功能。

这样一来,就通过一种巧妙的机制,避免了继承带来的复杂结构。

装饰器模式可以递归组合,以此通过追加装饰类带来不同的附加功能,符合开闭原则,且其接口与原对象一致,对外界透明。

Bridge

桥接模式是解决类别沿着不同维度异化而导致组合爆炸的一种方案,其将一个维度作为主体,另一个维度作为客体,主题持有客体的引用,以此实现不同维度的组合。

相比装饰模式,桥接模式侧重于不同维度,而非同维度的不同功能的不同特性。

Compose

组合模式的目的在于解决较为复杂的对象嵌套问题。通过每一层对象将调用划分给其持有对象进行处理或自我处理,组合模式能够避免过于深层次的直接调用。这样替换子对象时,无需修改最根处的调用,符合开闭。

Facade

外观模式将一个庞大的复杂系统进行封装,由外观类来梳理复杂的业务流程,将其组合成特定的接口再向外暴露,可以实现封装,易于对业务流程进行替换,且保持接口不变。

外观模式与创造器模式类似,都将负责过程隐藏,不过创造器模式更注重于对象的组装,而外观模式的行为更加广泛。

Flyweight

享元模式将大量对象的持有的不变或共通元素抽离出来,作为享元类,让对象以引用的形式持有,节省内存,且便于集中修改,利于增加新享元类。静态字段也许也能看作享元的一种?

Proxy

代理模式一边实现接口,另一边持有对象,在访问过程中可以进行一些额外操作,如缓存。

代理模式可以说是弱化的装饰器模式,其不支持嵌套组合。

Behavioral patterns

Behavioral patterns,行为型设计模式,将具体动作与框架分离,实现代码的可复用性。

Chain of Responsibility

责任链模式,将一些列流程层层嵌套,如用户请求处理:验证码验证->密码验证->IP验证……,将传递链条暴露自然可行,但是将链条嵌套起来,是一种更优雅的解决方案。

Memento

备忘录模式,实现对被备忘对象内部状态的记录,但是交由另一个负责人类进行持有,仅对被备忘对象开放访问权限,实现状态的存储,适用于撤销栈等领域。

Observer

观察者模式,使用订阅发布机制,被观察者记录所有观察者,在被观察者发生变化时,调用观察者登记的回调函数,实现观察机制。

Strategy

Strategy,即策略模式。该模式将功能与算法分离,用户通过传入实现了指定接口的算法对象,来运行功能类。

Template Method

Template Method即模板模式,其将某一个功能拆分为多个环节,将部分环节留白,待用户类继承抽象接口以实现。

注意策略模式与模板模式的差异,策略模式由传入对象进行委托实现,而模板模式则由继承机制实现。

Iterator

Iterator,迭代器模式,即提供统一的遍历手段,封装存储方式与遍历动作,要实现不同遍历可添加新的类型,符合开闭原则。

Visitor

Visitor,访问者模式,将功能与操作隔离,将对多种对象的操作放入一个类中。编码中,并非访问器接收对象,而是对象接收访问器,反向调用其中对应回调方法。

Mediator

中介模式,将复杂系统中近乎全连接的访问网络改造成以中介为中心的星形网络,所有对象将请求转发给中介进行,在对象看来,一切事务都由中介进行处理,降低了所有模块的扇出与扇入,简洁化了系统。

Command

命令模式,类似中介模式,但是不产生一个全知全能的中介类,而是为每一个可能的访问建立一个子类,将对象间访问逻辑封装到类中,利于修改实现,符合开闭。

例子:UI中的按钮行为就可以绑定到一个对象上。

参考资料

设计模式

知识水平与时间精力优先,暂且就先写到这里,待学成再来补坑