什么时候应该使用设计模式?

72
任何人都可以阅读GoF书籍来学习什么是设计模式以及如何使用它们,但是如何找出何时使用设计模式解决问题的过程是什么?模式的知识是否驱动设计,或者有没有一种方法来确定如何使用模式改变设计?
换句话说,是否存在用于模式的模式?
14个回答

51

设计模式旨在提供一个结构,以便解决问题。在解决实际问题时,您必须考虑许多微小的问题解决方案变化,以查看是否有任何解决方案符合设计模式。特别是,您可能需要将问题或其解决方案概括,以使设计模式适用。

答案是:这是一门艺术。了解设计模式当然是重要的一步。习惯于此类事情的方法之一是研究设计模式的应用,而不仅仅是模式本身。看到同一模式的许多不同应用可以帮助您随着时间的推移更好地将任务映射到模式上。


12
如何在没有文档说明的情况下学习不同应用程序?在现实世界中,我们会应用并继续前进。如何找到可以在应用之前学习成功应用程序的来源?这个来源在哪里? - A_Var

48

我强烈推荐阅读O'Reilly的Head First Design Patterns。这本书可以解释这些模式如何在实际应用中使用。

Head First Design Patterns

我还想补充一点,不要试图在设计中过多考虑模式。相反,寻找可能需要模式来解决的“代码异味”。


1
是的,我有那本书。它真的很好。我不喜欢里面的例子(鸭子、披萨之类的),但它确实为设计模式打下了坚实的基础。 - Robert S.
5
但是这本书中的例子(例如披萨、巧克力工厂等)确实帮助你理解每个模式的概念和思想。 - Andreas Grech
感觉设计模式已经注入到了大脑中。这真是一本非常棒的书。 - Jnana

16

模式背后的核心概念是大多数人没有掌握的。不要将它们视为数据结构或算法。

相反,将您的代码视为人们彼此发送消息,就像传递笔记或发送信件一样。每个对象都是一个“人”。

您组织“人”及其彼此发送消息的方式就是模式。


13

把问题反过来:你应该做的是"什么样式适合我的问题"。考虑一个非常简单的样式,查找数组中的元素。在C语言中,它大致如下:

把问题转化一下:你需要做的是“哪种模式适用于我的问题”。对于一个非常简单的模式,查找数组中的元素。在C语言中,它看起来像这样:

TYPE_t ary[SIZE] = // ... gets initialized somehow
size_t ix ;        // Your index variable

for(ix=0; ix < SIZE; ix++){
    if (ary[ix] == item) {
       return ix ;
    }
}

你不是在看代码然后想:“我可以在哪里使用它”,而是在看问题然后说:“我知道如何在数组中找到一个元素吗?”

对于更广泛的模式,它确实以相同的方式工作。你需要有许多不经常更改的数据结构的副本 --- 这使你想到了“享元”(Flyweight)模式。如果你需要一些可以存在于网络边界两侧的东西,那么你要考虑“代理”(Proxy)模式。

当你学习设计模式,特别是 GoF 的时候,问问自己:“什么情况需要使用这种模式?我以前见过这种模式吗?我以前的工作中能用到这个模式吗?在我的生活中哪里可以找到这个模式的例子?”


8

设计模式?你早已沉浸其中!

设计模式并非特别之处,它们只是设计的一种模式。所有开发都使用设计模式。在面向对象编程中存在一定数量的被认为是普遍理想的设计模式,并成为标准设计模式。但同时也存在许多不理想或无关紧要的设计模式(例如设计反面模式),以及未被发现或未被记录的模式。

编程时无法避免使用模式。但是你可以更加了解自己正在使用的模式,以及何时某些模式有用,何时没有用。学习来自GoF书籍的标准设计模式以及了解代码异味和重构将会有所帮助。在何时何地使用哪种模式并没有单一正确答案,你需要通过实践使用和实现它们来积累经验,才能知道何时何地使用哪个模式。


6

经验。学习它们的模式和实际应用示例。每次您做出设计决策时,请考虑您所知道的模式是否适用于它。随着时间的推移,您会变得更加熟练,并发现将模式应用于更广泛问题范围的新方法。


1
学习如何识别设计模式的最佳场所之一是编程道场,参与者通过玩具问题进行“刻意练习”(请参阅http://en.wikipedia.org/wiki/Kata_(programming))。当地用户组有时会主办道场。但是,即使找不到可加入的道场,独自完成卡塔也有很多价值。 - Craig Jones

6

我发现另一本很棒的书:

重构到模式

通过展示何时、何地以及如何将现有代码改为模式,它让我更好地理解了这些概念,并且能够识别它们可以使用的地方。


6

你是如何学习使用if语句的呢?

我认为if语句就像一个更大的结构体,你需要了解其内部细节才能有效地使用它。if语句可以解决需要分支处理的问题,桥接模式也可以解决一类问题。我并不认为它们有什么不同。


4

如果你了解模式,它们就会成为你工具箱中的工具。当你面对一个任务时,你可以从你的工具中选择。此时,你应该已经很清楚哪个工具最适合解决特定的问题。这就是公式不再起作用,你需要进行实际工程工作的地方。


4

Rian van der Merwe在2012年6月为Smashing Magazine撰写了一篇优秀的文章,内容与设计模式相关。以下是一些重点。

设计模式有两个用处:

  1. 模式可以节省时间,因为我们不必解决已经解决过的问题。
  2. 模式使网络更易于使用,因为随着设计师的采用增加,用户习惯了事物的工作方式,这反过来又减少了他们遇到常见设计元素时的认知负荷。

van der Merwe建议我们在以下情况下考虑打破模式:

  1. 新方法在实践中提高了可用性,或者
  2. 旧方法变得过时。

那是一种不同类型的设计模式,但你的答案仍然很棒。 :) - Robert S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接