软件设计是怎样炼成的(6)——打造系统的底蕴(数据库设计)(下篇)
摘要:
数据库是系统的根基,如果需求变更导致你要经常修改数据库的字段,甚至需要修改表及表关系,相信多折腾几次谁都受不了!因为数据库结构的变化,不仅仅是数据库本身的变更,实体类、数据操作层、逻辑层和表现层的代码都需要改。更麻烦的是数据库中如果已经存在大量的旧数据时,这些旧数据是不会“自动”适应新的数据库结构的,你需要想办法来“升级”这些旧数据。本文为你分享如何打造好系统的根基——做好数据库设计!文章太长,分成上下两篇了,此乃下篇。
大纲:
1.什么是优秀的设计?
2.优秀的设计能节省项目工作量
3.优秀设计从分析需求开始
4.软件系统不是木桶型的
5.软件设计的“大道理”
6.规划系统骨架——架构设计
7.打造系统的底蕴——数据库设计
8.细节决定成败——详细设计
9.用户感觉好才是真的好——用户体验设计
10.持续提升设计水平
本文章是系列文章之一,如果你还没有看过之前的文章,建议先看完前面的文章再看本篇,这样效果更好。
7.打造系统的底蕴——数据库设计
7.4 考勤系统的业务建模及数据库设计
学生选课系统这个案例比较简单,主要是帮助大家理解”业务概念模型驱动数据库设计“。接下来我们继续用”考勤系统“这个例子为你分享,我的主要目的有:
1)对考勤系统进行行为建模;
2)通过另外一个例子再次体会如何用类图分析业务概念模型;
3)根据业务概念模型,同时考虑到我们的现实情况,我们要做一个“老土”的数据库设计;
4)深挖业务概念模型,做一个“高端大气”的数据库设计。
本小节为你分享第1、2、3点。
这个考勤系统的需求请参考前面的文章,如果忘记了一定要重新看看噢!
你可以会发现,前面的文章没有详细描述请假(外出)的审批流程,下面我们通过一个图来看看这个流程吧,这个图就是业务行为建模的其中一个结果。
![](http://images0.cnblogs.com/blog/119077/201402/261617570825958.jpg)
图7.6 请假审批流程活动图
了解这个流程后,我们将会对业务概念模型有更加清晰的认识,下面直接上两个业务建模的图:
![](http://images0.cnblogs.com/blog/119077/201402/261618187121931.jpg)
图7.7 考勤系统的业务概念建模1
![](http://images0.cnblogs.com/blog/119077/201402/261618344078358.jpg)
图7.8 考勤系统的业务概念建模2
上面两个图结合一起看才是完整的业务建模,因为一张图太大可能会显示不下,或者显示出来不好看,所以才拆分成两张图。
根据上述业务建模,如何来设计数据库呢?如果照搬学生考勤系统的做法,那么一个类至少要对应一个数据表,这样设计的话似乎有点麻烦,后续写起代码来也可能挺麻烦的。我们要思考这个系统的主要需求是什么?这个系统主要是围绕请假(外出)的审批流程进行的,其实就是一个简单的工作流,我们要解决提出申请以及多个层次的审批问题。现实项目中进度压力是很大的,也会受制于各种限制条件,所以能解决需要当中主要矛盾的设计就是一个好设计,所以我有这样的一个老土的设计,能满足需求,实现起来也比较简单。请看下面的两个图,节选了部分的数据库设计。
![](http://images0.cnblogs.com/blog/119077/201402/261618591139875.jpg)
图7.9 考勤系统的数据库设计1
![](http://images0.cnblogs.com/blog/119077/201402/261619447867995.jpg)
图7.10 考勤系统的数据库设计2
这个设计相当老土,本来应该拆分为多张表的全部弄到一张表去:
1)当提出请假申请时,请假申请表就多了一条记录,这条记录审批相关的字段全部都是空的;
2)当去到某个审批环节时,该申请记录只需要更新相应的字段就行了。
这个程序的代码写起来也比较简单,例如:表现层不需要针对不同的流程环节设计不同的界面,直接可以通过一个界面搞定,当然还要写一堆 If Else 或 Switch Case。表现层的代码思路如下图:
![](http://images0.cnblogs.com/blog/119077/201402/261620030859651.jpg)
7.11 考勤系统的表现层代码思路
当员工提出请假申请时,他只能看到1这部分的内容,2、3、4部分隐藏;当部门经理审批申请时,1部分只读,2部分可编辑,3、4部分隐藏,副总和总经理审批时也进行类似的处理。
数据库设计不能单纯仅仅从数据库的角度来考虑,还需要整体平衡这个项目的工作量,一般来说能解决需求当中的主要矛盾,能让整个开发工作量降下来,并且是项目团队有能力做到的设计,这样的数据库设计及软件设计才是好的设计。
考勤系统的业务建模及数据库设计,也说明了这样的最佳实践:
1)业务结构建模和行为建模是很有必要的,业务建模这一步可以多深入一些,不要因为项目进度紧而压缩你的时间,这里的时间投入所带来的回报是超值的;
2)业务建模让我们对需求的理解更深,让我们的数据库设计及软件设计”进可攻退可守“;
3)遇到进度压力及各种限制条件时,你不一定非要照这个业务模型来设计你的数据库和代码,你可以退一步,用一个”老土“的数据库设计及程序设计来解决问题;
4)你也可以采取更加进取的设计策略,这点下一小节为你分享。
7.5 业务建模更上一层楼,打造更具弹性的数据库设计
本小节为你分享前文提到的第 4 个目标:深挖业务概念模型,做一个“高端大气”的数据库设计。但这个目标实在太“伟大”了,这里能仅为你分享开始的一部分,后续有机会我再发文章分享更多内容。
我们有更多的思考:如果请假(外出)审批流程改变了,例如增加了审批环节,怎么办?按照前面的“老土”设计的话就麻烦了,我们需要增加“请假申请表”的字段,而表现层的代码也需要修改,需要更多的If Else。
当然我们可能还有一个更好的处理办法,就是认为这是需求变更,对客户说:no money no talk(没有钱没商量)。只要前期我们的业务分析足够到位,将流程图、业务概念图等全部画出来,并且跟客户确认好了,客户就不能赖账了,增加审批环节,这明显就是需求变更嘛,是需要工作量,需要付钱滴!但是我们为什么不能将程序做得更有弹性呢?为什么不能做一个“全活”的工作流呢?这样我们的软件将会更有竞争力,帮助我们赚到更多的钱。
前文的文章提到的工作流,分为三种层次:
1)死的工作流:就是代码写死的(hard code),数据库设计也是死的,流程或表单有任何变化,都可能需要改代码和数据库设计。
2)半死不活的工作流:部分地方写死,部分地方是灵活的,能适应部分需求变化。
3)全活的工作流:代码和数据库设计等都是灵活的,能基本适应流程及表单的变化,不需要修改代码或数据库设计,只要配置一下就可以搞定。
前面这个老土的设计,是属于那种一种层次呢?
我都不好意思说了了,这是“死的工作流”,弹性最差的!流程稍微改变,就要到处修改,包括修改数据库设计和代码。
下面我们尝试一下做“活的工作流”,我们需要再进一步分析业务模型,找出流程的规律,针对规律来设计数据库和软件!
![](http://images0.cnblogs.com/blog/119077/201402/261620169258776.jpg)
图7.12 考勤系统业务概念模型的深入挖掘
上图红色虚线框框里面的内容就是规律,而且其他部分可以看成是这种规律的一个“实例”。
这个图揭示了这样的规律:
1)从提出申请开始,后续的审批其实就是一个”审批链”;
2)“申请”对应一个“首次审批”,“首次审批”后续是“下一个审批”;
3)对应某一个“审批”来说,如果它不是“首次审批”,它对应一个“上一个审批”。
如果数据库及程序能针对这样的规律进行设计,那么只要是符合这个规律的情况,系统都可以适应,这样就不怕审批流程的变化了!
图7.12 可能有点难度,如果没有应用类图分析业务的经验,会更加难理解此图,但这仅仅是挑战的开始!当我们需要打造更具弹性的系统的时候,我们面临两大挑战:
1)透视需求发现需求本质的能力,建立更深层次的业务模型;
2)根据第1)点的业务模型,设计出相应的数据库设计及软件设计。
这两大挑战都是难度很高的,图 7.12 仅仅是业务模型进一步深挖的开始,打造“活的工作流”难度是很大的,将来有机会再分享更多文章。
7.6 数据库设计小结
数据库设计的好坏决定了系统的底蕴,无论是“老土”的设计还是“高端大气”的设计,都是为项目的目标服务的。
一般来说我们应该达到以下基本要求:
1)意识上要重视数据库设计,数据库设计上的时间投资是超值的;
2)良好的业务建模(包括结构建模和行为建模)是良好数据库设计的基础,并且可以让你在后续工作中“进可攻退可守”;
3)在业务概念模型的基础上搭建数据库,你可以采用类似学生选课系统的数据库设计方法(业务实体类与数据表一一对应),也可以采用考勤系统的“老土”设计方法(合并业务实体类到一个表中)。
当条件成熟时,我们可以考虑进一步提升我们的业务深挖能力及弹性设计的能力,让我们的软件更好卖,让我们可以赚取更高的薪金!
本文是系列文章的其中一篇,要做软件设计师一点都不简单啊,请留意后续文章!
如果本文对你有帮助,麻烦点一下“推荐”啦,谢谢!
作者:张传波
创新工场创业课堂(敏捷课程)讲师
软件研发管理资深顾问
CMMI首席专家
《火球——UML大战需求分析》作者
软件知识原创基地创办人