本文探讨了如何开发复杂软件系统,提出了一种自顶向下的分层开发方法。作者建议通过编写微型驱动程序来了解物理约束,并从用户界面或API开始,逐步向下实现每一层,同时定义下一层的API。该方法强调在开发过程中保持代码的可读性和模块化,并建议只在涉及IO操作的部分使用模拟接口。
1. 通过编写小型测试程序了解硬件性能限制。2. 从软件的最顶层开始编码。3. 将软件分层实现,每层只处理必要的逻辑。4. 在编码某一层时,定义下一层的API。5. 填充下一层的stub。6. 递归实现下一层。7. IO抽象化。
作者建议在遇到问题时及时回溯并重新设计,而不是强行推进;同时鼓励开发者使用模拟和占位实现来加速开发进程。
作者:@Grant Slatton
原文:https://grantslatton.com/how-to-software
背景
本文探讨了如何开发复杂软件系统,提出了一种从顶层到底层的分层开发方法。作者建议通过编写微型驱动程序来了解物理约束,并从用户界面或 API 开始,逐步向下实现每一层,同时定义下一层的 API。这种方法强调在开发过程中保持代码的可读性和模块化,并建议仅在涉及 IO 操作的部分使用模拟接口。
【第3436期】再见Postman,你好Insomnia:更快的 API 测试方式
从顶层到底层的分层开发方法步骤
其主要步骤如下:
1、界定问题
2、自顶而下
3、分层实现
4、定义接口
5、填充下一层
6、递归实现
7、IO 抽象化
问题
1、如何开始构建复杂的软件项目?
-
首先,通过编写一些小型测试程序,了解你的解决方案空间的物理限制。例如,如果你正在构建数据库,测试每秒可以解析多少请求,磁盘可以处理多少次读写,CPU 每秒可以计算多少次校验和等等。
-
接下来,从软件栈的顶层开始,通常是用户界面或 API。
-
将你的软件实现为多层结构,每一层只剥离最少的逻辑,并将剩馀的複杂性委託给下一层。
-
在编写每一层时,将下一层的 API 定义为实现当前层的完美领域特定语言。
-
在编写当前层时,先将下一层的代码填充为占位符。
-
当前层完成后,递归地使用相同的方法实现下一层。
-
持续这个过程,直到完成整个软件。
-
只为执行 I/O 操作的代码部分实现可模拟的抽象接口,其他所有代码都应该是具体的。
2、什么时候应该使用这种方法?
当你构建的软件项目规模很大,不可避免地需要数万甚至数十万行代码时,这种方法才适用。对于小型软件项目,例如少于 5000 行代码的项目,使用单个文件和最小化抽象可能更有效率。
3、为什么要从顶层开始,而不是从底层开始?
从底层开始构建软件的缺点是,你在编写上层代码之前就锁定了底层的设计。当你实现上层时,你可能会发现底层 API 并不完美,但你却不愿意修改它,因为你已经花了很多时间来实现它。
从顶层开始,让每一层定义下一层的 API,可以确保每一层的 API 都完美地满足上层的需求。此外,这种方法还可以在开发过程中始终保持一个半可运行的软件,方便展示和测试。
4、如何实现一个软件层?
每个软件层的代码应该易于阅读。如果它不易读,则意味著它剥离了太多的逻辑。
在编写代码之前,先假设下一层的 API 已经存在,并以最佳的方式使用它来实现当前层的功能。
然后,再开始实现下一层的 API。
5、如何填充下一层的代码?
最初,你可以使用简单的占位符来填充下一层的代码,例如返回固定值,抛出异常或直接崩溃。
随着开发的进展,你可以使用更完整的 mock 对象来填充下一层,例如模拟数据库查询或文件读写操作。
尽量减少在实现占位符和 mock 对象上花费的时间,因为你很快就会实现真正的代码。
6、什么时候应该使用真正的 mock 对象?
只有在测试 I/O 操作时才需要使用真正的 mock 对象。例如,在测试数据库时,你可以使用 mock 对象来模拟底层数据存储层,例如硬盘或文件系统。这样可以使测试快速且确定性,避免网络调用或其他不确定因素的影响。
7、如何进行团队合作?
一旦你开始了这个过程,就可以很自然地让不同的人实现不同的 API。
每个软件层通常都有多个子层,每个子层都可以分配给不同的工程师进行开发。
这种方法需要项目开始时由一名开发人员负责编写最顶层代码,但这也有好处,因为它可以为整个项目设定基调。
8、使用这种方法可能遇到哪些陷阱?
有时你可能会以无法实现的 API 来编写某一层代码。
如果发生这种情况,不要强迫它工作或调整代码,而是应该删除代码,回溯到上一层,并使用新的 API 重新实现该层。
9、分层的优缺点
“分层” 方法指的是将软体分解成多个层级,每一层都负责处理特定的一部分逻辑,并将其余的性委託给下一层。这种方法有以下优点:
-
始终拥有可运作的软体:由于是从顶层开始开发,所以开发者总是有可以展示或测试的半成品软件。
-
每一层的 API 都完美符合需求:从顶层开始,让每一层定义下方一层的 API,可以确保每一层的 API 都完美符合上一层的需求。
-
易于协作:每个子层都可以委派给不同的工程师开发,提高效率。