设计模式是增加还是降低应用程序的复杂性?

Rob*_*uld 6 language-agnostic design-patterns

我只是在看这个关于SQL的问题,并且关注了一个关于DAO到维基百科链接.它提到了一个缺点:

"与许多设计模式一样,设计模式增加了应用程序的复杂性." - 维基百科

这突然让我想知道这个想法来自哪里(因为它没有引用).我个人总是认为模式会降低应用程序的复杂性,但我可能会妄想,所以我想知道这种复杂性是否基于某种东西.

谢谢.

gro*_*ver 11

如果阅读代码的人了解设计模式及其概念,并且能够在实际使用中识别设计模式(不仅仅是书籍示例),那么他们确实会降低复杂性.

但是我发现很多初级开发人员都没有听说过设计模式,或者根本没有意识到这些模式,他们认为使用它们会增加代码的复杂性.

我能理解它:你突然有更多的类或代码来解决一开始似乎是一个简单的问题.如果您不了解设计模式的好处,那么黑客攻击解决方案总是看起来更好.

  • 我认为,如果你给出一个模式的具体例子,那么你的答案会更有说服力. (2认同)

Sea*_*ean 5

设计模式通常会导致围绕问题的额外抽象级别,如果处理不当,那么过多的抽象会导致复杂性.

但是,由于设计模式提供了交流思想的通用词汇,因此它们也降低了复杂性并提高了可维护性.

在一天结束时,它是一把双刃剑,但我无法想象我会避免使用设计模式的情况......


duf*_*ymo 5

有一种臭名昭着的疾病被称为"模式综合症的小男孩",这种疾病通常会袭击最近一次阅读GoF书籍并突然看到各处模式的人.这可能会增加复杂性和不必要的抽象.

在我看来,模式最好添加到代码中作为解决特定问题的发现或重构.


Fuh*_*tor 5

我喜欢设计模式,但是它们(除了像Singleton这样的简单模式之外)肯定会增加应用程序的复杂性。它们为设计增加了一些维度,这对于新手设计师而言是直观上不明显的(并且不是编程语言功能的一部分)。

有些人可能会感到模式降低了复杂性,因为它们带来了软件非功能性需求(如可维护性,可扩展性,可重用性等)带来的好处。但是,我不同意并将这些好处视为复杂性投资的回报。也许在某些情况下,模式会降低复杂性,但是像这样的理论讨论比光散发的热量更多。到目前为止,几乎所有答案都没有使用具体示例,只有/sf/answers/53267791/即可

具体来说,许多模式通过引入在应用模式之前设计中不存在的新结构(接口,方法等)来增加设计的偶然复杂性

让我们以访客为例。

访客是一种将操作与操作对象结构分离的方法。在使用Visitor解决方案之前,将操作硬编码到对象结构的每个Element中。开发人员面临的挑战是添加新操作涉及修改各个元素中的代码。

在应用了访问者模式之后,还有一个访问者的附加类层次结构,它封装了操作。解决方案中的控制流程肯定会更复杂,并且将更难调试(实现了Visitor并尝试通过accept / visit遵循双调度调用的程序流程的任何人都将知道这一点)。

与内聚单元相比,理解和维护来访者功能比在已访问的固定结构中将功能编码到每个元素中的方法要简单得多。这是该模式的好处。

很难定量地说出意外复杂性增加了多少,或者添加新操作有多容易。从长远来看,我肯定不同意答案,因为从长远来看,应用模式会降低复杂性。这不像您的设计“忘记” Visitor方法所添加的双重调度,只是因为您拥有更容易添加操作的代码。复杂性是您为了获得可维护性利益而付出的代价(或税金)。

模式仍然必须应用

无论人们对模式的熟悉程度如何,都必须将任何给定的模式应用于解决方案。每次应用程序都会有所不同(Martin Fowler表示模式只是半熟的解决方案)。开发人员将始终必须了解哪些类在现有设计中扮演什么角色,这受制于通常不容易的基本复杂性(应用程序问题的复杂性)。

在最好的情况下,了解应用在已经很复杂的应用程序中的设计模式可能是微不足道的,但这不是零的努力:

  • 模式并非总是以相同的方式应用。模式有多种变体-想到代理。我不确定每个人应该如何应用任何给定的模式。
  • 引入一种模式(例如,封装算法的策略)通常会导致其他模式来正确地管理事物(例如,工厂来实例化具体的策略)。
  • 引入模式通常会导致更多责任。使用Factory时,对象清除并非易事(GoF中也未记录)。有多少人知道所谓的立听侦听器问题
  • 如果对模式需求的假设发生了变化(例如,不再需要由策略模式提供多种封装算法),会发生什么?稍后删除该模式将是额外的工作。如果您不删除它,那么新开发人员在加入董事会时可能会被它的存在所欺骗。模式在充当模式角色的类之间交织在一起。删除并非易事。

埃里希·伽玛给了一个故事,在2006年ECOOP设计师在一种情况下决定删除抽象工厂模式从商业的多平台GUI组件框架(经典抽象工厂的例子!)。事实证明,复杂的GUI中的多个级别的间接调用(多态调用)在客户端代码中极大地影响了性能。客户抱怨GUI太慢,“优化”是删除了间接指令。在这种情况下,性能胜过可维护性。这种模式只会使编码人员感到满意,而不会使最终用户满意。

DAO的例子

就DAO示例而言,您要在问题中引用,如果您要编码的应用程序永远不需要在不同的数据库上运行,则DAO模式是不需要的复杂性级别。通常,如果您的代码不需要模式应该提供的好处,那么应用该模式将不必要地增加应用程序的复杂性。

旋转门的隐喻

使用建筑物作为隐喻,让我们将旋转门视为建筑物设计模式。下图来自维基百科:

旋转门

您可以“看到”这种门的额外复杂性。旋转门的好处在于节能。他们试图解决人们经常进出建筑物的问题,并且每次打开/关闭标准门都会使建筑物内部与外部之间的空气交换过多。

将旋转门安装为两居室房屋的入口可能没有任何意义,因为没有足够的流量来证明额外的复杂性。旋转门仍然可以在两卧室房屋中使用。节能方面的好处很小(实际上,由于尺寸和相对于传统门的气密性,实际上可能更糟)。与传统的门相比,门肯定会花费更多,并且会占用更多的空间。