前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何开始软件设计 -- 浅议软件设计中的方法论

如何开始软件设计 -- 浅议软件设计中的方法论

原创
作者头像
syw
发布2018-07-25 20:28:43
1.1K0
发布2018-07-25 20:28:43
举报
文章被收录于专栏:程序员笔录程序员笔录

前言

当我们开始构建一个全新的系统时,常常是又喜又愁:喜的是这下终于有机会大展身手,创造自己的作品,不用再去做修修补补的事情;愁的是万事开头难,千头万绪,不知从何着手。诸君请先不要发愁,听我排解排解。

解决具体问题的方法虽各不相同,但获得问题解决方法的方法却是相通的,探求方法之方法便是哲学上所谓的“方法论”。方法论如同远方高耸的灯塔,指引着航船找到通向港口的航线。软件开发是一项创造性活动,一个产品在开发中的各个阶段,需要我们逐步的去认识问题,其间存在大量的抉择和取舍,需要可观的创造力与判断力。这些认识活动,包括需求分析、业务建模、关键技术调研、系统架构设计等,当我们将问题的方方面面有个比较清晰的认识后,解决方法自然是水到渠成、跃然纸上。那么有哪些方法可以指导我们认识软件开发过程中的种种问题,以便找到可行的解决方案,顺利完成代码构建呢?

从本质特性出发

亚里士多德最早系统性研究事物类属,他提出本质主义的哲学观点:事物属性可分为本质属性(essential)和偶然属性(accidental),本质属性是事物固有的属性,它不会因为外部环境的改变而变化,固有属性决定事物的类属,具备相同固有属性的个体是同一类事物;偶然属性是事物碰巧具有的属性,它可能会改变或者消失,它不影响事物的类属。亚里士多德以人举例:譬如人类基本上是理性的—具备理性思维是人类的本质属性,人有两条腿是偶然,实际上某个人失去一条腿后,他还是属于人类,但如果没有理智,或许会被当作野兽或者其它物种。哲学家对人类的定义可能过于严格,我们再看一个现代点的例子,譬如汽车,必须具备引擎、车轮、车门等必要组成部分,缺乏任何一样,它便不是真正意义上可用的汽车,但无论车门颜色、轮子大小等等这细节怎样,它还是一辆车。这里拥有引擎、车轮、车门是汽车本质属性,车门颜色、车轮大小是偶然属性。偶然属性附属的、任意的、非必须的。

同样,我们也应基于目标软件本质属性开始设计。那么什么是软件的本质属性呢?一个原则,不可或缺的功能特性。正如程序的定义是数据结构+算法,软件的本质属性也主要从业务数据与业务流程两方面去分析,这些特性包括:

  1. 核心数据的组成、形式与规模;
  2. 核心业务流程执行步骤与并发规模;

通过对业务本质特性的分析,我们便可以进行软件层面的概要设计,所谓概要设计,便是在软件层面对业务建立概要模型。这包括:

  1. 数据建模:建立业务数据在计算机世界的表达方式,并识别各类数据的访问特性(读写特性,访问频率等);
  2. 模块分解:将数据操作以及业务流程划分到多个物理模块中,模块是业务逻辑承载的实体,模块化是将复杂问题分而治之的基本手段;
  3. 接口设计:模块间交互的方式,以协调各模块职能,共同完成业务流程的执行;
  4. 运行时设计:运行时状态定义,标识数据访问与业务流程的并发特性;

以上均是对业务、软件的本质特性进行分析,并不涉及编程语言、数据库、第三方组件等实现层面的问题,这些属于偶然属性的范畴,不管具体的实现方案如何,系统的本质特性还是那些。我们应该根据项目的本质特性和开发团队的实际情况,选择合适的解决方案。

在实现层面,必然会引入一定的偶然属性。软件本质特性所蕴含的复杂性称之为本质复杂性,这是实现软件所必须克服的。其它由偶然属性引入复杂性称之为偶然复杂性,随着软件产业的发展,偶然复杂性已经大为降低,譬如操作系统、编译器已经非常稳定可靠,有更丰富的编程语言,更多高质量的组件和服务软件可以选择。但我们仍然需要非常小心,避免引入不可控的偶然复杂性,譬如引入过于庞大的框架组件,可能带来昂贵的学习与维护成本,甚至可能会因框架本身的缺陷可能会制约软件的发展,那就更是得不偿失了。能否有效控制复杂性,可以说是能否保障软件顺利完成开发的首要问题,Steve McConnell 在其经典著作《代码大全》中非常详细透彻的探讨了这个问题,非常值得一读。

小结

分析系统,首先是识别业务本质特性(数据,流程),进而在软件层面构建概要模型。在确定具体的编程方案时,应聚焦于本质特性,控制好软件构建的复杂性,避免由具体解决方案所引入的偶然复杂性失控。

开发原型代码

在项目开始,可能会出现两类相反的极端情况:

  1. 未经认真考虑,便开始埋头编码;
  2. 期望构思出一个终极方案,总是对现有的设计不满意,迟迟启动不了编码;

第一种是鲁莽,第二种则过于谨慎,都不利于我们建立对手头项目的正确认识,不利于开个好头。在社会学中,有“邪恶问题(Wicked Problem)”的概念,有先贤指出软件设计也是一个“邪恶问题”,所谓“邪恶问题”是这样的问题:即只有已经解决一遍或者部分解决之后,才能真正认识清楚的问题。这确实一针见血的说明了软件设计的特点:不论开始我们对系统有多么周全的考虑,但在实际开发过程中,以及后续系统运行过程中,总是会出现我们不曾预料到的问题,如果我们的前期设计缺乏弹性,这些问题可能还会彻底推翻现有的设计方案。盲目开始编程,因为对问题缺乏必要的认识或者根本就是搞错了问题,终归会使项目陷入困顿,浪费人力和时间。探求终极方案,因为始终未曾去解决或者部分解决问题,很难获得真知,这样的探求无异于缘木求鱼,难有成效。这就像是困在两堆干草之间的比亚当之驴,不先去吃一口,怎么知道不能吃呢?突破困局的办法是开发原型代码,这些代码不会作为正式的产品代码之用,我们可以只聚焦于问题核心本身,省却枝蔓,用最小的代价先让部分逻辑实际运行起来,无论如何推理想象,也不可能有实际所见让人对事物的认识更深刻。这些原型程序可能会否定我们的设计,我们不得不重新探寻新的方案,但这只是付出了必须付出的代价,远远好于因为问题发现太晚而导致项目返工,有些时候,可能连返工的机会也没有。建立原型在科研和工程实践中普遍方法,想想看物理化学的理论发现怎能离开实验,每一款新车在设计的过程中都要制作各种模型车,每一栋大厦在破土动工前也需要制作模型,验证设计方案抗风、抗震能力。可能因为代码推到重来的成本是无形的,大家因而忽视了模型的作用。

小结

在构思解决方案的同时编写必要的原型程序,让部分业务逻辑尽早运行起来,可以让我们更深刻的认识问题,以便设计出真正可行的解决方案。系统设计如此重要,它直接解决定了系统能否实现以及付出的代价,方案合理,便成功了一多半。套用Alan Kay的名言:预测未来最好的方式是创造它,创造完美设计的最好方式是部分实现它。

以发展的眼光看问题

往往想一次性就设计出一个“完美的”系统,足够灵活、足够强大,可以支持今后可能才会用到的各种特性,可以支持业务规模的任何扩展。 这往往是徒劳的,对当下有碍,对今后也不一定有实际的用处,因为:

  1. 认识不准。千万、上亿级别用户规模与数万、数十万用户规模对技术的挑战可能完全不同,虽然也有很多业界的经验可以借鉴,但只有真实经历了系统规模增长的过程,对这种差异的理解才会比较准确。另外,未来产品特性的发展也不可能准确预计,当前付出的代价不一定有收益,甚至会妨碍今后需要的特性开发;
  2. 力量不够。一般来讲,在业务初始阶段,不会有太多人力物力的投入,开发团队面临尽早让产品上线的压力,以便更好捕捉用户需求、验证产品模型。应该以尽量简单的方式实现产品,而要支持更大用户规模,所面临的问题当然会更复杂,需要的投入会更多,与当下的目标冲突。

我们应该以发展的眼光看问题,当下的设计主要为满足当下真实的产品需求,不要过份预设今后的功能需求,以免增加不必要的负担。真正可伸缩可扩展的系统设计,不在于当下预设了多了功能特性,而在于系统要有演进发展的潜力,这赖于结构清晰的数据模型、职责分明的模块定义,系统耦合适度。所谓发展眼光看问题,就是要根据业务的发展来演进软件,而软件的演进又能支持业务发展到更大的规模。《程序员》杂志2013年6月刊的一篇文章:“从一扩展到无穷大:“架构艺术与工程实践的华尔兹 ——读 ‘Scaling Memcache at Facebook’有感”,对Facebook为应对业务规模的快速增长、从小到大建设Cache 系统的工程实践进行了剖析,很好的诠释了系统如何伴随业务的发展而自然地演进,看后相信会对大家有所启示。

小结

在设计系统时,我们应该以发展的眼光看问题,立足业务本质特性与于当前需求,定义客观合理的开发目标。对整体系统而言,绝不可存一劳永逸之幻想,好比给小孩买大码的鞋穿,貌似可以为今后省钱,但却不能让小孩现在穿着好好走路。

后记

一年之计在于春,一日之计在于晨,因为春天、早晨是规划的时节,规划得当,我们才能行之有效的去做事情。同样,项目开头的时间也是非常关键的,这时对系统本质特性认识是否准确,设计方案是否合理,决定了后面我们还能否愉快的编程,决定了产品最终可以达到质量水准的上限,以及实现成本。方法论是强大的武器,它能让我们形成正确的分析问题的思维模式,以不变应万变。面对新的项目,我们应该根据系统本质特性进行设计,管理好项目复杂性,避免偶然复杂性失控;可以用快速开发的原型程序来帮助认识问题、验证方案;同时应该发展的看问题、阶段性的去解决问题。如果您刚好要着手新系统的开发,刚好在起步的时候也有些踯躅,希望这篇文章能对您有所帮助。

参考文献

  1. Steve McConnell 著,金戈等译。《代码大全2》中文版。P73-80。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 从本质特性出发
  • 开发原型代码
  • 以发展的眼光看问题
  • 后记
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档