糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > tdd设计比赛_我们是否应该始终使用TDD进行设计?

tdd设计比赛_我们是否应该始终使用TDD进行设计?

时间:2019-05-05 11:21:35

相关推荐

tdd设计比赛_我们是否应该始终使用TDD进行设计?

tdd设计比赛

设计可以从TDD中浮现吗? 我们是否应该始终使用TDD设计软件? 我们应该预先设计吗? 我们应该在何时进行多少设计?

这些是常见问题,经常引起很多争论。 参与这些辩论的人们通常对设计及其定义的范围有截然不同的定义。 如果不先同意某些定义,就很难进行明智的讨论。

软件设计定义

让我们检查一下维基百科的内容:

软件设计是一个过程,代理通过该过程使用一组原始组件并受约束,从而创建旨在实现目标的软件工件规范。 软件设计可以指“在概念化,框架化,实现,调试和最终修改复杂系统中涉及的所有活动”,也可以指“在……(在……)程式化软件工程过程中,在需求规范之后和编程之前的活动。” –维基百科。

我发现此定义有点麻烦,并且使我想到了瀑布过程,在实现任何代码之前都要进行较大的设计阶段。

快速的Google可以向我们显示许多其他定义,其中大多数都说类似的话,但方式不同。 为了简洁起见,我不会在此处添加所有内容。 我将使用自己的定义:

软件设计是指定软件模块的持续过程,该模块负责以易于理解,组合,更改和替换的方式提供良好定义的内聚行为。

该定义的问题在于,它不仅定义了软件设计,而且还引用了一种工作方式,这意味着它意味着设计应作为开发过程的一部分进行逐步完成,而不是完全预先进行。 对于那些不喜欢这种工作方式的人,我们现在可以将其作为描述的可选部分。

软件设计是[连续的]过程,该过程指定负责以易于理解,组合,更改和替换的方式(随着时间的推移)提供定义良好且具有凝聚力的行为的软件模块。

软件设计水平和影响

软件设计发生在许多不同的级别,并且并非所有设计技术都适用于每个级别。 尽管系统可以显示多个级别的细节,但是为了简化起见,我将简化可以进行设计的不同级别。

体系结构:此级别的设计是定义不同系统的职责以及它们之间如何交互的过程。 在这里,我们还可以定义技术堆栈,持久性机制,安全性,性能,日志记录,监视和部署的通用策略。 错误的决策或此级别的更改会严重影响整个项目。

宏设计:此级别的设计是定义单个系统的总体结构的过程。 这种结构可能与以下各层有关:传送层与核心域的分离,六角形体系结构,组件,间接层,高层抽象,包/命名空间。 我们可能还会定义技术堆栈和上述一些架构问题,但仅限于单个系统。 此级别的决策应影响系统本身,而不影响生态系统的其余部分。

微观设计:此级别的设计是在代码级别定义细节的过程,重点是在宏级别定义的高级概念的内部。 微观设计意味着定义类,方法,函数,参数,返回类型和一些小组件。 该级别的决策在系统级别的影响很小,而在体系结构级别的影响则很小。

设计方法

除了进行设计的不同级别之外,还有其他不同的设计决策方式。 它们主要与我们做出这些决定的时间有关。

预先大型设计(BDUF):通常与瀑布式流程相关联,BDUF是预先设计整个系统(在开发之前)的过程,其范围从高级概念(体系结构,服务,协议,数据库)到低级概念级别的概念(类,方法)。

战略设计:定义生态系统主要部分及其整体架构的过程。 与BDUF不同,战略设计未涉及细节。 其目的是根据最重要的业务需求提供技术远景。 这种高级愿景描述了服务,其职责,它们的通信方式,体系结构组件,主要业务流,持久性,API等。

即时设计:在即将构建软件模块时对其进行定义的过程。 该设计过程可用于宏观或微观设计。 实时设计在Outside-In TDD(伦敦学校)中很常见,在TDD的红色阶段中定义了模块之间的协作。 当使用Outside-In TDD时,重构阶段通常涉及较小的设计改进。

紧急设计:基于刚刚编写的代码定义软件模块的过程。 此设计过程通常应用于微观设计级别,并逐渐推向宏观设计。 紧急设计通常在古典主义TDD(芝加哥学校)中找到,该设计在TDD的重构阶段进行,以改进在Green阶段编写的现有工作代码。

复杂程度

复杂性是在决定设计策略时需要考虑的另一个观点。 复杂性可以采取多种形式 ,并且超出了本文的范围,无法描述我们可以在软件项目中找到的所有类型的复杂性。 但是为了简洁起见,让我们考虑复杂的事情,我们无法立即理解或可视化解决方案。 复杂性可以存在于任何级别,包括体系结构,宏设计或微观设计。 根据复杂程度及其发生的程度,应使用不同的设计方法。

TDD通常可以在微观级别上逐步使用,以逐步解决复杂问题,主要是在已知输入,输出和/或副作用的情况下。 例如罗马数字kata或计算保险费之类的算法。 但是,某些微观问题肯定会受益于一些先期思考,例如实施遗传算法。

设计发现过程

设计发现过程不仅应在不同级别上有所不同,还应根据我们对问题域的熟悉程度而有所不同。 无论我们是在架构还是微观设计层面,我们都应该能够立即设计出一个熟悉的问题。 在这种情况下,预先设计没有太多优势。 我宁愿在编写代码的同时进行增量设计。 但是并非总是我们都熟悉问题领域,为了使风险最小化,我们应该进行一些前期调查,创建原型,与业务人员或其他团队一起举办研讨会,并在白板上画一些图。

最后责任时刻与延误成本

明天我们将永远比今天知道更多。 在我们对项目知之甚少的情况下,过早做出重要决策可能会在很长一段时间内严重破坏项目。 我记得投资银行的架构小组很早就决定,我们的团队必须在一个新项目中使用数据网格。 这个决定对项目非常有害,对我们的开发人员来说是痛苦的,正如我们在开发的最初几个月中发现的那样,我们可以以更简单,更快速的方式构建相同的系统。 但是到那时,改变为时已晚。

一个非常明智的建议是在最后一个负责任的时刻做出建筑决策。 有一个著名的故事,一个团队推迟了使用哪个数据库的决策,并使用内存中的存储库构建了系统的核心。 当他们对这些功能感到满意时,他们意识到可以将所有内容存储在文件中,而不必使用数据库,这使得他们的系统更易于部署和使用。 这很棒,但这只是故事的一方面。 另一方面,由于系统无法保留数据,因此他们花了一年时间上线。 推迟对他们的持久机制的决定也推迟了他们的上线日期。

延迟设计决策通常意味着延迟成本的增加。 与其延迟架构决策,不如将重点放在降低更改决策的成本上,以最小化架构组件之间的耦合的方式设计架构。

启用并行工作

当作为一个团队的一部分工作时,我们可以轻松地同意何时进行设计决策,因为不会影响其他任何人。 但是,在多个团队合作的环境中,需要预先进行一些设计,以使团队能够并行工作而不会造成很多干扰。 当他们在定义明确的接口或API后面工作时,将多个团队的工作集成起来也更加容易。

所有级别的并行和增量设计

持续部署是许多公司的目标,因此我们需要开发垂直切片的功能,并不断改进设计的所有部分,从架构到微设计。 各个级别之间的差异通常是变化率。 在体系结构级别,我们将定义支持最重要功能(例如,将成为最低可行产品(MVP)或里程碑的一部分的功能)所必需的最低要求。 这样,架构将每隔几个月发展一次,宏设计每隔一个月左右发展一次,而微观设计则逐日发展。

设计和测试步骤的大小

有时,宏观与微观设计之间的界线可能会有些模糊。 通常,我需要在使用即时设计和紧急设计之间做出选择。 决定与我的信心水平有关。 我对要提供给问题的解决方案越有信心,我的TDD步骤将越大。 在这种情况下,Outside-In TDD是我偏爱的TDD风格,在编写测试时着重于行为和协作。 但是,有时候我无法轻易地可视化解决方案,或者我不确定我脑子里的解决方案是一个好的解决方案。 在这种情况下,我转到古典主义TDD并在测试中使用非常小的步骤,对红色阶段不做任何设计假设,并使用我能找到的最简单的实现尽快将其变为绿色,然后使用重构阶段来确定我是否以及如何要改进设计。 简单设计和SOLID原则的 四个规则是我在重构阶段使用的设计准则。

试驾架构

有人说他们测试架构。 可能是正确的,但我相信他们实际上使用了“测试优先”方法,并不一定能像从TDD中那样受益于快速的短序列“红-绿-重构”迭代来发展体系结构。 在“测试优先”方法中,进行测试是为了确保满足特定的功能或非功能需求,而不是作为逐步发现体系的帮助。 TDDing体系结构可能会浪费大量时间。 我更喜欢使用TDD的双循环,首先从验收测试为我提供指导,然后再使用单元测试来发展解决方案。 我也喜欢架构适应性功能的想法–我们在瑞银(UBS)让他们确保吞吐量和延迟处于可接受的水平–但它们并非完全是TDD。

之后可以编写测试吗?

在某些情况下,我会在架构和黑盒测试中这样做,因为我宁愿等待界面和业务功能稳定下来。 这些测试通常很难编写和维护(通常它们具有复杂的设置),因此在我对需要测试的内容以及如何使其工作有了很好的了解之后,我更喜欢编写它们。

我们通常遵循的准则

由于影响和复杂性,我们通常在编写任何测试或代码之前预先设计架构。 每个项目的前期如何变化。 我们倾向于增量架构,并且通常使用下一个里程碑的功能作为我们的架构决策的基础。 我们接受风险可能会在接下来的里程碑中发生变化,但是事实证明,降低这种风险是非常浪费的。

在宏设计级别,我们通常会进行一些快速的白板会议并讨论应用程序的主要组件。 我们也同意我们是否要使用层,六边形体系结构以及如何将传递机制和基础结构与核心域分离。 由于我们熟悉宏设计决策,并且倾向于在较小的垂直切片中开发代码,因此,Outside-In TDD是我们最喜欢的方法。

在微观层面上,我们的绝大多数设计决策都来自TDD,结合了由外而内和古典主义TDD的组合。 尽管来自外部,但我们经常在流程的一部分中使用小的步骤和三角剖分来冲刷算法,组件的详细信息,甚至一些基础结构代码。

结论

对我来说,问题不是我们是否应该预先设计,而是时间。 设计发生在许多不同的级别(体系结构,宏和微观),并且具有不同程度的复杂性。 我们还需要了解谁是设计的消费者。

从BDUF到Classicist TDD,都有不同的设计风格和技术。 我不是极端的狂热爱好者,所以我更喜欢介于两者之间,有时使用Emergent Design,但很少使用BDUF。

务实。 不要盲目遵循惯例。 有时在白板上画几个小时可以节省几个月的工作量。

翻译自: //05/should-we-always-use-tdd-design.html

tdd设计比赛

如果觉得《tdd设计比赛_我们是否应该始终使用TDD进行设计?》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。