您如何处理复杂性跳跃?


13

似乎很少见,但经常遇到的经验是,有时您正在从事一个项目,突然间突然出现一些意外情况,在工作中投入了大量的扳手,并极大地提高了复杂性。

例如,我正在开发一个与其他各种机器上的SOAP服务通信的应用程序。我提出了一个效果很好的原型,然后继续开发常规前端,并以一种不错,相当简单且易于遵循的方式来启动和运行所有东西。直到我们开始在更广泛的网络上进行测试,突然页面开始超时,因为连接的延迟和在远程计算机上执行计算所需的时间导致对Soap服务的请求超时后,它才开始工作。事实证明,我们需要更改架构以将请求转出到自己的线程上并缓存返回的数据,以便可以在后台逐步更新它,而不是根据请求逐个执行计算。

这种情况的细节不是太重要-确实不是一个很好的例子,因为它是可以预见的,并且为这种环境编写过很多此类应用的人可能已经预料到了-除了它说明了一种方式可以从简单的前提和模型开始,然后突然将复杂性升级到项目的开发中。

您有什么策略来应对这些类型的功能更改,这些功能更改的出现通常是环境因素而不是规格更改的结果,而在开发过程的后期或测试的结果是?在避免过早优化/ YAGNI /过度设计设计解决方案的风险之间,如何设计解决方案来缓解可能(但不一定是)可能的问题,而不是开发一个可能更有效但又没有针对此问题准备更简单的解决方案,这两者之间如何平衡?一切可能的事情?

编辑:疯狂的埃迪的答案包括“您吸纳它并找到实现新复杂性的最便宜的方法。” 这让我想到了问题中隐含的东西,但我没有具体提出。

一旦遇到困难,就可以进行必要的更改。您是否执行了使项目尽可能接近进度但可能会影响可维护性的事情,还是回到了体系结构并在更详细的级别上对其进行了重新设计,该级别可能更易于维护,但会在开发过程中推迟一切?

Answers:


8

读这本书时,我想到的是敏捷格言:首先在项目生命周期内处理风险最高和/或理解程度最低的任务。即尝试尽早将项目的工作框架放在一起,以证明该概念有效。反过来,这也使人们可以运行各种残酷的测试,以检测该体系结构在现实生活中是否确实兑现了承诺。另外,如果解决方案中包含任何新的,未知的技术/平台/工具,也请尽早采用。

如果核心体系结构尚可,则可以逐项添加和测试各个功能,并在需要时进行重构,而成本相对较低。需要改变架构是最大的风险,应该预先解决。这样可以提供快速的反馈:在最坏的情况下,如果整个概念崩溃了,我们会尽早知道,并且可以以最小的损失中止该项目。


6

您的示例涉及了编程中最具挑战性的方面,即分布式计算并发编程,它们正变得越来越广泛地使用,并使程序员的工作越来越困难。

即使是“普通”编程(一台机器上的单线程),对于任何非临时性程序也是如此复杂,以至于要花很多时间才能拥有熟练的技能和多年的经验,但离“解决”还差得很远。即使在此级别上,复杂度(主要是组合爆炸)也远远超出了人类大脑完全掌握和理解的能力。否则思考是愚蠢的。

分布式计算和并发编程在“复杂性”空间的大小上增加了两个维度,与“常规”编程相比,空间至少以立方(sp?)(n ^ 3)增长。例如,考虑一下我们必须应对的一些新的问题和谬论。甚至想出一个主意,就可以以这种规模理解互连和副作用是可笑的。

我显然没有任何灵丹妙药,但是我敢肯定,一个人可能最大错误就是认为您已了解并解决了所有问题。

除了已经涵盖的其他答案之外,还有一些关于如何应对这一切的想法:

  • 谦虚
  • 接受您的系统/程序不完美,无常且不完整
  • 为错误做准备
  • 迎接改变
  • 计划冗余
  • 考虑未来的证明
  • 研究(或研究)生物学或社会学,复杂系统的行为
  • 尽最大努力避免状态发生变化。寻求无状态协议(例如REST和HTTP)。
  • 函数式编程可能会减轻一些痛苦

我想我可以继续下去。非常有趣的主题:)


查看(或研究)生物学或社会学,复杂系统的行为 -来吧。您剩下的答案都是很可靠的,但是对于所描述的问题,它具有如此广泛的应用。
Jim G.

1
@Jim G.也许 生物学无助于优化循环,但是如果您想提出新的观点,见解或有效的抽象(关于软件开发),它确实有助于走出人们的沙盒。争论生物学(或社会学)与编程无关,而与争论说OOP设计模式与编程无关则只有几步之遥。例如:OOP:生物学-> Alan Kay-> OOP / Smalltalk。或设计模式:社会学->城市设计->克里斯托弗·亚历山大->一种模式语言->设计模式。
Maglob

@Jim G.续 一些引用,Alan Kay:“我认为对象就像生物细胞和/或网络上的单个计算机,只能与消息进行通信”,维基百科:“ [设计模式]这个想法是由建筑师Christopher Alexander在建筑领域[1],并已适应其他各种学科,包括计算机科学”
Maglob

好的。我为您提供+1的尝试,以尽最大可能避免状态变幻和其他掘金。我的观点是,如果您的经理要求您降低复杂性,那么您肯定会使用Occam的剃须刀解决问题并开始工作。我认为您或其他任何人都不会“寻求生物学”来解决眼前的问题。
Jim G.

2

我不同意@PéterTörök的回答精神,因为它假定团队(或个人)可以在项目生命周期的早期预见最危险的项目。例如,在OP的情况下,团队无法预见到多线程解决方案所带来的不断升级的复杂性,直到他们的背靠墙。

OP的问题是一个很好的问题,它谈到了许多软件开发商店所遇到的问题。

这是我如何处理该问题:

  1. 遵循弗雷德·布鲁克斯(Fred Brooks)的建议,像外科手术团队一样组织您的开发人员。
  2. 选择一个既有智慧又有“仁慈”的外科医生,可以做到:A)获得同龄人的信任和尊重;B)及时做出困难的决定。
  3. 期望外科医生在开发过程的前端和后端减少复杂性。

关于第3点的更多信息:

  1. 外科医生应有意识地提出最可行的解决方案。多年的有意义的经验应该使主治医师能够做到这一点。
  2. 更大的组织,即主外科医师的上司,应给团队足够的时间和资源,以减少船期后的复杂性。这将允许开发团队都船舶代码及时并进行持续改善,以减少在持续进行的复杂性。

在OP的情况下,恕我直言,他们应该早点开始测试,以了解其架构在现实生活中的工作方式(以及是否)。顺便说一句通过建议有一个“大师操刀”,你似乎基本上意味着有谁可以预见该项目的技术风险的人-你声称与不同意的确切地点。
彼得Török

@PéterTörök:...建议一个“主治医师”,您似乎基本上是在暗示有人可以预见该项目的技术风险:不,我不是。我是说这些人都是:A)首先最适合完全避免复杂性;B)最适合在代码发布后使团队摆脱复杂性。
Jim G.

恕我直言,我们正在谈论同一件事。可以帮助您的“主治医师”选择可能可行的最简单解决方案的经验是建立在对过去的项目和解决方案的记忆中,并了解哪种解决方案在哪种情况下有效(或无效)。换句话说,他会研究适用于特定问题的解决方案,并评估每个问题的潜在收益和风险。这就是帮助他/她为当前情况选择正确的方法的原因,从而避免了冒险的道路
彼得Török

1
这让我想起了一位已故的伟大的驯马师雷·亨特(Ray Hunt)的一句话:“您如何获得良好的判断力?经验。您如何获得经验?错误的判断力。”
glenatron

1

接口代码

在编写与其他功能接口的新功能时,请以所有接口都通过的接口(Java类)的形式进行边界。这将

  1. 确保您完全控制使用的功能
  2. 允许您具有相同功能的多种实现。
  3. 降低整体复杂性,因为模块仅是稀疏连接,而不是完全交织在一起。

0

可以从简单的前提和模型开始,然后突然将复杂性升级到项目的开发中

不奇怪。

这是软件开发。如果您不发明新东西,那么您将下载现有的,经过验证的解决方案。

没有什么中间立场。

如果您要发明新东西,那么至少必须有一个您不完全了解的功能。(要完全理解它,您必须要有一个可以使用的可行的实现。)

如何处理?

  1. 有现实的期望。您正在发明新的东西。有必须是你不理解的部分。

  2. 有现实的期望。如果它似乎第一次正常工作,那么您就忽略了一些东西。

  3. 有现实的期望。如果很简单,那么其他人会首先这样做,而您只需下载该解决方案即可。

  4. 有现实的期望。您无法很好地预测未来。


2
等待,所以您要说的是:有现实的期望吗?
glenatron 2011年

0

设计和编码时要过时。假设您今天编写的代码明天将需要删除并替换。


0

环境应该是规范的一部分。因此,环境的变化就是规格的变化。另一方面,如果您将原型和设计基于规范之外的环境,那么您将犯下愚蠢的错误。无论哪种方式,您都会发现并找到实现新复杂性的最便宜的方法。


0

与大多数编程问题一样,我认为这取决于。这个问题对于创意工作来说是内在的,您不要忘记失败会发生,这是可以的。编程是一个严重的问题,通常在解决问题之前,您不知道正确的解决方案。

但是,这里可能会涉及许多本地的特定因素,例如:

  • 该系统的目标。 这是一次性的事情吗?您是否打算使该系统在中长期运行?

对于短期的事情,仅仅为了使其运行而进行思考可能就不值得了。重构非常昂贵,而且不会为用户创造直接的最终价值。 然而,除了绝对适用的软件外,几乎没有什么我可以想到的,因为它太短了,因此不值得改进您的设计。与立即完成相比,能够了解您所做的事情并迅速进行修复更为重要。如果是更长远的话,那么它很可能最终会得到回报(可能比涉及的每个人都想像的要早得多),或者反过来(不这样做会很快引起痛苦,而不是“当我们必须修复它时”)。我几乎想说“总是花时间使它变得更好”,但是在某些情况下这是不可能的。

  • 团队的目标。 它更像是“不惜一切代价现在就做”还是“让我们做对了”之类的事情?

这将极大地影响您的决定。您的团队将通过为您提供重新设计的资源来支持此决定,或者他们将要求立即执行快速解决方案。在我看来,如果您发现团队始终将您推向错误的方向,那将是一个巨大的危险信号。我已经看到这种情况最终会发生在不断进行灭火的情况下,再也没有时间进行重新设计了,因为您总是在解决不良设计所带来的问题。但是,也可以有一个中间立场:现在,“胶带”,尽快修复(但实际上要这样做)。

  • 您对问题的理解。 为什么以前的解决方案不起作用?

真的很重要 考虑一下错误或问题是什么以及它为什么发生。这种情况是寻找有缺陷(或缺失)的假设,约束和相互作用的好机会。通常,始终倾向于更好地理解问题而不是解决当前问题。这可能是您针对YAGNI /过度设计的最大防御。如果您对问题有足够的了解,那么您将解决问题而不是其他问题。

最后,尝试以正确的方式构建事物。当您对问题或固有的人为错误有所了解时,我并不是在谈论您面临的错误和问题。我的意思不是“不要犯错误,并且第一次就能做到完美”-这是不可能的。我的意思是,尝试在日常工作中很好地管理复杂性,修复破损的窗户,使它尽可能简单,并始终改进代码和思维。这样,(不是如果)零钱敲门时,您可以张开双臂而不是a弹枪欢迎它。

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.