导读:本文为各位提醒一下,设计与构建软件的重要一环,抽象的力量。一起来看看。
我第一次听到抽象是在我攻读学士学位期间的编程课程上,当时我们正在研究面向对象编程的四大支柱:抽象、封装、多态与继承。
我对在正在构建的软件过程,对现实世界进行建模的想法着了迷。这对我来说是一个全新概念,需要大量练习才能习惯这种方式思考。
后来,我对抽象的理解有所增长。正如我们在面向对象编程课程中学到的那样,它不仅仅是在软件中复制现实世界。抽象还可以应用于不同的级别,虽然一开始看起来可能很复杂,但事实也并非那么难。
在本文中,我将解释抽象如何应用于代码设计,以及它如何帮助你更好地理解技术世界。通过使用有效的抽象,我们可以构建更好、更易于维护和理解的软件。
其中:商业部分包括商业设计、运营设计与产品设计;架构设施包括需求分析,架构设计,数据库设计;编码和设计包括实现、交付与详细设计。
作为软件工程师,针对不同场景适当地处理抽象至关重要。我们需要根据所处的环境调整沟通和重点。
在与利益相关者会面时,我们不能使用与工程团队中使用的相同的技术语言。
在这些场合下,主要目标是尽可能彻底地了解业务、领域和策略。
另一方面,在与团队讨论解决方案、基础设施和架构时,我们应该避免关注特定的代码或编程语言。这些是高层对话,旨在确定管理微服务和应用程序的最佳方法。
因此,需要考虑不同的抽象层次,我们必须在正确的时间与正确的人一起将我们的问题和思维调整到正确的水平。认识到这些抽象层次帮助我理解了上下文的力量。
但低级解决方案又如何呢?我们如何识别正在构建的软件中的抽象,以及它是如何工作的?
在设计软件时,我们处理代表系统内用户操作的用例。抽象是必不可少的。通过定义抽象的责任,我们根据已经建立的上下文和目的来塑造它。
创建新的抽象,就像将某些东西赋予生命一样。我们需要明确其职责和目的。这就是为什么我特别喜欢使用界面的原因。它们使我们能够为抽象定义清晰的契约,确保系统的每个部分都有特定的角色并与其他部分交互。
用定义良好的接口充当我们抽象的契约。这就像把某件事带入生活并说:“你的目的就是只做这件事,并且把它做好。”我们不需要担心如何完成的细节;该接口提供了一个稳定的契约,定义了抽象是什么以及它提供什么。
此方法与 SOLID 原则中的“D”一致:依赖倒置原则 (DIP)。DIP 指出我们应该依赖抽象而不是具体。通过遵循这一原则,我们创建了灵活且可维护的系统,可以更轻松地适应变化。
在软件设计中,我认为界面就像拼图一样。每件作品都有明确的协议和目的,使我们能够在需要的地方精确地使用它们。
使用接口可以在更改代码时提供稳定性。无论具体类发生多大变化,只要它遵守契约,该接口的使用者就不会受到影响。
使用接口定义抽象也支持 TDD。通过模拟方法,我可以模拟外部抽象的行为,并专注于我正在构建的当前抽象的预期行为。这可确保拼图的每一块都完美贴合并按预期发挥作用。
在设计用例时,我们通常倾向于将所有行为和业务规则集中在单个服务或用例中。
但是,一个设计良好的用例实际上是多个抽象一起工作的组合。
示例:
在财务软件中,考虑生成发票的用例。流程可能如下所示:
验证请求的用户是否有权限
获取发票
计算税金
生成发票
但是实际上,此用例处理所有业务规则并不十分理想。相反,它应该将特定的职责委托给为这些任务设计的抽象。
构建高质量的软件需要的高质量问题
为了创建有凝聚力的用例,我们需要提出正确的问题:
这是谁的责任/职责?
这个用例有多少个理由必须改变?
我们是否应该创建一个抽象来处理这个特定的业务规则?
该业务规则是否在我正在构建的抽象范围内?
这是有内聚力的吗?
没有太多上下文的人可以理解这个用例吗?
一个可能的解决方案:
依赖于处理权限验证的抽象
获取发票金额
依赖于处理税收计算的抽象
依赖于以所需格式生成发票的抽象
好的软件设计始于提出正确的问题,最终目标是简单。而软件设计是一个持续的过程;总是会有改进的空间。
也不一定一次设计的完善,我们仍然可以通过从错误中学习,以及定期练习来不断完善软件设计。
作者:洛逸
失落的软件设计艺术 - Simon Brown
构建抽象而不是幻想 - Gregor Hohpe
软件开发人员的核心设计原则 - Venkat Subramaniam
本文为 @ 场长 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。