软件设计:快速构建还是良好构建?


38

在构建非平凡的应用程序时,最好集中精力使事情快速运行,并在代码中采取一些捷径,例如将模型逻辑与视图混合,破坏封装-典型的代码味道?或者,您是不是最好花些时间来构建更多的体系结构,正确构建它,但是冒着这样的风险,因为您的设计非常流畅,所以可能无法使用所有这些额外的代码,并且如果反馈导致您可能不得不将其丢弃去一个不同的方向?

对于上下文,我正在构建一个桌面应用程序。我是唯一的开发人员,因为我有一份日常工作,所以我做兼职。现在,在工作中,我会尽量按计划安排正确的方式做事。但是对于这个项目,我希望它会随着人们的反馈而变化,我不确定这是正确的方法。我本周花了几个小时在适当的地方放置了教科书“模型视图控制器”设计,以将模型中的更改传达给视图。总的来说,这很好,但是我不确定是否需要多个视图来显示数据,而且我知道如果没有其他体系结构,我可以更快地显示内容。我可能每周花10到15个小时花在该项目上,如果遵循良好的软件实践,我会花很多时间来构建可以演示的东西。我知道我的用户会 不在乎我在内部使用MVC,他们只是想要解决问题的方法。但是我也遇到过这样的情况,即您因快捷方式而承担了太多的技术债务,以至于很难维护代码并添加新功能。我很想听听其他人如何解决这种问题。


10
“从来没有时间做正确的事,但是总是有时间做完。”
Scott Whitlock

1
您知道财务顾问如何说不负债吗?也不承担技术债务:)
妮可(Nicole)

3
必须提供的xkcd参考:xkcd.com/844
user281377 2011年

@ammoQ击败了我。

1
史蒂文:根据我的经验,这种假设成立,而未来的需求却落在了预期的范围内(并且是概念上准备好的);但是有时候,一个新需求需要进行一些“怪异的交互”,而这在适当的设计中更难实现,因为所有那些整齐地分开的类,层等突然需要以一种设计没有准备好的方式进行交流。
user281377 2011年

Answers:


48

建造好

如果看大图,“快速”构建它是一个逻辑谬误。这将使您无法很好地构建它,最终您将陷入无法进行重构甚至无法添加新功能的错误和基本体系结构缺陷的困扰。

好的构建实际上是相反的。起初它可能会比较慢,但是最终您将花时间在正确的选择上,从而发现效率提高。此外,您将能够更轻松地适应未来的需求(如果需要,可以进行重构),并且至少由于更少的错误而拥有更好的最终产品。

换句话说(除非这是一个一次性合同),快速构建它=缓慢构建它,良好构建=快速构建它


关于“很好地构建”和设计体系结构,还有一些重要的认识要实现。您问...

...但是冒着这样的风险,因为您的设计非常流畅,因此可能无法使用所有这些额外的代码,并且如果反馈导致您朝着不同的方向前进,则可能不得不将其丢弃?

这并不是“花费架构时间”的真正风险。 建筑设计应该是有机的。在证明其合理性之前,不要花时间为任何部分设计架构。架构仅应在项目中观察和确认的模式之外发展。

来自系统论的约翰·加尔定律:

从头开始设计的复杂系统永远无法运行,也无法进行修补以使其正常运行。您必须重新开始,首先要使用一个简单的系统。


9
我不能投票足够。鲍勃叔叔的另一个好话是“走快的唯一方法就是走得好”
CaffGeek 2011年

1
+1是因为一旦做得好,您就可以重用该代码并在下一个项目中再次使用它,它的速度甚至更快。冲洗并重复直到其成为第二自然。
加里·罗

4
为了纪念我父亲,“如果您第一次对它不满意,那么当您重新修理它时,您的工作量将增加一倍。”
蚂蚁先生

呵呵...这个公式使我想到:良好构建=快速构建=缓慢构建。我猜最后一个“快速构建”应该以较少的技术债务来构建。由于构建完善的系统所需的工作较少。
Spoike 2011年

@Spoike我也同意,但是这个主意是“构建好= 以后再构建”。因此,许多经理不想放弃速度几个月,而实际上会在以后提高速度。
妮可(Nicole)

17

快,那就好

这是从我的个人经验中尝试过许多不同的方法得出的。

通常,仅快速工作(并发布)的问题是,您需要将一个功能接一个功能地添加到应用程序中,并且由于该功能已发布,因此很难对程序进行根本性的更改。从长远来看,您要付出高昂的代价,而要拥有一个健全的基础架构,就像在流沙上摇摇欲坠一样。

做得好的程序会浪费很多时间和代码。就像建造一座没有任何蓝图的豪宅一样。编写应用程序是一个学习过程,根据我的经验,几乎不可能预先设计。这意味着您将进行大量的重构,并且如果您一直都写得很好,那么最终您将浪费很多代码。

因此,快,那就好!

开始时最主要的就是将所有内容都写在代码中,以便可以确定所有功能并查看需要支持哪种架构。这种方法的另一件好事是,我会保持积极性,因为您会很快运行一些东西。实施一些“边缘情况”功能也很重要,因为这会对您的总体体系结构产生影响。在此阶段,请勿打扰编写单元测试或处理细节。如果您认为将来需要支持多语言,则可以使用什么都没有的插件架构来实现,但又麻烦又麻烦。进行一些重构以使应用程序易于管理,但不要过多。

感觉到您有一个有效的“原型”之后,就该开始重构了。基本上,如果您从头开始知道现在所知道的一切,那么您想要像执行操作一样重做该应用程序。重要的是使架构正确,而不是重新实现在第一阶段中完成的所有功能,但是您应该拥有适当的架构以在以后对其进行支持。

无论如何,根据我的经验,您将最终以尽可能高效的声音结构构建应用程序:)


2
+1是,我要添加-使用迭代方法
。– pmod

我同意这个答案。我同意pmod。
金钟佑

迭代速度优于迭代质量-根据StackExchange
jasonk 2012年

10

建立它

如果上市时间比质量更重要,那就

好吧,如果质量比上市时间更重要


8

快速构建它会给您带来短期利益和长期损失。

建造得好会带来短期损失,但会带来长期利益。

很好地构建它需要耐心和智慧,但您会得到回报。

快速构建它仅对快速原型设计和即弃产品有用。从一开始就只有正确的态度才能实现长期目标。


5

对于您计划分发给他人使用的项目,我总是会在前期工作中出错。如果需要,经过深思熟虑的体系结构更易于扩展。捷径只是积累技术债务的模型。

有时它会令人沮丧地缓慢。值得做的事情值得做对的事情。


1
只是为了表述“经过深思熟虑”的陈述:这并不意味着要事前考虑所有事情(这无法完成),而只是花一些时间思考如何集成功能而不是在某个地方扔掉并完成它。 。
Matthieu M.

5

精心构建=快速构建

捷径往往会转身,甚至比您想的要快。有时甚至在午餐前。

关于你的背景;不要立即抽象。坚持使用YAGNI并删除重复项。当您实际上有第二个视图时,不要实现该基于视图的模式,这并不是因为您认为将来可能会有一个。当第二个View到达时,您创建的抽象通常会好于您在第一个View中创建的抽象。


3

好吧,如果您已经知道自己在做什么,那么如果不知道,那就快

我是一名研究科学家,在不了解总体情况或项目将如何发展之前,我编写了很多探索性代码。在这些情况下,甚至很难看到应该定义“井”的程度。而且,通常很难看到所有小细节和事情可能会提前扩展的方式。因此,旧格言适用:

  1. 让它起作用。
  2. 改正它。将其正确设置的好处是,一旦您拥有使它正常工作的经验,便可以更好地定义“正确”。

2

很好地构建它..总是,但是给人一种快速前进的幻想

但要使其快速,只需使其变小即可。建立整体的一小部分,足以获得反馈。以恒定的速度逐步添加它,将产生与快速构建几乎相同的好处,而不会让您的灵魂陷入打playing虫的不眠之夜的连锁反应中。


+1,仅构建真正需要的内容。
妮可(Nicole)

1

我认为应该始终“建造良好”。如果上市时间是一个大问题,则使用增量开发过程。最坏的情况是您的产品功能较少,但至少要交付高质量的产品,并且可以在以后的功能版本中对其进行扩展。


1

平衡

将您的代码完美地设计或将一些代码拼凑在一起是不切实际的,对吗?真正的目的是达到适当的平衡。我认为重要的是您什么时候做什么。

我认为这里最重要的是绝对确保应用程序的核心(基本结构)的构建良好。气密。一旦实现,取决于时间限制,如果时间紧迫,您可以将一些代码放在一起,然后再进行重构,这样您就可以负担得起,因为您会格外小心地获得基础是的,重构代码不会有什么坏处。


正确。在允许的时间范围内尽可能地构建它。
jwenting 2011年

1

做可能可行的最简单的事情。在您的特定情况下,您的程序不会变得很大,因为您是兼职工作的唯一人员。我不是在提倡不良习惯,例如滥用goto,不描述变量名等,但是您不应使其变得比必须的复杂。也许MVC只是您的特定项目的一个过大杀伤力。


0

我希望随着人们的反馈,它会发生变化

您自己说的最好:

但是我也遇到过这样的情况,即您因快捷方式而承担了太多的技术债务,以至于很难维护代码并添加新功能。

如果您的时间很短,请不要害怕用相同的理由要求更多的时间来完成您的雇主的项目。我相信他们会把它授予你的。话虽如此,我知道有时候在某件事上如此努力地工作,而不能炫耀很多结果,会感到多么沮丧。但是请放心,您会到达那里,并且构建好它肯定是值得的。


0

通常,我喜欢很好地构建结构,而不必担心特定的实现细节,从而节省时间。就像您说的那样,它们仍然会改变。建立完善的基础结构的想法是,一旦建立基础,变更就可以很快发生。我试图集中精力在我的课堂上尽可能地通用,并使它们在可能的情况下可重用。我通常会为用户提供一个构建良好的应用程序,该应用程序只能满足最基本的可用性要求。一旦有了工具,用户就可以使用各种Idea,因此想得更远没有任何用处。


0

建造。如果没有时间,请减少功能集。

设计尽可能通用。例如,设计一种插件架构,即使您知道,也只会在第一次使用一个插件。使用通用配置方案(可扩展的配置,组织语言),即使开始时只有一个参数。这是一项非常好的投资,您只能在项目开始时进行这项投资。


0

最好集中精力使事情快速运行,并在代码中采取捷径,例如将模型逻辑与您的视图混合,破坏封装-典型的代码味道?或者,您是否最好花些时间来构建更多架构

在我耳中,按照您所说的方式,您列出了两个极端。首要选择是破坏封装,将模型逻辑置于视图中,这只是糟糕的惰性编程。恕我直言,解决这些问题与增加更多体系结构不一样。除非您在说什么,否则除非UI代码正在执行SQL语句。但是,我不会说要构建更多的体系结构,而是要说您完全缺乏设计和体系结构,应该得到一个。

关于架构,我会选择最简单的架构来立即解决您的问题,然后在出现问题时进行扩展。

例如,您现在需要的是从单个数据库表返回数据的功能,即使我知道问题最终会出现,我也不用担心如何从相关表中加载数据之类的问题。当我开始实现该功能时,我将开始担心它。

因此,对于我自己的家庭开发项目,我将采用以下方法:构建最简单的解决方案,该解决方案可以解决我目前正在处理的问题,但是要很好地构建它。然后,当需要更多复杂性时,我将重构解决方案。遵循TDD惯例可确保重构安全,并有助于避免代码异味(如果破坏封装,则很难创建良好的单元测试)。

顺便说一句,这也是我专业工作时所采用的方法。;)


0

我建议您首先应该站立软件,涵盖所有方面,并首先站立软件,然后逐步装饰并提高其性能。


-1

通常,您希望位于以下两个边缘的中间:

精心构建 = 人们生活所依赖的至关重要的实时软件。即软件控制:核反应堆,透析机,MRI机等。

快速构建它 =没人真正使用的无用软件。


哈!构建无用的软件...
pmod

有否决理由吗?
vz0 2011年
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.