6.5 逐步拆解架构设计
需求驱动设计
有这样的一句话:不以结婚为目的的谈恋爱是耍流氓!
这句话与软件设计有什么关系呢?颇有关系呢!由于有另外这样的一句话:不以解决需求为目的软件设计就是耍流氓!
因此若是不想被人家说你耍流氓,你须要了解需求,须要“需求驱动”地思考设计问题。
前文咱们从需求中发现了四个设计点,一块儿来回顾一下:
1)用例图中提到,员工能够经过移动设备提出请假或外出申请,领导能够及时收到审批的提醒。那么咱们应该如何设计“即时了解”和“及时收到提醒”呢?解决方案可能有:短信提醒、邮件提醒、或者二者同时提醒。
2)需求中要求员工能够经过移动设备提出申请,领导也能够经过移动设备完成审批?咱们要思考,为何须要移动设备完成这些工做呢?什么状况下才须要经过移动设备完成这些工做呢?咱们的解决方案是怎样呢?经过短信、手机上网,仍是经过手机的APP来搞定?
3)请假申请和审批流程,跟流程相关的均可以扯到“工做流”。工做流能够是一个很“恐怖”的话题,你打算作一个"死"的工做流,“半死不活”的工做流,仍是“全活”的工做流呢?你打算从零开始作,仍是买一个工做流引擎呢?
4)权限要作成重用已是有必定难度的,同时还须要考虑与工做流的结合,还要考虑工做流也能够作成重用,难度很高啊!那到底要不要考虑作成重用,而且权限和工做流能结合起来呢?
补充说明一下工做流:
1)死的工做流:就是代码写死的(hard code),数据库设计也是死的,流程或表单有任何变化,均可能须要改代码和数据库设计。
2)半死不活的工做流:部分地方写死,部分地方是灵活的,能适应部分需求变化。
3)全活的工做流:代码和数据库设计等都是灵活的,能基本适应流程及表单的变化,不须要修改代码或数据库设计,只要配置一下就能够搞定。
没有任何工做流技术积累的状况下,要作到“全活的工做流”是很高难度的,通常不要在当前项目中就定下这样的设计目标,基本是实现不了的。能够分阶段来作,先写“死”,而后“半死不活”,最后才追求“全活”。
初步架构设计(第一层拆解)
咱们再次回顾一下,什么才是优秀的设计?
我在前文中提到,一个优秀的设计应该具有如下特色:
1)优秀的设计都是需求驱动的,不熟悉需求就作出来的设计是不靠谱的;
2)优秀的设计应该是当前团队能理解能实现的,太超前的设计项目团队作不出来,这个设计只能是摆设;
3)优秀的设计应充分考虑当前各类限制条件,适当作出平衡,能保证达成项目的目标:
4)优秀的设计能尽可能下降项目的总体工做量,让整个项目更加可控。框架
咱们尝试一下,尽可能按上述标准来完成这个设计吧!数据库设计
我打算用 .net(开发语言采用 C#) 及 SQLServer 来开发这个系统。
你可能会问,为何你选择这个开发语言和数据库?这些不是须要论证,须要作方案选择的吗?
咱们不是搞理论或学术研究,一个真实项目的状况是这样的:你接手项目时合同已经签下来,合同中会规定用什么技术框架的,包括开发语言与数据库,通常不会不定下来的。而定下来的技术框架,通常就是大家公司最熟悉的那种,而你接手这个项目,通常是熟悉这个技术框架的。公司不会这么傻,选一个本身公司一点都不熟悉的技术框架来完成项目,客户更加不会这么傻选一个不懂这个技术架构的软件公司,你的上司也不会这么傻找不熟悉这个技术架构的你来负责这个项目的设计。
一个系统到底用.net好一点,java好一点,PHP好一点?这些其实没有定论的,通常来讲就是你熟悉哪一个就用哪一个!哪一个你最有经验最有成功案例就用哪一个!针对具体一个项目作架构设计时,不能脱离具体的技术框架,要先肯定你的开发语言、数据库种类等。架构设计要从物理设计的深度来思考,而不能仅仅是理论设计或者是逻辑上的设计,不然又会犯了太空洞的毛病(即“放之四海而皆准”的毛病)。
如下是初步的架构设计,这个设计并非怎样“惊天地泣鬼神”,仅仅是我以为咱们能作到的也能应对需求的一个设计。
图6.6 初步的架构设计
图中标记出来的一、二、三、4,分别对应对前面的设计关注点一、二、三、4。此图对设计关注点一、2考虑得稍微具体一点,而对于设计关注点三、4仅仅是一个初步的考虑,由于当时咱们工做流的技术积累还比较初级。
须要特别说明的:请留意“智能手机”这个客户端,图中写的是操做系统用WindowsMoble,这是一个之前的设计,在如今看来是不合适的,如今用这种操做系统的手机几乎不存在了。需求中提到要求使用移动设备完成相关工做,那么咱们就须要思考是什么移动设备呢?移动设备上须要什么操做系统?须要安装什么软件等等?这些咱们都须要考虑。
小结一下进行初步架构设计的要点:
1)咱们的系统大部分会涉及到多个客户端及服务器,咱们须要思考咱们的系统须要怎样的客户端及服务器,思考这些设备上面须要安装怎样的操做系统、平台、软件等,思考这些设备须要怎样的硬件配置,如CPU、内存、硬盘大小等等。
2)咱们须要思考这些客户端及服务器之间的物理联系方式,例如:是局域网方式、互联网,仍是二者都支持?是HTTP或是HTTPS?等等。
3)这些设备上咱们须要开发什么软件、数据库等?例如:图6.6中须要咱们须要开发的东西有:Web Application、工做流定义用的客户端软件、三个数据库。架构设计其实就是划分系统的各部分及各部分的关系,这些内容其实就是咱们整个系统的第一次的各部分的划分,而各部分的关系咱们能够经过图6.6大体能够了解。
继续深刻拆解(第二层拆解)
图6.6已经从硬件配置、软件各部分的划分、数据库的规划等方面描述了本系统的初步架构,固然这个架构仍是太粗了,咱们还须要继续深刻思考,请看下图:
图6.7 架构设计的进一步思考
这个系统至少有5个须要咱们开发的部分,每个部分都须要更进一步深化设计,下面咱们以Web Application为例子,继续深刻设计!请看下图:
图6.8 Web Application的设计
咱们规划 Web Application 的内部架构时,除了考虑内部各部分之间的关系,也须要考虑内部所划分出来的各部分,有哪些是须要和外部交互的?图6.6中表示的各部分关系还比较粗,咱们还须要继续细化,请看下图:
图6.9 系统各部分的关系
当咱们逐步细化设计的时候,咱们极可能会发现以前初步架构设计不合理的或遗漏的地方等等,留意图6.9中红色的部分,这是以前没有画进去的内容。这个图已经更进一步细化设计了,但咱们仍然有不少问题未解决,请看下图:
图6.10 更多的更具体的设计问题
图6.10与图6.9的区别就是多了黄色的部分,请思考这三个问题:
1)权限设置的UI如何考虑?
用户管理、权限管理的UI可考虑设计成可重用的。
界面能够是独立的,也能够“嵌入”到别的系统中。
2)工做流如何设计?
还须要对工做流进行进一步的抽象。
考虑清楚工做流的对外接口。
考虑清楚数据库设计。
3)图形定义客户端软件如何设计?
图形平台自主开发,仍是利用第三方的?
数据如何保存到DB中?
除了上述这些问题和思考,还会有更多的其余问题,软件设计是充满挑战的工做!
设计初期的问题可能比较朦胧比较大,但随着设计的深刻,问题会愈来愈多,问题也会愈来愈具体。有时候你会以为怎么越深刻设计,发现的问题越多,这是正常现象,并且是好事!若是没有发现问题,这每每不是真的没有问题了,而是咱们不具有发现问题的能力了,这是至关可怕的,要当心留意不可轻敌噢!
图6.6后咱们连续进行了多步的设计拆解,这里小结一下:
1)系统须要开发什么软件和数据库等,这些是第一次对系统各部分的拆分,姑且这叫”第一层的拆解“,接下来须要继续拆解。
2)继续拆解时可参考分层架构,但须要拆分得更加具体,不要犯”放之四海而皆准“的毛病。这个层次的拆解,姑且叫“第二层的拆解”。
3)除了规划好内部各部分的关系,还须要规划内部的各部分与外部之间的关系。
4)在拆解的过程当中,问题会愈来愈多,也会愈来愈细,这是正常现象,也是好现象。
5)拆解过程当中也可能会发现以前初步架构设计中不合理或遗漏的地方,请立刻调整;有时候甚至会发现以前的设计彻底不对,那么就要有勇气推翻重作。
6)“第二层的的拆解”结果有多是组件(Component)、代码包、某个分层等等,多是“物理分拆”也多是“逻辑分拆”。那么“第二层的拆解”要多细才合适呢?其实很难有固定的标准,给一个简单标准做为参考:若是再拆解下去下一步的拆解就到类了,那么就能够认为目前的拆解粒度比较合适了。细化到类的拆解,能够在模块设计(详细设计)中再进一步考虑。
说明一下“物理分拆”和“逻辑分拆”:
物理分拆:物理分拆就是物理上是独立的部分,有多是exe、dll、数据库文件等。图6.6中将系统分拆为5部分,分别是Web Application、流程定义用的客户端软件以及三个数据库,这就是物理分拆;咱们对Web Applicationi继续分拆时,图6.8中的日历控件是物理分拆,这个控件将经过二进制的方式供程序其余部分调用,而这个控件未来也能够供其余系统使用。
逻辑分拆:代码包、某个分层这些每每是逻辑分拆,物理上它们不会编译成单独的一部分,而是被总体编译进软件当中。
“第二层拆解”的目的除了更加方便咱们设计出系统,另一个重要目的就是作系统的重用设计。若是是“物理分拆”,就能够作到二进制重用;若是是“逻辑分拆”,那么只能作到源代码重用。这些重用不只仅为当前软件服务,还能够为未来及其余软件服务。
6.6 分布式系统与单机系统的架构设计
分布式系统可能有不少定义,有些资料可能也说得比较炫,文章这里提出这个说法不是用来“抛书包”的,这里也顺便说明一下:本文中提出的一些概念(例如:第一层拆解、第二层拆解、物理分拆、逻辑分拆)是为了更加方便说明问题而已,你们没有必要去互联网上搜索这些名词的定义。
咱们开发的东西只须要安装在一台电脑上,这个软件就能工做,这就是单机软件,例如Office软件、Photoshop软件等;但分布式系统每每须要咱们在多台设备上部署,各部分须要联调后,整个系统才能正常工做。
文中用到的案例是分布式系统,分布式系统如何作架构设计,相信你已经有一些体会了。单机系统的架构设计看上去彷佛更简单一点,由于它不须要作“第一层拆解”,直接就是“第二层拆解”。其实不必定的,由于单机系统的“第二层拆解”每每是很复杂的,单机系统每每有特殊的高科技的算法、有独特数据存储格式等等,你能够设想一下,你能完成Office的架构设计吗?还有Photoshop的架构设计?
6.7 架构设计小结
架构设计是高难度、高技术含量的活,我以为很难写出一本秘籍,你看了后就能应对大部分软件的架构设计。若是咱们不精通业务,不精通技术,没有丰富的设计经验,不少设计咱们将会一筹莫展。
小结一下分布式系统的架构设计要点,单机系统也能够参考:
1)咱们的系统大部分会涉及到多个客户端及服务器,咱们须要思考咱们的系统须要怎样的客户端及服务器,思考这些设备上面须要安装怎样的操做系统、平台、软件等,思考这些设备须要怎样的硬件配置,如CPU、内存、硬盘大小等等。
2)咱们须要思考这些客户端及服务器之间的物理联系方式,例如:是局域网方式、互联网,仍是二者都支持?是HTTP或是HTTPS?等等。
4)思考系统须要开发什么软件和数据库等,这些是第一次对系统各部分的拆分,姑且这叫”第一层的拆解“。
5)继续拆解时可参考分层架构,但须要拆分得更加具体,不要犯”放之四海而皆准“的毛病。这个层次的拆解,姑且叫“第二层的拆解”。
6)除了规划好内部各部分的关系,还须要规划内部的各部分与外部之间的关系。
7)在拆解的过程当中,问题会愈来愈多,也会愈来愈细,这是正常现象,也是好现象。
8)拆解过程当中也可能会发现以前初步架构设计中不合理或遗漏的地方,请立刻调整;有时候甚至会发现以前的设计彻底不对,那么就要有勇气推翻重作。
9)“第二层的的拆解”结果有多是组件(Component)、代码包、某个分层等等,多是“物理分拆”也多是“逻辑分拆”。那么“第二层的拆解”要多细才合适呢?其实很难有固定的标准,给一个简单标准做为参考:若是再拆解下去下一步的拆解就到类了,那么就能够认为目前的拆解粒度比较合适了。细化到类的拆解,能够在模块设计(详细设计)中再进一步考虑。
软件架构设计博大精深,上述仅仅是一些规律的简单总结,但愿对你能有一点点帮助。
本文是系列文章的其中一篇,要作软件设计师一点都不简单啊,请留意后续文章!分布式
若是本文对你有帮助,麻烦点一下“推荐”啦,谢谢!spa
做者:张传波操作系统
创新工场创业课堂(敏捷课程)讲师
软件研发管理资深顾问
CMMI首席专家
《火球——UML大战需求分析》做者
软件知识原创基地创办人