本文将简单的介绍一下我读《设计模式》(GOF95)这本书的经验和教训。
我想首先应该讲的是,这本书应该怎么读。
几乎没什么程序设计经验的新手,重点读第一章,第二章,明白一些大概的原则;
有一定的程序设计经验的人,读自己熟悉的模式,以及一些简单的、易于理解的模式,注意区别自己以前在遇到类似问题的时候是怎么解决的,GOF是怎么解决的,为什么;不需要太过于区分一些接近的模式,顺其自然就好。
对于如果你能熟练的编码,并开始拥有自己的设计思路的人,重点在学习用GOF的方式描述自己的经验,寻找自身思路和GOF的思路的差异性,熟悉一些自己没太用过的模式。
如果是已经阅读过设计模式,并且已经有了一些运用经验的人,详细读第一章,第二章,以及每一大类的模式的总结和每个模式的最后一节,注意区分模式之间的差异性以便于在系统中准确的选择。
接下来我希望能和大家讨论一下我对于设计模式的核心动机的理解,欢迎大家回帖的时候各抒己见,我会将大家的意见整理出来,并放在帖子中~
首先讨论一下构造型模式。
Factory Method
描述:
是最基本的构造型模式。它将构造从单纯的构造函数中分离出来。
动机:
用于封装复杂的或者是易于变化的构造操作。
适用性/作用:
适用于创建那些构造时需要初始化的对象,或者需要按一定次序构造对象的时候。该模式结构很简单,额外的代码量也很少,因此适合在开发的开始阶段就可以使用,它通常不会有那些“过度设计”的麻烦。它的另外一个实际作用,是可以统一程序的对象构造风格,增强可读性。
Abstract Factory
适用性/作用:
维护一个对象系列的一致性。当存在多个并行继承体系,并且每一组继承都较为独立,且容易错误的混用时候,建议使用该模式来构造对象系列。
Builder
适用性/作用:
当对象构造步骤复杂,并且每个步骤都使用同样的接口,但是它们具备不同实现的时候,可以选择该模式。常用于创建 构造逻辑接近、但其构造实现差异很大 的一系列对象,如构造不同格式的文本文档(GOF的示例),它们的构造逻辑接近,但是实现却是与平台相关的。
Prototype
适用性/作用:
这个模式的本意是从一个对象构造另外一个对象。在一个应用系统中,由于我们通常也能很方面的使用其它的构造方法;或者我们只需要一个按照默认初始化方式构造的对象,这样并不适合使用原型。当我们希望从不是由客户代码控制的对象中复制出一个相同的但是被客户代码管理的对象(管理权移交);或者是对象需要深拷贝语义;或者是两个子系统协作时,一个系统无法方便的访问到另外一个系统的构造函数,但是确能很方面的获得它的实例时(往往是由参数传递进来的),便需要使用这样一个模式存在。
Singleton
适用性/作用:
提供一个全局唯一的描述。还可以用来取代一些难以避免的全局变量。
有关于构造型的一些个人看法:
在C++中,由于构造函数不能多态调用虚成员函数,因此很多时候Factory Method成为了维持构造-初始化的一致性的逼不得已的选择;但是在C#一类的语言中,由于构造函数本身是虚函数,因此一些Factory Method的作用可以通过将Template Method运用到构造函数中来避免一部分Factory Method的使用;Factory Method更加强调于封装可能的构造方法变化,以及统一设计风格,而不是隐藏不必要的构造步骤。
然后是结构型模式:
Adapter
描述:
转换接口的格式(也可以说转换接口的signature)。
适用性/作用:
通常是为了统一程序风格。例如在开发系统时,发现某一个系统所使用的程序库接口不符合系统约定,便需要使用Adapter模式适配接口,使风格统一。该模式也可用于使两个系统接合到一起工作。
Bridge
描述:
分离接口与实现。
适用性/作用:
Bridge的Interface与其Implementation通常在程序的架构中是垂直关系,即上层调用下层。在基础设置,即Impl发生变化的时候,可以避免使用Interface的客户代码发生变化。将实现部分的变化消灭在接口上。
在一些使用beta版的lib开发软件,或者是开发所依赖的库有较大的可能性在软件的生命期内发生改变时,通常回使用该模式。
Composite
适用性/作用:
描述嵌套的结构,类似于程序设计里的递归,当每一个对象既是一个有独立功能的对象,也是一个容器时,通常会选择该模式,典型的例子就是XML Document。每一个节点都可能包含了叶节点。
需要注意的是,这些被包容和对象,和容器都具有及其类似的逻辑;如果从接口的层面上,可以认为这些对象是自包含的。