浅谈软件设计与复杂度控制

1. 什么是软件设计

2. 软件设计的目标

需求、产品、设计和开发是软件研发过程的一系列活动,需求和产品的侧重点是为软件用户提供价值服务,是来寻找和挖掘商业价值的,而设计和开发的目标则是尽可能高效、经济地实现软件,只有两方面都发挥好了,才能使软件为客户获得更好的“利润”。


软件、需求和设计各自的目标

3. 软件设计的特点

我们经常可以看到软件研发同学在软件设计环节争得面红耳赤,也经常遇到设计评审时“权威”压制“民意”而导致后者耿耿于怀的情况。那么,究竟是什么原因导致了这些现象的发生呢?软件设计为什么会有这么多困难和困惑呢?我们试着来解析一下。

3.1 设计重在平衡

这一点我们从软件设计的目标可以窥得一斑,软件设计是研发过程的中间环节,最终是为了更好、更快、更经济地实现软件需求,而在有限的时间、空间、人力、财力等资源条件下,质量、时间、成本三者本身就存在相互制约的关系。所以,软件设计就需要在尽可能满足多个要求的前提下根据实际情况进行权衡,而这就很有艺术性了,可以说,设计就是平衡的“艺术”

质量、时间、成本的制约关系

3.2 设计见仁见智

俗话说:“条条大路通罗马”,软件设计也是这样,解决方案有很多,一千个人眼中就有一千个哈姆雷特,没有标准答案,甚至不存在最优解。当然,软件设计也适用另外一句话,那就是“英雄所见略同”,好的设计方案缺点不会特别明显,而且还是有一定的趋同性的,容易受到多数人的认可。


新国标红绿灯

4. 软件设计的重心

相对来说,软件设计中最不好控制的应该是成本,这是绝大多数软件项目会面对的问题。软件研发是智力为主的活动,智力投入不足时,就会冒出来很多需要体力完成的任务,体力劳动量就可能呈几何级数飙升,而智力和体力目前都是由人来输出的,而人的成本也会越来越高,所以软件研发过程,尤其是软件设计,重心就是对成本的控制
研究显示,软件生命周期中,最大的成本就是后期维护的成本,可以占到50%以上。而软件维护、新特性的增加,主要的工作就是对已有代码的修改。
已有代码修改的难易程度,直接影响着软件维护成本,进而影响软件整体成本

软件生命周期成本比例


因而,
降低代码复杂度,就成为软件设计及实现过程中必须考虑的重要事项。

5. 处理设计中的复杂度

5.1 复杂性的根源

软件本身是方便生产、生活的工具。在当前人工智能发展的阶段,还不能主要依赖软件来制造软件,代码主要靠人来识读和编写。因此,代码的复杂度,就是相对于人的,人容易理解和使用的代码就是简单的,否则就是复杂的,要通过研究人的认知和行为规律,来控制代码的复杂度。
根据心理学家研究,人的工作记忆能力与短时记忆能力有关,大概是7±2个信息块,更接近于4-5个信息块。工作记忆能力又进一步影响到注意力和认知能力,而这或许是人在理解过多嵌套、分支和关系时表现出艰难的原因。而那种符合习惯,或者表现一致的设计则更容易理解,可能与需要较少的工作记忆单元有关。
除了认知方面,复杂性还表现在行动方面,主要包括很难开始、很难进行和很难结束三种情形。比如由于信息缺失或不清导致的无从下手,由于修改点分散导致的难于修改,由于依赖混乱导致的循环修改等。

5.2 降低复杂度的原则

根据复杂性的根源,降低复杂度的核心在于确保需要同时处理的信息少量、清晰、明确

5.3 降低复杂度的方法

大型软件都是一步一步“长”起来的,而软件的复杂性也是经年累月集聚起来的。


软件复杂度的产生


为此,从动态的角度来看,降低软件复杂度要避免“战术编程”,避免“破窗”,做好每次设计,及时重构,及时还清技术债务。

而静态地来看,为降低复杂度,每次设计要做到:

  • 信息内聚
    为了更好地理解设计,相关信息需要清晰、完整和内聚,避免需要额外的步骤才能补齐信息。代码是给人看的,代码要说人话,要能够“自说明”,包括变量、方法的命名。代码注释要出现在合适的位置,用来说明“为什么”,只保留必要的注释。
  • 保持一致
    符合认知习惯的东西,总是容易被人理解和使用。产品设计时,经常运用这一点。软件设计也是一样,只不过“产品”的“用户”变成了开发人员。设计时,需要尽量按照认知习惯来进行抽象和建模,使用业务领域通用语言,做到始终、到处保持一致,避免随意“发明”新的概念,以降低认知难度。具体到设计开发中,就是要尽量使用行业通用的架构、模式,尽量使用业务领域通用的术语,并保持一致性、一惯性。常说的“约定大于配置”,也是基于这个思想,避免增加额外的认知和行为负荷。
  • 恰当抽象
    抽象用于简化问题,基于特定目的,从使用的角度出发,在恰当的层次对相关事物进行抽象,仅提取必要的信息,隐藏或屏蔽无关信息和具体细节,能够很好地起到简化信息的作用。开发中,要设计接口简单而功能强大的模块或组件,即所谓的“深模块”,让组件更易理解和使用。
  • 分而治之
    众所周知,解决复杂问题的首要方法就是分而治之。这个方法也可以平移到软件设计中。在软件设计时,注意区分技术和业务,注意区分业务和应用,注意区分通用与专用,可以根据领域、职责将复杂系统拆分为在数量和关系上适当的层次、模块,避免需要同时关注的信息过多、过杂。这里会用到常说的“高内聚、低耦合”原则,控制拆分数量的同时,避免产生过多或过于复杂的关系。模块或分层内部也需要将自己的事情处理好,包括异常情况,避免内部概念污染扩散到外部层次或模块。
  • 软件设计实质就是对信息和变化的管理

    解决复杂性(治信息,隔变化)

    6. 软件设计的困惑

    人常说:“明白了很多大道理,却依然过不好这一生”。设计也是这样,我们看了很多文章,学了很多设计模式和方法,在设计时仍然有很多困惑,最常见的就是面临多个方案而无法抉择,不能确定选哪一个比较好。这时候,其实应该回到设计的“初心”上来,回溯一下设计的目标,看哪个方案更符合目标,做好这思考的“最后一公里”。

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2021年4月6日
    下一篇 2021年4月6日

    相关推荐