直接引用他的话,“例如,在OO世界中,你会听到很多关于‘模式’的内容。我想知道这些模式是否有时不是(c)情况下人类编译器正在工作的证据。当我在我的程序中看到模式时,我认为这是一个麻烦的迹象。程序的形状应该只反映它需要解决的问题。代码中的任何其他规律性都是一个迹象,至少对我来说,表明我使用的抽象不够强大--通常是我手动生成某个宏的扩展所需写入的。”
我只是想知道每个人是否认为设计模式被过度使用,并且是代码抽象不足的症状。
我认为问题并非在于设计模式本身,而是开发人员可能会学习这些模式,然后过度应用它们或以极不合适的方式应用它们。
使用设计模式是有经验的程序员自然而然地学习的。您已经解决了许多次X问题,您知道哪种方法有效,您使用该方法,因为您的技能和经验告诉您它是合适的。 这就是一种模式,它是可以的。
但同样可能发生一种情况,即技能较低的程序员找到一种方法来解决问题,并试图将他们遇到的每个问题都塞到那个模子里,因为他们不知道其他方法。 这也是一种模式,它是有害的。
模式实际上只是描述事物如何工作的一种方式。它是一种分类的方式。是否有一些程序过度使用它们?当然有。拥有模式的最大优势是,通过将某些东西分类为这个或那个,每个人都在同一页上(假设他们具有了解正在讨论的内容的知识水平)。当您拥有一套包含10,000行代码的系统时,需要能够快速确定某些内容的工作方式。
这是否意味着您应该始终使用模式?不是。这将导致强制将事物归类到一起而出现问题,但您也不应该回避使用它们。
我对设计模式的问题在于这个概念似乎存在一个核心谎言:如果你能将专家编写的代码分类,那么任何人只要识别并机械地应用这些分类就可以编写专业级代码。对于经验丰富的软件设计师相对较为罕见的经理来说,这听起来很棒。
问题在于这不是真的。仅仅使用“设计模式”,你无法编写专业水准的代码,就像仅仅使用裁剪图案就无法设计出专业级时装一样。
一个程序的形状应该只反映它需要解决的问题。
如果需求发生变化,而你的模块没有使用外观模式或者中介者模式进行抽象,则更换模块将变得非常困难,会发生什么情况呢?
设计模式是缺乏足够抽象的标志。
如果你已经正确地进行了所有抽象处理,那么你肯定会在某个地方使用到设计模式。
如果有一个非常“沉重”的对象不必被加载,代理模式将使用户免于永远等待。
我可以继续说下去,但我想我已经说得足够多了。设计模式是很好的工具,当使用正确时,但当它们被错误地使用时,问题就会出现,这就是为什么被误用的设计模式称为反模式的缘故吧。
我认为保罗·格雷厄姆(Paul Graham)的这句话很重要:
[...]我正在使用的抽象不够强大——通常情况下,我是手动生成一些需要编写的宏的扩展[...]
这表明,如果您可以在您的语言中构建这些抽象(而您几乎可以使用Lisp做任何事情,这可能是他上面所说的),则您无需使用模式对其进行建模。
但并非每个人都使用Lisp,因此您只能在能够构建抽象的地方构建它们,并在无法构建抽象的地方使用模式。例如,在没有高阶函数的语言中,通常使用策略模式来对其进行建模。
这似乎是一个观察问题的方式:模式可以被视为问题的症状(例如,缺少高阶函数),也可以被视为解决问题的方法(例如,通过策略模式实现类似高阶函数的功能)。