早些年,软件很简单的时候,不需要需求分析和架构设计,直接采用边写边改模型,也能做出来了。后来软件复杂了,就对程序员要求特别高了,所以早些年的软件开发,但是个人英雄注意盛行。比如张小龙一个人完成了 Foxmail,求伯君完成 WPS…
不过,那时候对普通程序员来说,去写这样复杂的系统,也是可望不可及的。再后来软件产品越发复杂之后,靠高手的开发模式也就不可行了。
软件需求越来越多,而高手又是稀缺资源,所以要解决的一个问题就是:让普通程序员也能参与其中,一起实现复杂系统,而不必依赖于很多精英。
要想实现让普通程序员也能实现复杂的软件系统,我们先看看什么样的是复杂的软件项目。复杂的软件项目,通常有两个特点:需求不明确或者技术复杂。
下面我们来分析一下为什么就导致技术复杂。技术复杂,主要体现在四个方面:
(1)需求让技术变复杂
(2)人员会让技术变复杂
(3)技术本身也是很复杂的
(4)要让软件稳定运行时复杂的
因为技术的这些复杂性,会导致软件开发变得很复杂,开发成本很高。而架构设计刚好可以在这些方面很好的解决技术复杂的问题
(1)首先,架构设计可以降低满足需求和需求变化的开发成本
(2)其次,架构设计可以帮助组织人员一起高效协作
(3)再次,架构设计可以帮助组织好各种技术
(4)最后,架构设计可以帮助保障服务稳定运行
总的来说,架构设计,就是通过组织人员和技术,低成本满足需求以及需求的变化,保障软件稳定高效运行。
究竟什么是架构设计呢?要说清楚这点,我们可以分别从目标和方法两个角度来看:
架构设计,已经有了很多成熟的方法。比如说:
这些架构设计的方法,其实都是基于工程领域分而治之的策略,本质上是将系统分拆,将人员分拆。但是光拆还不够,拆完了还得能拼回来,所以你要清楚架构设计的“道”。
架构设计的“道”,就是组织人员和技术把系统和团队拆分,并安排好切分后的排列关系,让拆分后的部分能通过约定好的协议相互通信,共同实现最终的结果
这很像乐高玩具,将一个个小的模块通过接口拼接在一起,搭成一个大的模型。只不过在程序中,换成了其他形式的接口,比如前后端通过REST这种协议交互,内部组件之间通过方法调用;在软件项目中,人员从大的开发团队被分拆成小组后,小组之间通过流程规范协作。
架构设计要做好,确实不是一个容易的事,需要大量的经验积累。但业界已经有了很多成熟的架构设计模式,我们不需要闭门造车,可以在理解清楚业务需求后,找到相近的架构设计,然后基于成熟的架构设计方案,进行改造,变成适合自己业务需求的架构。
接下来就以极客时间的服务端为例,来简要说明一下如何做架构设计。假设现在你要设计第一版本极客时间服务端的架构,只有专栏课程一个核心功能,目标用户访问量是日 PV 上万,峰值每秒 10 个左右访问,对稳定性要求高。那么,你该如何做呢?
架构设计,最基本的就是要能够满足业务需求,所以搞清楚需求是至关重要的一步。而产品需求,只有功能的描述,界面的交互,还需要进一步进行抽象。
一个常用的分析方法是分析用例,也就是了解主要用户校色和其使用的场景。
如果把极客时间的专栏课程功能画成用例图,大概如下所示:
从图上可以看出,有四种角色:编辑、专栏作者、未付费用户和付费用户。每个角色有其独特的功能,有些角色之间还有通用的功能。还需要注意的一点是,每个用户,都可能会通过不同的设备终端来使用这些功能:网站、安卓手机、iPhone 手机。
在了解清楚需求之后,就可以从业界成熟的架构设计模式中选取一个或者几个。当然,具体选择哪些架构设计模式,需要你根据平时的学习积累来做判断。到这个阶段,同时还要考虑使用的语言和框架。
极客时间服务端,主要包含两部分内容,一个是给手机客户端提供的 API 服务,还有就是网站需要的 Web 服务。第一个版本其实访问量并不大,我们完全可以把 API 服务和网站服务合并成一个服务。另外专栏的内容,文字内容涉及数据库的存储,同时音频涉及文件存储。
这其实是一个典型的网站架构,可以基于传统的分层架构来实现。分层架构按照水平方向将系统拆分成几个层,每层都有清晰的角色和分工,不需要关心其他层的细节
在选择好架构方案后,还需要考虑选择什么语言和开发框架。这部分选择需要根据团队情况和项目情况来综合评定。
比如说团队以 PHP 程序员为主,就没必要贸然选择 Java 作为开发语言;如果以 js 程序员为主,就可以考虑使用 Nodejs。因为这样的选择,能让团队不需要太多的学习成本。
在选择好成熟的架构设计方案后,可以基于方案,层层细化,逐步完善、调整和优化。
这类分层架构网站,部署也比较简单。为了减少运维成本,我们可以基于云服务设计部署架构,选购云数据库和文件存储,选购虚机作为网站服务器。
那么部署架构可以比较简单,如下图所示:
基本上这个架构就可以基本满足运行需求。但要做到稳定性高还不够,万一数据库挂了或者网站服务器挂了,都可能会让服务中断一段时间。
所以我们可以增加一台异地网站服务器和一个异地云数据库实例作为备份,这样一旦网站宕机或者数据库有问题,可以切换到备机,马上恢复访问。所以调整后架构如下:
按照分层架构的思路,我们可以把系统分成四层。
分层分好后,还需要基于前面的用例图,把相同的功能抽象出来,设计成模块,比如说留言相关的都放到留言的模块,文稿相关的都放到文稿模块。
最终的设计图大概会是这个样子:
在分层和分模块之后,就可以很好的对人员进行分工,可以把具体工作细分到某一层的某个模块。
在分层和分模块的设计完成后,就可以对 API 进行设计,对数据库进行表设计。这部分就不展开细讲了。
在技术方案完成后,还需要去验证方案是不是满足设计的目标,能否满足需求和未来需求的变化,能否保障软件有效的运行。
方案的验证时贯穿整个设计始终的,一个完整的架构设计方案,需要有多次的评审会议,充分收集各方面的反馈,反复修改后才能最终确定下来。
在第二、三步,可能会生成几个技术方案,这时候就需要做出一些技术上的决策。决策时,需要考虑清楚方案是否能低成本的完成软件需求的开发,同时能低成本的运行和维护该软件。还有你要考虑架构预期要满足多长时间的业务增长,比如说半年还是一年还是三年。
在架构设计确定后,就可以基于架构设计的结果大家一起分工协作了。架构设计并不是确定后就不修改了,在实际开发的过程中,还需要根据情况对架构进行优化和调整。
比如说实际运行的时候,发现 API 访问量很大,会拖慢网站访问速度,那我们就可以考虑把 API 和网站分拆开来,各自做成单独的服务,避免相互干扰。
架构设计,是为了控制软件项目中技术复杂的问题。架构设计,通过组织人员和技术,低成本满足需求以及需求的变化,保障软件稳定高效运行。
架构设计可以通过四个基本步骤:
通过良好的架构设计,可以有效降低开发难度和成本,让普通程序员也能实现复杂系统。