设计模式-您使用它们吗?


44

作为一名IT专业学生,我们的一位老师最近给了我一些有关设计模式的概述。我了解它们的用途,但某些方面仍然困扰着我。

它们是大多数程序员真正使用的吗?

说到经验,我在编程时遇到了一些麻烦,但我暂时无法解决,但是Google和一些小时的研究解决了我的问题。如果在网络中某个地方找到解决问题的方法,这是一种设计模式吗?我在用吗?

而且,您(程序员)在开始开发时是否发现自己正在寻找模式(顺便问一下,我应该在哪里寻找?)?如果是这样,那肯定是我必须开始接受的习惯。

更新:我想当我问程序员是否使用它们时,我是在问是否有问题要解决时,您会认为“哦,我应该使用该模式”。


7
不是确切重复的问题,但我的答案将是相同的。程序员
.stackexchange.com / questions / 70877 /…

4
大多数被高估,过度宣传的“设计模式”仅与OOP编程有关。并且有很多充分的理由要尽可能长时间地远离OOP。
SK-logic

5
我发现自己经常使用泥浆大球,这比我想要的要多。开玩笑。
sashoalm 2012年

唯一的答案是对条件声明为“何时适当”的是
钻机

Answers:


114

当我是一个新手程序员时,我喜欢设计模式。我不只是使用设计模式。我给了他们。无论何时何地。我是无情的。啊哈!观察者模式!拿着它!使用听众!代理!抽象工厂!为什么要使用五层抽象呢?我已经与许多经验丰富的程序员进行了交谈,发现几乎每个阅读GoF书的人都经历了这个阶段。

新手程序员不使用设计模式。他们滥用设计模式。

最近,我发现,保持原则就像心目中的单一职责原则,并先写测试,帮助图案出现在更务实的方式。当我意识到这些模式时,我可以继续轻松地进行改进。我认出了它们,但是我不再尝试将它们强制放在代码上。如果出现“访问者”模式,可能是因为我重构了重复项,而不是因为我提前考虑了渲染树与增加其值的相似性。

经验丰富的程序员不使用设计模式。设计模式使用它们。


2
@schlingel-您为什么叫OP先生?
奥德

10
在这种情况下,@ Oded我保留被称为“先生”的权利,并享有享受。
鲁尼沃(Lunivore)2012年

3
是,长官。没有冒犯的意思!
奥德

1
在苏维埃俄罗斯.. :)
索兰提斯(Sorantis)2012年

5
好的答案,但是在最后一行中,您试图变得博大精深,但这是荒谬的。怎么样?“有经验的程序员不选择设计模式,而是让它们发生。”
加勒特·霍尔

43

不管人们是否认识到它们,大多数程序员都会使用模式。

但是,在日常工作中,人们并没有想到要在模式中进行编程-人们意识到代码中已经出现了一种模式,然后对其进行了命名。

某些语言内置了一些常见模式-例如,带有关键字的C#内置了迭代器模式foreach

有时您已经知道您将使用该模式来解决当前的问题(比如说存储库模式 -您已经知道要将数据表示为内存中的集合)。


13
差不多就是我要说的,模式是帮助程序员传达设计和实现思想的一种语言,而不是一组可以拼凑在一起以实现系统的编程乐高积木
Mark Booth 2012年

27
@DeadMG为什么?
克里斯·哈珀

11
@DeadMG:我一定已经被这个愚蠢的想法所蒙蔽了-我不明白你为什么认为它是愚蠢的;-)
Treb

2
@ root45-朋友,您的foreach构造使编程变得太容易了。如果像迭代集合这样的复杂任务很容易,一个人会感觉比别人更好?我为所有CRUD应用程序编写了一个仍在汇编中的代码。显然,@ DeadMG的情绪是纯粹的务实天才之一。
ChaosPandion 2012年

8
@DeadMG-当.NET 1.0 / 1.1出现时,LINQ就不存在了。yield也不存在。您是否认为通过删除关键字来破坏旧代码是更好的选择?
奥德

22

正如答案pdr所隐含的那样:设计模式是人们无论如何都在做的事情的名称,目的是使人们更容易讨论这些事情。

通常,值得一开始学习它们,因为它们可以使您深入了解人们发现可行的解决方案,因此您可以基于多年的经验和反复试验来建立。

模式中包含的激励问题的讨论可能使您首先了解解决问题的好方法,但是除非您的模式知识使您认识到存在众所周知的现有解决方案,否则您仍然需要专注于解决问题第一。

如果事实证明是使用一个或多个现有模式,那就太好了,您可以使用现成的名称,以使其他人更容易理解您的代码。


+1为我想说的内容的一个重要总结:专注于问题,然后,只有在问题看起来像一个模式可以解决时,才应用该模式。
Joshua Drake

1
+1表示设计模式是人们一直在做的事情的名字的真实事实。
miraculixx 2012年

12

一般来说,没有。有时候我的代码中会出现模式,但是总的来说,我不寻找它们,我当然也不会说“哦,桥接模式可以解决我的问题!”。

就是这个 大多数模式都被滥用和滥用,而没有人考虑它们是否是好的设计。模式不是原子。代码不包含X个模式排列。更不用说并不是所有的模式实际上都是好主意,或者某些语言​​所具有的语言级解决方案要远远优于某些模式。


+1:我同意有时会滥用模式。有时候,我看到程序员在其中使用某种模式的代码仅仅是因为他(她)知道它并认为它很酷,但这使代码不必要地变得复杂且难以阅读。就像用推土机弄碎坚果一样。关于语言级解决方案,难道语言级解决方案不只是该语言直接支持的模式吗?或有什么区别?
乔治

1
@乔治:换种说法,一些模式用于解决这种事实,即该语言缺乏一种表达整洁事物的方法。
丹妮丝2012年

8

是的,我遇到过的大多数程序员都使用最常见的模式,那就是“泥泞大球”。他们通常从设计良好的体系结构开始,但通常到这里结束,尤其是当他们开始认为“我们必须在各处使用设计模式”并毫不留情地进行重构时。


2
链接让我度过了一天
dukeofgaming

1
哎哟。该网页需要一些文本格式。
Nailer 2012年

7

你用它们吗?

是的,经验丰富的程序员肯定会这样做。您可以暂时避免使用大多数设计模式(不包括简单的单例内容);但是您编写的程序越多,构建的系统越复杂,您就越会感到需要使用设计模式。如果仍然避免使用它,那么当您必须扩展系统并根据新要求进行更改时,就会开始感到痛苦。

如果在网络中某个地方找到解决问题的方法,这是一种设计模式吗?

不必要。设计模式是指一种设计类,其行为和交互以实现特定目标(或避免特定问题)的特定方式。您可能遇到的可能不是真正的设计问题,而是编程特定API的特定步骤序列。例如:建立套接字连接有一定顺序。做错了,您的套接字将无法通信。步骤的顺序不构成模式。

您(程序员)是否发现自己正在寻找模式

是。设计模式体现了“预防胜于治疗”的公理。如果您可以事先发现即将出现的特定设计问题,则可以防止进行大规模的重新设计以适应以后的更改。因此,需要事先了解设计模式并在构建应用程序时寻找需要使用它们的地方。

我应该在哪里看?

由于您是一名学生,因此您可能还没有看到启发设计模式的典型问题。我强烈建议您查看Head First设计模式。他们首先提出一个设计问题,然后说明如何解决/避免特定的模式。


5

我上学时没有教过设计模式。而且,在我的大部分编程生涯中,我都使用传统的,非面向对象的代码。近年来,我尝试学习它们,因为它们听起来像是一个好主意。但是,我必须承认,每当我拿起一本书或尝试阅读有关该主题的教程时,我的眼睛都蒙住了双眼,而且我根本没有真正学到任何实用的知识。

我不敢相信我只是在公开场合承认这一点。我想我可能已经失去了我多年来建立的极客信誉。


3

不要寻找时尚

任何针对某个问题的标准编程解决方案都可以视为一种设计模式,无论其受欢迎程度如何,是否其他程序员都可以使用它们。

您可能已经在使用尚未发明/指定的设计模式。

不要尝试使用它们,请尝试以它们的术语进行思考

设计模式的问题在于,有时程序员会想办法解决他们的问题。

请记住,设计模式的设计约定有一个典型的问题需要解决,您甚至可以结合使用设计模式来解决其他更大的问题。这是面向服务的体系结构中的一种典型,只需看看其中有一些SOA模式即可

在野外寻找它们

在许多开源项目中,您将找到应用的设计模式。我想到的一个例子是Joomla:观察者,您会发现单例。GUI库将具有装饰器模式,实现的命令模式,甚至可能是flyweight

还有其他模式,例如数据模式,例如仅使用Doctrine Project的模式,活动记录模式(1.x),实体管理器模式(2.x),工作单元存储库查询对象元数据映射数据映射和其他更通用的映射,如策略模式装饰模式

有很多有趣的解决方案可供选择。参见Martin Fowler的企业体系结构模式,还有数据模型模式

只要有时间就去学习

学习它们,了解它们,沉迷于它们,当时间到来时,您将知道如何解决编程问题x,届时您将成为更好的程序员。

成为建筑师

我想说,能够以模式的方式思考以解决问题,可以有效地将您变成软件架构师即使您本身不想成为软件架构师,默认情况下,从设计的角度来看,您的解决方案也将具有更高的技术质量,更清洁和更好的可伸缩性。


1

我已经用C ++编程了大约7年,大约2年前学习了模式。大多数模式可能都有一些应用程序,但是在我的用法中,有些比其他的要好。您必须考虑为什么要使用它们。

迭代器模式实际上使我的代码更加混乱,并增加了不必要的复杂性。使用STL向量类型的typedef可以获得相同的可维护性。我对要迭代的类所做的任何更改也必须对迭代器类进行。

但是,基于工厂方法提供的多态性,它非常有用。我忘了是谁说的,但是“可重用性意味着旧代码可以使用新代码”这一说法在工厂模式中绝对是正确的。

我已经使用模板方法模式多年,甚至都不知道它是“设计模式”。

在某些情况下,观察者模式很有帮助,有时则无济于事。您有时必须预测复杂度,以确定Observer模式的开销复杂度是否值得。我们有一个程序,它使用大约10个订阅者,并且可能会有更多订阅者,因此观察者/订阅者模式很有帮助。但是,另一个程序有两个GUI显示。我为该程序实现了观察者模式,它在很大程度上是不必要的,仅仅是因为它增加了复杂性,而且我预计不会增加更多的显示。

我认为那些总是使用模式的人会假设您的程序将变得无限复杂,但是与所有内容一样,在复杂性方面有一个盈亏平衡点。


1

添加到Lunivore。我想引用第一本书的开头

        ## **Three steps to great software** ##     
  • 确保软件能够满足客户的需求
  • 应用良好的面向对象原则
  • 努力实现可维护,可重用的设计

这是在系统按照预期的方式工作之后的第三阶段。是时候应用这些模式使您的软件为未来几年做好准备了。


0

它们是大多数程序员真正使用的吗?

我想是的。在ADO.Net中,有一个DataAdapter类可以给出一个简单的示例,但是取决于要专门化模式的区域可能有所不同。

说到经验,我在编程时遇到了一些麻烦,有些事情我暂时无法解决,但是谷歌和一些小时的研究解决了我的问题。如果在网络中某个地方找到解决问题的方法,这是一种设计模式吗?我在用吗?

不,我认为这不是设计模式。设计模式往往具有定义模式配方的类和方法的某种安排。

我宁愿将您在那做的事当作一种普通做法。不过要小心复制和粘贴编码。

而且,您(程序员)在开始开发时是否发现自己正在寻找模式(我应该在哪里寻找?)?如果是这样,那肯定是我必须开始接受的习惯。

有时,当我一遍又一遍地看到相同的代码时,我可能会找到一种将代码重构为模式的方法,或者,如果我记得针对涉及模式的类似问题的解决方案,则将其取出并使用。 Head First设计模式中包含多个模式,而重构是编码实践的建议,可能导致人们找到各种模式。如果您想要另一个可能的起点,请查看Microsoft的Patterns and Practices


0

学习模式不仅仅是学习一些东西。您将学习使用编程语言可以做什么。我本人只是通过学习模式的工作原理(在这种情况下为复合模式)学习了很多有关面向对象编程的知识。

正如Oded所提到的,大多数程序员有时甚至不认识它就使用它们。模式的优点在于,您可以使用预定义的模式解决特定的问题,因此您不必考虑太多架构问题。


0

在开始处理现有项目时,您将学习模式。有太多的模式可供您学习,不值得花所有时间掌握所有模式,这取决于您正在从事的项目。每当您遇到一个问题时,都要对其进行了解以了解其用法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.