为什么我推荐功能驱动的软件设计方法? - khalilstemmler


功能feature代表了软件设计的基本复杂性。这是无法避免的复杂性。其他所有内容(语言,工具,模式等)都是意外复杂性的一种形式。因此,要编写最简单的代码(无论我们在堆栈的哪一侧),都应该采用功能驱动feature-driven的方法。它影响我们构造项目,编写测试,封装模块和设计功能的方式。
 
偶然的复杂性
在大多数主流编程语言中,都存在状态和序列的概念。根据本·莫斯利(Ben Moseley)的说法,状态和序列是 意外复杂性的两个主要原因:

  • 状态:“您是否尝试过将其关闭然后再次打开?” 以前有没有人对你这么说过?当系统最终处于非法状态时,就会发生这种情况。维持状态很难。我们必须跟踪变量,实例等。
  • 顺序:首先,我们执行这个操作,然后才需要执行那个操作,但前提是发生这种情况”。我们大多数人都使用支持过程和条件的语言编写。当我们必须确保事物按特定顺序发生时,我们还将引入表面积,这样就提高了复杂性。

偶然的复杂性是指我们面临的复杂性实际上与问题的复杂性无关(例如基本问题-功能)。相反,意外的复杂性与我们解决问题的方式有关。
这意味着包含状态和序列的语言或范式会无意间引入意外的复杂性。
好吧,我们可以编写没有状态和序列的代码吗?
事实证明,我们可以。
 
通过函数式编程减轻意外的复杂性
这是(纯粹地)函数式编程的亮点。Scott Wlaschin的《领域建模的功能》一书描述了一种通过使用最少的状态或序列来对功能/用例(他称为工作流)进行建模来尽可能接近基本复杂性的方法。

这是一种非常彻底的方法。我认为这太神奇了。但是,真正的纯铁上下的函数式编程是不适合心脏虚弱。这是一些严格的程序设计。通过从头开始对整个域建模,类似于我们从第一原理建立数学方程式的方法,这确实是使非法状态无法表示的方法。
 
结构与开发人员的经验-FP很难
在软件设计中,需要在结构Structure和程序员经验之间平衡。90年代的OOP员工发现了一种很棒的功能优先方式,可以始终如一,可靠且自信地编写包含状态和序列的代码。
  
使用功能优先的TDD驯服(状态和序列)复杂性
测试驱动开发不仅仅是对React组件和类进行单元测试。
通过找出一种继续添加和更改代码的方式,并确保我们应用程序的功能仍然有效,可以获得最佳的投资回报。这就是我们大多数努力的地方-因为这些功能毕竟是必不可少的复杂性。
执行TDD的“功能优先”方法是执行Double Loop TDD
 
功能优先的集合
我发现的一些最佳技术可以帮助我们与当前问题的本质保持一致,并消除噪音(技术堆栈,语言,范例等),这些技巧如下:
  • 事件风暴
  • 事件建模
  • 用例驱动设计
  • 验收测试驱动开发(也称为双循环TDD)
  • ...还有更多,待续

  
您可以在前端和后端体系结构上以功能驱动的方式工作。看看DDDForum的代码,DDDForum是我们在solidbook.io中构建的应用程序。后端遵循按用例组织的功能优先项目结构。