疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

如何学习设计模式


 

        GoF的[设计模式]是经典著作,有人看了好多遍仍然说没有看懂,许多人看懂了一些模式但不知道如何应用……这里,yqj2065抛砖引玉,讨论一下如何学习设计模式。
        注:《Design Patterns: Elements of Reusable Object-Oriented Software》(即后述《设计模式》一书),由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著(Addison-Wesley,1995)。这几位作者常被称为"四人组(Gang of Four)",简称:GoF
①学习技巧
学习设计模式时,有一些技巧能够帮助你快速理解设计模式。
a)使用较简单的面向对象的语言如Java、C#。GoF的[设计模式]实质上是面向对象的设计模式。[GoF·1.1]中提到“程序设计语言的选择非常重要,它将影响人们理解问题的出发点”。从学习设计模式的角度看,Java和C#较C++更容易一些。比如Java接口等,能够更有效展现设计模式的意图。
b)使用工具BlueJ。BlueJ最大的好处,就是提供了简单的类图。正如我在简明设计模式Java中所做的,较少去专门画类图,而是在BlueJ中截图。在学生上机编写演示程序时,常常先看他的类图,以判断他的程序是否正确,必要时再看源代码。
c)日常生活的隐喻。用一些实际生活中的例子来说明某某模式,能够让你快速掌握某模式的目的和实现代码的结构。同时,你要认识到,这种隐喻如同告诉你(2+3)2=22+2*2*3+32,你需要自己举一反三,得出(a+b)2=a2+2ab+b2。在实际工作中的模式的具体应用,则相当于应用代数公式。
d)动手实践和怀疑精神。看显浅的参考书或上网查阅资料时,要自己敲(复制也可以)代码并运行,要多修改别人的源代码提出自己的观点:为什么书中不这样设计、为什么要那样设计;如果增添一些方法、方法参数、或成员变量会如何?必须要自己亲自动手,最起码要运行。另外,要敢于向博主提问、拍砖。你甚至可以质疑GoF的某些章节的解说和意图,更何况一些博主呢。
②基础知识
这些知识让你知道,设计模式好在何处。
a)面向对象范式。也就是人们传说的思想。封装、继承和多态这些东西,在我看来比if、for等稍微高一点,也属于语法问题。面向对象编程要掌握的三大原则是柏拉图(Plato)原则、里氏(Liskov)替换原则和Parnas原则。这三个原则其实非常简单。任何原则,你觉得很难一见钟情,很难快速认同,那它就不会是好原则。
b)设计原则。许多人列举了7大原则,如单一职责原则、开闭原则、里氏代换原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则。LSP,我将它提升为面向对象范式的3大基石之一;单一职责和接口隔离,主要作为面向对象分析/OOA时职责划分所遵循的原则,此时你可以不太在意。依赖倒转原则,我把它作为垃圾扔掉,因为开闭原则或者直接地说“依赖于抽象类型原则”已经包含了依赖倒转原则的精华,而依赖倒转原则的糟粕由IoC继承。当然,回调,我很强调。所以,你要掌握的有抽象依赖原则(OCP)、单向依赖原则(含对回调的学习)和最低依赖原则(合成复用原则、迪米特法则)。
c)UML的初步了解。这是学习设计模式的工具。在早期,你甚至可以仅了解BlueJ的相关图示,也就10分钟的事情。
③境界
《五灯会元》卷十七中,有一则唐朝禅师青原惟信禅师的语录:“老僧三十年前未参禅时,见山是山,见水是水。及至后来亲见知识,有个入处,见山不是山,见水不是水。而今得个休歇处,依前见山只是山,见水只是水。”
a)仔细研究GoF的[设计模式],逐个学习其意图和结构,是一个抱着字典学习英语的方式。见山是山,见水是水,导致你可能在实际工作中生搬硬套、东施效颦。
b)建议从简单的场景出发,自己发现或设计出某种模式。你从中体会该模式是如何解决问题的,这样,该模式成为你自己的东西,你才不会出现知易行难的问题。所有的设计模式不过是基本原则和理念在特定场合的应用。你可能不知道某个设计模式的名字,但是你知道它一切的优缺点和变体以及应用场合。见山不是山,见水不是水。
c)你对基本原则和理念融会贯通,你可以惋惜:“我找到一种模式,原来在[设计模式](其实是某个特殊的书、文章提到的模式)中早就有了这种模式”。这时,模式不模式又如何呢?反模式又怎样。看见一个模式,你会说:“嗯,这是一种有用的模式”。见山只是山,见水只是水。