》。
这本GOF著作的书籍可以说是设计模式的来源和最权威的著作。
在你更深入的学习设计模式相关的知识前,我们还需要像《Head First 设计模式》中最后一个章节那样对前边学习的部分进行一个总结。
什么是设计模式
这是我们学习设计模式绕不开的一个问题。
有意思的是《Head First 设计模式》的作者在书中提到,设计模式的源头是一位美国的建筑专业学者,具体来说源自其两本著作:
《》
《》
从这里就可以看出设计模式并非是局限于编程领域的一种技巧或者说知识,而是存在于现实中的其它多种领域,更准确的说这是一种人类在某种情景下处理特定问题而总结出来的一种行之有效的知识。
所以设计模式具有两个方面的特点:
-
通用性:即如果你总结出的某个“设计模式”仅是一次性的,并不能让别人在处理类似的问题时候重复使用,则该模式并不能称为设计模式,因为不具有通用性。
-
约束:并不存在一个能解决所有问题的万能模式,所有的设计模式都是在某些条件下为了解决某个问题而提供的一种解决方案,并且面对类似但并不完全相同的问题和条件时候可能需要进行一些调整,所以不能单纯记住模式本身并尝试生拉硬套,而是要仔细思考现实中的条件和目标,以及模式的适用场景和使用该模式后的影响。
应该在何时使用
就像中说的那样,编程的最终目的是找到一条最佳解决方案,而设计模式更像是能帮你更容易找到那条路径的指南针和地图,它们是顺手的工具,但是我们的目的并不是一定要使用指南针或者地图,我们的目的是找到我们要找的那条路径。
所以新手最容易陷入的陷阱就是学到一门新的技艺后盲目且迫不及待地运用,这无疑是一种得不偿失的举措,还记得吗,我们在介绍各种模式时候虽然会说明引入各种模式的好处,但同时也会说明其缺陷,比如最常见的就是不得不创建更多的类来进行必要的组织。如果其带来的优点超过这些缺陷,那当然因该引入设计模式,但是如果答案是NO,则会带来不必要的麻烦。
比如说对于一个明明可以简单使用两三行判断语句创建,并且其它地方不会有任何使用的代码,我们额外创建一个工厂类来进行创建工作,这明显是得不偿失的,这就好比我们需要找的路径明明就在几米外,你已经看到它了,但你还是要掏出你的指南针和地图,当然这在现实中可能有用,避免你认错路,但是在编程中只会徒增烦恼罢了。
对于应该在何时使用设计模式,我的建议是要么是在开始设计时,对一些显而易见的模块使用设计模式,比如中我创建的缓存模块,虽然一开始我仅仅编写一个简单的文件缓存就可以满足需要,但是显然我们只需要使用策略模式和简单工厂就可以创建一个可以扩展的缓存机制,只要我们需要,就可以在后续很容易地扩展出其它机制的缓存,比如数据库或者memcache缓存,所以在这里一开始就使用设计模式应当是恰当的。
但大多数时候是否使用设计模式其实是模糊的,如果积极地使用模式很容易出现前面说地那种盲目使用地例子,创建了一堆额外地类却压根不会扩展相应地功能,那无疑是在做无用功。
所以如果你不确定是否应该使用设计模式,就先按简洁的方式实现,然后在必须的重构中使用设计模式进行优化。
在我的工作经验中上面的做法是频率最高的,当然,在重构中和同伴保持高效沟通非常重要。
设计模式的类型
需要说明的是对设计模式进行分类并非必须,而且也没有什么权威性规定。对其分类的目的是帮助你更容易记住和掌握这些设计模式。
一种最通用的分类方式是将模式划分为:
-
创建型
-
单例模式(Singleton)
-
抽象工厂(Abstract Factory)
-
工厂方法(Factory Method)
-
-
行为型
-
模板方法(Template Method)
-
迭代模式(Iterator)
-
命令模式(Command)
-
观察者模式(Observer)
-
状态模式(State)
-
策略模式(Strategy)
-
-
结构型
-
装饰器模式(Decorator)
-
代理模式(Proxy)
-
组合模式(Composite)
-
外观模式(Facade)
-
适配器模式(Adapter)
-
上面的分类为GOF对设计模式给出的分类,当然有一些划分存在异议,比如说我就觉得观察者模式也可以是结构型,因为观察者模式的订阅和通知功能依赖于被观察对象的一个类List
容器。
所以这并非权威和绝对的分类,但是总的来说还是复合一般性认知的分类,可以帮助你记忆设计模式。
总结出你自己的模式
关于这点,书中已经很“善意”地提醒读者,基本上该有的设计模式已经被人都发现了(这本书是97年左右出版的),现在嘛...
但是书中展示的《》中对模式的归纳总结我认为相当有用,即从模式的使用情景,模式的类图构成,模式的有缺点等几个方面阐述某个模式,可以说这本书相当于一本模式辞典或者参考手册,可能这本书并不适合作为设计模式的入门书籍,但是作为工具书或者参考书无疑相当不错。你完全可以参照它编写某个领域内的某些专用模式,如果还没有人总结类似的模式的话。
反模式
所谓的反模式就是使用不恰当的设计模式造成的反面案例,如果有时间和精力的话,总结出类似的反模式并在开发团队内分享以提升对设计模式的理解,避免类似的问题出现是个不错的想法。
但我觉得更多的时候是看到类似糟糕的代码时候视若无睹,毕竟重构是个费力气的活计,只要代码还能运行,大多数人都不会有动它的勇气。
设计模式Level
《Head Frist 设计模式》的最后提到了学习设计模式的开发人员的几个级别:
-
初级开发者:对设计模式掌握不多,盲目使用设计模式。
-
中级开发者:按部就班的在该使用的地方进行使用。
-
大师:编写简洁的代码,在该使用的地方自然而然地使用。
我觉得这段论述很有意思,很像是金庸武侠中对独孤求败剑术地描述:
-
早年使用削铁如泥的宝剑和快剑剑招。
-
中年使用玄铁重剑,以力破巧。
-
老年手中无剑心中有剑,草木飞花皆可为剑。
就在这里结束这个系列吧,原书附录中还介绍了一些额外模式,或许我会总结后写一篇番外,谢谢阅读。
最后附上我的豆瓣书单
文章评论