我与从事此业务20年的一位高级开发人员进行了讨论。他在安大略省以写博客着称。

他告诉我的事情很奇怪:他说,有一段代码是工作的噩梦,因为它是从一本教科书,并没有说明现实世界。将新字段添加到UI /数据库/数据层需要2-3个小时,而在他的代码中则需要30分钟。

另一件事是他避免使用设计模式,因为大多数程序员不了解它们,从维护角度来看它们也不是很好。

然后,还有一种想法,加拿大的大多数Web开发人员都希望其数据模型继承自Data Layer类,而不是保持隔离状态。我问他:“将模型与数据层分开不是行业标准吗?”他有时说,但是这里的大多数人不愿意这样做,因为这太繁琐了。它(我自己),如果您需要在几天内推出新功能或字​​段,使用起来会很慢。主要鼓励人们遵循行业标准。我们是否被迫在几天之内不断推出新的领域和功能,而又无法推断出足够灵活的坚实模式呢?这似乎是我从中了解的要点。

您如何看待这些陈述?

评论

“关于标准的好处是,您有很多选择...”

我个人对任何被称为“最佳实践”(没有正当理由)的东西感到不安,因为它通常表示“我不知道为什么这是一个好主意,但我还是希望您这样做;结束讨论”

行业标准,设计模式和最佳实践只是“某人所说的内容在其上下文中可以更好地工作的条件,因此也应该在您自己的情况下。您的高级开发人员的权利。

这与敏捷无关。

“高级MVC开发人员”“设计模式不好”的认知失调

#1 楼

这是一个成功的人的话,而无视那些试图告诉他如何用他不理解的模式行话的人。有些人认为自己是,并驱使知道自己在干什么的人。即使他们不知道自己所做的工作的正确名称。

设计模式在命名之前就已经存在。我们给他们起了个名字,使他们的讨论变得更加容易。具有名称的模式不会使其成为一件好事。

这个家伙可能使用的是你们中没人听说过的模式。很好,直到您需要与他谈谈如何做某事为止。他要么必须学习如何与您交谈,要么您将不得不学习如何与他交谈。与谁是“正确的”无关。

评论


需注意的是,当今大多数人使用“设计模式”一词时,通常是指四人组。

–罗伯特·哈维(Robert Harvey)
16年8月30日在19:39



是的,我喜欢使用英语,这对我来说很有意义。不知道为什么法国人需要这么长时间才能采用它。直到他们做到为止,我将继续学习有关该度量标准的知识。

–candied_orange
16年8月30日在21:00

可能不是他不了解,也可能是他确实了解了,但他知道并不是所有情况都适用于所有情况。

–whatsisname
16年8月30日在21:15

“具有名称的模式并不能使它成为一件好事。它会使它成为可识别的事物。”哦,天哪,这是我所听过的问题的最好总结:D

–轨道轻度竞赛
16年8月31日在8:53

@JanDoggen之所以称为(反)模式,是因为它们也是软件开发中的常见模式(其中一些是与设计相关的模式)。

– JAB
16年8月31日在17:20

#2 楼

您和您的朋友所描述的许多设计模式实际上只是针对编程语言缺陷的解决方法。使用一种更具表现力的编程语言,这些设计模式的大多数需求就消失了。过度设计的代码会带来成本:您必须阅读它,了解它的作用,并了解它在整个软件系统的上下文中如何工作。因此,与任何其他软件开发技术一样,您必须对照使用该技术的成本来评估该技术,并确定收益是否超过成本。

在所有其他条件相同的情况下,代码越少越好。我已经遍历了分层体系结构,在这些体系结构中,您实际上必须在多个项目中进行三到六跳才能找到任何有趣的代码,也就是说,这些代码实际上可以完成除增加开销之外的工作。 >众所周知的软件模式应该为您提供通用的词汇表,您可以通过这些词汇表交流设计策略。不幸的是,许多软件开发人员对软件模式词汇不够了解,无法正确地将其应用于他们的编程问题。没有经验的开发人员将这些模式视为专家的职责范围。他们希望被视为专家,因此他们在准备就绪之前就尝试过早学习和应用模式。相反,他们真正应该做的是首先专注于学习编程的基础知识,然后尝试解决每种模式都能解决的问题。如果这样做,他们将处于更好的位置,可以正确理解和应用模式。

评论


好吧,这是与您在问题中描述的问题不同的问题。我现在工作的商店证明了您可以敏捷并且仍然具有易于维护的非常干净,精益的代码,但这不是大多数Java商店中常见的企业级多层产品,而且其方法是“非标准的”。我们没有一年以“企业”方式构建应用程序。

–罗伯特·哈维(Robert Harvey)
16年8月30日在20:21



@ Igneous01:请注意,从未有任何实际经验的教授认为“好”的东西可能与试图赚钱的企业认为“好”的东西完全不同。

–罗伯特·哈维(Robert Harvey)
16年8月30日在20:58

“不幸的是,许多软件开发人员对软件模式词汇不够了解,无法正确地将其应用于编程问题。”简而言之,这就是我。 =)我看到的几个名称很少,很难找到它们的真实实现。我可能已经编写了一些代码块,可以将其分类为实现模式,但是我肯定无法告诉您哪些代码。我开始认为,模式比实际可解密的代码重要得多,并且需求更改仅影响几个代码位置。

– jpmc26
16年8月31日在1:54

尽管我会以“用更少的代码总会更好”为理由,但我会之以鼻的问题,因为我知道它会导致看起来像脑筋急转弯的代码,但我会热情地同意“模式变化”这一观点。不要抱怨我的代码很烂,因为您无法在教科书中找到它。有很多非常好的理由来称呼我的代码废话,但这不是其中之一。

–candied_orange
16年8月31日在2:04



“实际上可以完成除增加开销之外的事情的代码” -我认为企业软件的目标是应该没有实际上可以完成任何事情的代码。该软件可能具有的任何实际行为,要么应该是分层设计的新兴属性,要么应该由将代码视为数据的业务规则进行表驱动。我只是在开玩笑的50%。

–史蒂夫·杰索普(Steve Jessop)
16年8月31日在8:32



#3 楼

Stackoverflow.SE和Programmers.SE大多鼓励人们遵循SOLID等最佳实践,而不是行业标准。不管您相信与否,事实上的行业标准通常是“泥潭”架构-认真地讲。

但是要直接回答您的问题:设计模式的问题与继承的问题类似-许多平庸的开发人员过度使用它们,因此存在创建过度设计,难以维护代码的风险。但是,这样做的答案肯定不是完全避免或禁止使用设计模式(或继承),答案是学会在有意义的情况下(仅限于此)使用这些工具。而且这完全独立于“敏捷”的工作与否。

评论


我认为您的陈述“设计模式的问题与继承的问题类似-许多平庸的开发人员过度使用它们”的特殊性是不必要的……在编码的所有方面,开发人员可能没有适当地使用某些东西的知识经常会滥用它,并编写次优代码。一般而言,这可以被视为发展的公理。

– Jeremy Holovacs
2016年9月6日14:49在

@JeremyHolovacs:不完全是。我看到的问题是,即使是受过良好教育的开发人员也会过度使用它们。我经常看到解决方案,在这些解决方案中,经验丰富的开发人员试图将问题塞入“某种程度上”适合但并非很好的模式。

–布朗博士
16 Sep 8'在5:47



#4 楼


设计模式只是用于传达思想的名称。我经常发现自己做的事情后来被发现有名字。因此,与“非设计模式方式”相反,没有“设计模式方式”。
设计模式是准则。作为一切,它们每个都有优点和缺点。关键不是要学习模式并将其应用到适合的位置,而是要了解模式的思想,模式的优点和缺点,并利用它来为解决问题提供灵感。
每种最佳实践如果有充分的理由,可以忽略准则。有效的原因包括开发时间和对应用程序的期望。例如,我知道对值进行硬编码(愚蠢的示例)是不好的,但是对于概念证明,其优势可能大于成本(在这种情况下,主要是开发时间)。但是,如果做出这样的决定,则可能适得其反,有时可能需要重构。


评论


RE:是的,是的,是的,是的-我发明了模板样式。我只是没有先做。或诸如此类。

–格林枪杀案
16年8月31日在15:24

#5 楼

为了给汤加一个比喻,设计模式是Microsoft Office帮助程序Clippy。 “您似乎对一堆东西都做同样的事情。我可以通过为您提供Iterator或Visitor来帮助您吗?”

对这些模式的好的记录将表明何时用以前多次做过的相同方式来做某件事很有用,第一次尝试时会犯哪些错误,以及找到了避免这些错误的常见方法。因此,您阅读了设计模式(或从内存中查看了它),然后继续进行工作。您无法做的是仅使用Clippy和向导。

经验不足的人可能会出错并编写不考虑现实的代码,这是当他们认为自己的设计清单模式是解决软件问题的所有可能方法的完整列表,并尝试通过将设计模式链接在一起直到完成为止来设计代码。在野外观察到的另一种较差的策略是,在设计模式“是最佳实践”的基础上,将设计模式塞入并非真正适合的情况。不,对于实际解决的问题,这可能不是最佳实践,但对于无法解决的问题或仅在存在更简单的解决方案时引入不必要的复杂性来解决的问题,这当然不是最佳实践。

当然,也有人可以基于YAGNI来避免使用某种模式,然后意识到他们确实需要这种模式并向常规解决方案摸索。这通常(但不总是)比从一开始就实现需求更糟糕,这就是为什么即使在敏捷开发中,如果没有尽早发现可完全预测的需求也会令人沮丧。我不是唯一一个对此感到非常高兴的C ++程序员,因为Java最初拒绝通用容器是不必要的复杂,然后又将它们重新固定。

因此,原则上避免编写Iterator几乎是一个错误,因为您希望避免使用设计模式。这样做,就像在他的代码中一样,需要30分钟。不管是因为他避免了设计模式还是值得商,的,我认为这更有可能是因为他在设计时考虑了正确的“现实世界”问题,并且由于经验的优势,他的工作要比只拥有教科书和书本的人更好。高理想。

因此,他认识到,任何需要您触摸代码中很多不同点来添加字段的模式,对于工作来说都是一个糟糕的模式,“使添加字段变得容易” ,而他没有使用这些模式。分层体系结构确实会在这方面遭受损失,使用设计模式而不意识到其缺点是错误的。

与此相反,在其设计中编写新UI需要花费多长时间,以及如何多层架构需要多长时间?如果该项目要求他不断在固定数据模型上构建和部署新的UI,而不是不断添加字段,那么希望他会为此设计。还是一样。但是,尽管具有所有好处,但遗憾的是“我们正在做敏捷”并不意味着您永远不必再权衡!

从设计模式菜单中进行选择肯定会阻止您的思考最重要的问题。但是,当您识别出编写访问者并将其记录或命名为“访问者”以帮助读者快速获得它时,并没有多大碍事。由于高级开发人员给出的原因而写“这是一个访客”而不是正确地记录它是一个严重的错误-程序员不会理解。即使是知道访问者是什么的程序员,也需要更多的信息,而不仅仅是“这是访问者”。

评论


“设计模式是Clippy的Microsoft Office帮助程序”今晚我将做噩梦。

–金属迈克斯特
16年9月1日在11:40

“没有经验的人会出错的地方是(当他们)尝试通过将设计模式链接在一起直到完成为止来设计代码。”听见。我希望我能给予多个支持。 :)

– Quuxplusone
16年4月4日在18:37

我也希望我对最后一段有多个投票。设计模式是编程的词汇:如果您掌握大量词汇,那么您将是一个更好,更清晰的作家。看到它们时,我可以告诉建造者一个工厂,但是我从阅读有关设计模式的书中得不到的知识,不外乎我学会了如何通过阅读英语词典来告诉虚张声势。

– Quuxplusone
16-09-4在18:38

#6 楼

您的同事似乎患有NIH综合征(“此处未发明”)。

他的代码可以使添加新字段更加容易:比其他人编写的代码但是这种短期的速度并没有说明代码的可维护性和可移植性。我会给他带来疑问的好处:如果现有的代码不正确地遵循教科书或在错误的上下文中遵循了良好的配方,则可能确实存在错误的结构。 。在我过去的30年编码和管理编码人员的工作中,设计模式有助于将本能上的事情说出来,从而帮助您更快地了解其意图,优势,不便,风险,机会和相关模式。设计模式被证明是掌握复杂性的真正加速器! br />“程序员不了解设计模式”的说法听起来像“我无法真正解释自己在做什么”。或“我不想争论自己的设计”。我真的认为,模式化可以利用整体理解,并且可以让较少的高级同事分享宝贵的意见。但是也许您的高级同事想避免这种情况。

事实证明,在大多数企业应用程序中,分层方法要优于其他体系结构。世界一流的领先套件围绕这一理念构建,并且在性能上优于手工架构。马丁·福勒(Martin Fowler)在他的优秀著作《企业体系结构模式》中介绍了这种方法。哦!再次抱歉:这是关于经过验证的模式的;您同事的NIH观点中没有机会;-)

评论


NIH综合征,有趣,我之前从未听说过。显然,这是大多数北美雇主面临的如何管理员工的问题!

–付款
2016年9月1日20:38在

@pay我不确定这是否仅限于北美;-)总是很想寻求我们过去已经使用的解决方案并取得了一些成功。这是舒适区。但是,人们应该始终保持开放的态度,与具有挑战性的同事进行新想法和建设性对话。毕竟,“您一个人旅行得更快,但是一起走得更远。”

–克里斯托弗(Christophe)
16年9月1日在21:37

#7 楼

许多人错过的一个关键见解是软件设计是上下文相关的。存在它是为了达到业务目标,并且不同的目标可能需要不同的方法。换句话说,即使总有最好的设计,也没有永远都是最好的设计。

设计模式是解决标准问题的标准解决方案。但是,如果您没有遇到问题,则解决该问题很费力。

瀑布式设计与敏捷软件设计之间的主要区别在于制定设计决策时。在瀑布中,我们收集所有需求,确定所需的设计模式,然后才开始编码。在敏捷架构中,我们遵循YAGNI原则将设计决策推迟到最后一个负责任的时刻,这时我们会尽可能地了解选择。

在瀑布式设计中,设计模式倾向于如果在实际需要时可以敏捷地预期到他们的需求,则可以使用该应用程序。结果,敏捷项目倾向于较少地应用设计模式,因为并非所有预期需求都是实际的。

评论


设计模式的+1是解决标准问题的标准解决方案。我有点失望,没有看到更多赞成的答案。因此,这首先需要确定您的问题是否正在与标准问题相吻合,而且通常情况下,它们会让人满意。

–沃尔夫特
16年9月1日在11:06

#8 楼

设计模式并不是真正的设计模式,因为它们规定了要做什么。设计模式之所以是设计模式,是因为它们描述了以前所做的事情。一些开发人员或某些开发人员设计了一种方法,可以很好地完成特定任务,并且能够将其应用于具有相似结果的相似情况。仅此而已。许多模式都有其固有的优点和缺点,并且受过教育的开发人员必须评估技术和业务需求,以确定适合的模式。

鉴于此,除非您真正致力于写作100%的一次性代码,从一个用例到下一个用例都没有可用的概念或实现,几乎可以肯定,您至少使用了某些设计模式。它们可能没有浮华的通用名称,例如“存储库”,“工作单元”甚至“ MVC”,但这并没有使它们“不是设计模式”。

#9 楼

我通常喜欢以使用GPS进行“导航”的方式来思考它。
学习“最佳实践”和“设计模式”时,您将学会采用GPS导航路线。
但是当您知道该区域时,您会经常学到沿着小路行驶会带您经过有问题的区域,使您更快或更佳地到达那里。
这些东西-经验使您能够解构工具箱并采取捷径。

学习设计模式和学习“最佳实践”意味着您了解了背后的想法,因此可以在给定的条件下进行选择情况。因为现实生活中的情况通常比理论上的情况要复杂得多,所以您经常会遇到教科书中没有的限制和问题。
客户/客户希望他们的产品既快速又便宜。
您需要使用遗留代码;
您需要与第三方工具进行交互,这些工具很可能是黑匣子,效率不高;
以及各种各样的事情。
您的情况是特定的-最佳实践和模式更为笼统。

SE之类的网站上的许多人会为您提供“最佳实践”答案和“设计模式”答案的主要原因之一是,因为他们正在回答它提供了通用的语言来解决一种类型的问题。并且让您学习。

所以-不-在敏捷开发环境中,设计模式不会被皱眉;然而,开发很少是通用且抽象得足以完全适合模式的,并且(经验丰富的)开发人员都知道这一点。

#10 楼


将新字段添加到UI /数据库/数据层需要2-3个小时,而在他的代码中则需要30分钟。


如果要“优化”您需要说出要优化的设计。

例如,一辆赛车是一种优化的车辆,而波音747也是一种优化的车辆...但它们针对不同的需求进行了优化。例如,“ MVC”模式的想法针对以下情况进行了优化:


不同相同模型的视图(视图独立于模型)
在集成之前,可以单独开发每个层(例如,由不同的团队)并分别进行测试(单元测试)。
等。 >他的代码可能正在针对其他方面进行优化,例如:完全不同的图层)
等。

模式描述始于对要解决哪种模式的问题。如果他认为不使用特定模式是“最佳实践”,那么(假设它不是一个愚蠢的模式,假设这是一个有时有用的模式),我想他没有/经历过该模式声称的特定问题解决,和/或他遇到了另一个(更大或更紧急,更具竞争性的)问题,而他正在尝试对此进行优化。

评论


“根本没有真正不同的层”-或者,公平地说,是具有通过层传播的可接受的“默认行为”。例如,基于Web的SQL管理应用程序是表示层,当数据库层更改时会自动更新自身。只是,除了有限的用途外,它们实际上并没有按照您希望呈现给用户的方式呈现您的数据:-)半小时似乎难以置信地增加了一个新字段,这表明没有可用于设计的重要UI与新字段的连接,分层或其他方式。

–史蒂夫·杰索普(Steve Jessop)
16/09/5在8:57



#11 楼

设计模式是工具。像工具一样,有两种使用方法:正确的方法和错误的方法。例如,如果我给您一把螺丝起子和钉子,并要求您将两块木头连接在一起,您应该向我要锤子。锤子用来钉钉子,螺丝刀用来钉螺丝。初级开发人员在找到新玩意时通常像孩子。他们想将这种设计模式应用于所有事物。只要他们最终了解到模式A适用于问题B,模式C适用于问题D,就没有内在的错。就像您不使用螺丝起子来钉钉子一样,您也不需要使用特殊的工具。仅仅因为它存在就存在模式;之所以使用图案,是因为它是完成工作的最佳工具。

图案的反面是反图案。一次又一次被证明是不好的事情,通常是在执行时间或内存方面。但是,模式和反模式对不了解它们为什么存在的开发人员都没有好处。开发人员喜欢认为他们正在做的事情是新颖和创新的,但是在大多数情况下,他们不是。以前可能已经想到过。之前的人们是根据经验创建图案的。

当然,初级开发人员通常似乎想出了做旧事情的新方法,有时这些方法更好。但是,最终往往是邓宁-克鲁格效应的结果。开发人员仅了解足以编写功能程序的知识,但不了解自己的局限性。克服这一障碍的唯一方法似乎是通过正面和负面的经验。他们会忽略模式,因为他们认为自己是高级的,但实际上,不知道有10,000个开发人员已经使用了一种特定的设计,然后因为它确实不好而放弃了它。

敏捷的支持关于快速适应不断变化的客户需求的“响应式完成”。它既不支持设计模式也不鄙视它们。如果模式是最快,最可靠的方法,那么开发人员应该使用它。如果一个特定的模式比简单地“完成它”要花费更多的时间,那么使用不是模式的东西就可以了(当然,假设性能不会受到严重影响,等等)。如果找不到已知的模式,则优先设计自己的模式,而不是告诉客户“否”。客户,尤其是付费客户通常是正确的。

任何声称模式是“道路”或声称模式是“存在的祸根”的人都是错误的。模式是工具,旨在应用于特定情况,并根据情况具有不同程度的成功。这是一个事实,与您是否选择MVC,是否使用数据传输对象等无关,这是事实。重要的是在相当短的时间内实现代码,这对于用户来说表现不错,并且没有逻辑错误。

通常,模式将允许一种连贯的设计形式,并且比忽略所有模式来表现更好,而倾向于编写100%的原始想法,但是您不能避免所有模式。例如,如果y = x + 5,您是否真的要编写y = x +(5 * 3 + 15/3)/ 4,只是为了避免写x + 5的模式?不你不是。您将要编写y = x + 5,然后转到下一个问题。

人们每天都使用模式,这没关系。最重要的是拥有具有逻辑功能,很少崩溃且易于使用的代码。没有什么比这更重要了。

评论


我认为需要注意的是,根据您对问题和领域的“当前”理解,您可以创建一个新的类或遵循一种适用于该情况的模式,但是第二天客户希望您这样做对它们进行自定义,使其具有其他客户端在其版本中不希望使用的一些小方面。合并满足2打客户端需求并避免复制面食的代码库似乎是不可能完成的。我今天在重构旧的邮件合并过程时遇到了这个问题。

– Igneous01
16年9月1日在16:15

#12 楼

您不能“避免设计模式”,除非我想避免以相同的方式设计系统的任何两个部分(我不建议这样做,并且我怀疑您的高级开发人员正在这样做)。他可能的意思是“避免仅仅因为坚持设计模式而盲目使用设计”。思考您所做的事情绝对是“最佳实践”,应该有一所大学可以教书;可悲的是,这似乎没有发生。

#13 楼

设计模式与敏捷实践并不对立。与敏捷实践相对应的是,为了使用设计模式而使用设计模式,这是应届毕业生和学生的普遍做法,是按照“我们将如何使用工厂模式解决此问题”的思路进行思考。 >敏捷意味着选择适合工作的最佳工具,而不是试图根据您选择的工具来调整工作。之所以会做出妥协,是因为您可以选择的工具通常受公司标准,许可限制(例如GPL有时不能使用其他开源工具,特别是在构建用于转售的软件时)的限制,以及类似的事情。 br />您的同事/朋友可能反对您的代码,不是因为它本身使用了设计模式,而是因为它是一种人工构造,旨在在其他设计会更好的情况下显示特定模式的使用(尽管通常主观上,我(以及许多我无疑)看到了很多示例,这些示例强制使用特定的设计模式会导致丑陋,难以维护和效率很低的代码。