(1)——什么是优秀的设计?
某项目的设计文档评审会上,各路技术大牛进行了“热烈”的讨论,讨论的焦点是怎样的设计才漂亮!大家围绕着如何OO,如何高内聚低耦合,如何反转控制等话题进行了“热烈”的争论。照这样开下去,这个评审会岂不是变成了“神仙大会”!怎样的设计才叫优秀的设计呢?
1.什么是优秀的设计?
某项目的设计文档评审会上,各路技术大牛进行了“热烈”的讨论,讨论的焦点是怎样的设计才漂亮!大家围绕着如何OO,如何高内聚低耦合,如何反转控制等话题进行了“热烈”的争论。
你觉得以下标准可以成为“漂亮”设计的标准吗?
1)高效
2)可靠
3)易用
4)安全
5)可扩展
6)兼容性强
7)移植性强
……
如果每次设计文档评审,我们都采用上述标准来评审,你觉得这个设计评审会有效果吗?
当时我参加了这样的一个设计评审会,觉得气氛很不对,照这样开下去,这个评审会岂不是变成了“神仙大会”!
于是我问了两个问题:
1)谁能说说这个项目的主要需求?
2)这些需求,设计上是如何考虑实现的?
结果没有人能答上来!
我们从书本上看到的那些”通用“的设计标准,说得难听一点,就是废话!对实际的项目工作基本上没有实质用途!
请看下面4个例子,分别思考这4个案例的软件设计思路,你会发现上述“漂亮设计的标准”,真的是废话!
案例1:某项目要求在很短时间内完成,而且客户对系统的当前认识还是比较初步的,你打算怎样设计这个系统?
案例2:某软件公司接了一个“网页+数据库”类型的项目,这类项目已经做过多个,但这次的业务却是新的,你怎样考虑这个项目的设计?
案例3:某软件公司已经成功为n个医院做了管理系统,现在需要为一家新的大医院做类似这个系统,你会怎样考虑这个系统的设计?
案例4:你接到一个任务,要做一个即时战略游戏,目标是要在当前游戏市场找中杀出一条血路,你怎样考虑这个游戏的设计?
4个案例各有特点,分别代表了4种“典型”:
案例1:需求很朦胧,工期很紧,技术上基本上没有积累。
案例2:需求是新的,但可以重用“网页+数据库”的技术架构。
案例3:需求是类似的,技术架构也是类似的,相信你会直接重用之前的系统。
案例4:这是一个需要创意和高技术含量的游戏,而游戏软件的需求和技术都是充满挑战的。
上述4种情况,相信你采取的设计策略是不一样的,你可能会发现所谓的优秀设计没有固定的标准。
如果硬是要来一个优秀设计的标准呢?
我会这样说:就是做高性价比的设计!
一个优秀的设计应该具备以下特点:
1)优秀的设计都是需求驱动的,不熟悉需求就做出来的设计是不靠谱的;
2)优秀的设计应该是当前团队能理解能实现的,太超前的设计项目团队做不出来,这个设计只能是摆设;
3)优秀的设计应充分考虑当前各种限制条件,适当做出平衡,能保证达成项目的目标:
4)优秀的设计能尽量降低项目的整体工作量,让整个项目更加可控。
2.优秀的设计能节省项目工作量
关于软件设计的话题,如果脱离一些实际案例讨论的话,很容易变成空洞无力的学术讨论,所以本文将会列出很多案例供你参考。
设计案例:开发某线上社区网站
背景:某社区已经举办了多期沙龙活动,为了拓展沙龙的影响力,让更多朋友受益,树立良好品牌,将来实现盈利,有必要建立一个线上的社区网站。
该网站应有这样的功能:
1)发布各种活动信息。
2)发布业界新闻。
3)能开展线上沙龙活动,包括在线视频沙龙。
4)具备SNS社区,可汇聚人气。
5)每位会员有自己的博客,能维护自己的个人页面。
6)支持简体中文、繁体中文、英文三种语言随时切换。
7)支持全文搜索。
你打算如何设计上述系统呢?
你可能会问,有工期限制吗?
你说呢?真实项目一定会有工期限制的,这个项目你的工期只有1个月!
你可能会说:你当我是神仙啊,1个月有可能怎样死都死不出啊!
这个时候能帮助你的就是优秀的设计,优秀的设计有可能能让你用很少的工作量就做出来,优秀的设计也不一定需要你全部从零开发的,我们可以拿来主义!有不少开源软件是可以基本满足上述要求的,我们可以直接拿来用,这样你需要付出的工作量就少很多了。
我曾经用某开源软件做了这样的一个网站出来,但发现没有全文搜索功能,结果我想了一个“投机取巧”的办法,自己不写一句代码,直接利用谷歌的这个搜索功能“site:域名
关键字”,让谷歌帮我搞定全文搜索。当然这样做出来的效果还不是很完美,但至少我能在很短时间内能做出个大概啊,如果自己开发还不一定能做出这样的效果呢!
小结:
受工期限制、受能力限制等制约因素,十全十美的设计基本上是很难做到的,但如果因为赶工期而在软件设计上节省时间甚至是直接忽略这步,其实是得不偿失的。在软件设计上“节省”1小时,可能会让你将来多投入成倍的项目时间;越是工期紧,越需要冷静思考软件的设计,合适的设计能大大地降低项目工作量,让你后期的工作轻松很多。
(2)——优秀设计从分析需求开始
设计应该针对需求来做,这个大道理似乎人人都懂,但实际操作时往往就不是这样。所以我们也不说大道理,直接通过一个“很简单”的案例来体验一下优秀设计应该如何从分析需求开始,体验架构设计是如何全面考虑各种需求、项目的工期限制预算限制,还有项目组人员水平后做出来的。
3.优秀设计从分析需求开始
设计应该针对需求来做,这个大道理似乎人人都懂,但实际操作时往往就不是这样。所以我们
也不说大道理,直接通过一个“很简单”的案例来体验一下优秀设计应该如何从分析需求开始。
3.1 案例挑战:考勤系统的软件设计
某公司要做一个内部用的考勤系统,希望达成以下目标:
1)规范员工的上下班、请假、外出工作等行为。
2)方便计算员工的薪金。
3)方便管理各种带薪假期。
你如何考虑本系统的设计呢?
你可能会说:我靠,才三句话的需求,怎样做设计呢?
说得太好了!我们做软件设计的,第一步并不是直接去设计,而是分析需求!
3.2 如何分析需求?
当你接受一个项目的设计任务时,可能会遇到比较尴尬的情况,那就是需求有问题!
具体的情况可能有:
a)需求很简单,几句话或者是一页纸的需求。
b)需求很详细,可能有几十页甚至上百页,这些需求是招标书中提供的,或者是客户直接提供的。不要以为有这么多需求是好事,这些需求通常是前后有点矛盾、逻辑有点混乱,甚至是不知所云滴!
c)你们有专门的部门或者专职完成了需求工作,提供了一份需求文档。你也不要以为这是好事,因为很可能会出现这样的情况:需求文档的提供者认为自己写的需求文档很牛逼,水平很高;但负责实现的开发部门认为该文档质量太差,比方说:不考虑实现的可能性和难度,没有考虑到客户的真正需求等等。有时候甚至出现开发部门忽略掉需求部门,直接找客户重新调研,重新编写需求文档的情况。
上述三种情况一句话总结就是:需求的质量有问题!
我们需要重新分析一次需求,先从业务角度审视一次,然后再从软件设计的视角审视一次。通常我们需要按顺序思考以下问题:
1)什么人会使用这个系统?
2)不同的人将会使用这个系统的什么功能?
3)还有哪些不确定或不具体的需求点?
4)哪些需求对技术提出了怎样的要求?
5)系统的大致架构应该如何考虑?
下面开始我们看几个图,按顺序逐一思考一下上述的几个问题。本小节回答问题1、2,后面的小节回答其他问题。
1)什么人会使用这个系统?
不少技术人员分析需求时往往是技术的视角,当你问他系统有什么用户时,你可能得到的结果有两种:
a)没有什么用户啊,所有人都是用户,因为系统只需要配置一下权限,谁都可以用。
b)系统有两种用户,就是:用户和管理员。
我们从业务的角度来审视一下考勤系统的可能用户,请看下图:
图2.1 系统可能用户分析
此图列出了如下可能用户:
employee:员工
finance:财务
receptionist:前台
manager:经理
senior manager:高级经理
administrator:管理员
而上述用户还有这样的关系:finanace(财务)、receptionist(前台)、manager(经理)继承employee(员工);senior
manager(高级经理)继承manager(经理)。
用户之间的继承关系,是什么意思呢?
我们都知道代码中B类(子类)继承A类(父类),子类就具备了父类的特点。用户之间的继承关系是相同的意思,我们继续看看下图你就可以理解了。
下图将会回答这个问题:
2)不同的人将会使用这个系统的什么功能?
图2.2 系统的需求分析
图2.1和图2.2都是UML的用例图,两个图加在一起比较完整系统地表达了以下问题:
a)什么角色会用本系统?
b)这些角色通过本系统分别能干什么事情?
c)角色之间有可能会有继承关系,请留意父类能干的事情,子类也能干,例如:employee可以打卡,manager也可以打卡,尽管图2.2中manager没有直接与”打卡“相连,但图2.1中已经说明了manager继承employee。
UML是需求分析的有力工具,我的工作中很喜欢用UML。但你的工作中、你的需求文档中可能会没有UML图,不管你们是否用UML图,分析需求时都需要从业务的角度思考这些问题:
a)什么人(角色)会用这个系统?
b)这些人(角色)分别需要用系统的什么功能?
需求分析其实是一个负责的高难度的话题,回答上述两个问题仅仅是需求分析的第一步而已,我们还需要深入分析业务,包括业务流程、业务数据结构等等。如果之前的需求工作不到位,就需要我们立马开展软件设计工作,其实将会埋下很多地雷,后患无穷。关于需求分析的更多分享,请留意我的其他文章。
3.3 找出设计关注点
本小节我们回答这两个问题:
3)还有哪些不确定或不具体的需求点?
4)哪些需求对技术提出了怎样的要求?
软件设计师需要有敏锐的需求及设计触觉,看着图2.1和图2.2 嗅出一些问题,你能嗅出一些问题吗?
请看下图:
图2.3 系统的设计点分析
图2.3主要从设计的视角对需求再进行一次审视,以下是一些建议:
a)你需要更加深入思考需求,考虑到各种不同的业务场景和特殊情况,例如:领导不在公司时如何审批请假?
b)你需要思考需求的细节,例如:报表的具体形式?
c)你需要思考各种技术方案,例如:打卡数据的同步方案,财务软件是否要对接等等?
d)你要做出平衡,用合适的方案和尽量少的工作量来满足需求。
3.4 针对需求做初步的架构设计
本小节将会回答这个问题:
5)系统的大致架构应该如何考虑?
接下来你要做初步的架构设计了,架构设计是难度很高的事情,需要你全面考虑需求,考虑工期限制预算限制,考虑项目组人员的水平,而做出的一种平衡。请看下图:
图2.4 系统架构的考虑
图2.4是UML的部署图,这个图比较粗糙,而且为了降低大家阅读难度,我仅仅是用了部署图的最基本最少的语法来表达。
图2.4中的每一个立体的矩形,表示的就是物理上或者是逻辑上的一台设备,设备之间 有物理连接的话就用线条连接,每台设备中”{
}“括起来的文字是对该设备的进一步说明。
图可能是表达设计的最好方式,建议大家用UML,表达系统架构时,用UML的部署图、组件图和包图是比较合适的。我们设计的系统多数是分布式系统,不是单机系统,用部署图来表达分布式系统的架构设计可能是比较合适的。
图2.4针对图2.3中提出的问题进行了初步的回应,图2.4 就是一个初步的架构设计,当然后续我们还需要继续细化这个设计。
3.5 小结:如何需求驱动设计?
本篇的例子告诉我们:
1)优秀的设计是需要从分析需求开始的。
2)需求的质量可能有问题,那么我们需要从业务的角度重新审视一次。
3)从设计的角度审视需求,我们会提出很多需求细化及设计方案的问题。
4)架构设计是全面考虑各种需求、项目的工期限制预算限制,还有项目组人员水平后综合做出来的一种平衡。
(3)——软件系统不是木桶型的
前文提到我们应该需求驱动设计,那就直接来一个更干脆的做法,我们将需求表示为一个一个的用户故事,软件设计分别针对用户故事来做就行了,只要将用户故事逐个实现了,系统也就完成了。果然能这样做吗?
4.软件系统不是木桶型的
4.1 某种“需求直接驱动设计”的工作方法
案例分析:某敏捷实践项目小组的设计方式
某项目小组正在如火如荼地实践敏捷,任务看板上已经粘贴了很多“用户故事”,项目小组经常在看板前讨论问题:
1)讨论每一个用户故事的实现方法,并进行估算;
2)项目小组成员领取用户故事,负责实现该用户故事;
3)每天检讨进度情况和遇到的问题。
该工作模式给项目小组带来了新鲜的动力,调动了大家的工作热情,取得一定的工作成绩,但也带来了一些思考:
1)只要我们将每一个用户故事的设计想好并实现,每个用户故事都能通过测试,软件就能完成?
2)用户故事之间没有关系吗?软件设计不需要统筹考虑全部的用户故事吗?
4.2 软件是木桶型的吗?
请看图:
图3.1 软件是这样工作的吗?
一般我们的系统会采用分层架构,以三层架构为例子:
1)最外面的是表现层,主要就是程序的界面了;
2)界面后面就是我们写的程序;
3)程序后面就是数据库。
按照上述的“需求直接驱动设计”的工作模式,只要有新的需求,其实就是有新的用户故事,那么在这个用户故事驱动下,直接设计对应的界面、程序和数据库表就行了。这样的框架下工作,我们可以无惧需求变更。软件就是一个大木桶,需要实现更多需求,那就增加更多的木条就可以了;如果要修改需求,那就修改某条木条就可以了!
我发现很多系统是按照这样的思路来设计的,举一个某电信网站的例子。
我到该网站交费,发现有免费宽带提速的服务,需要输入电话号码来确认该电话线路是否具备提速的条件。我觉得很郁闷,明明我已经登录系统了,系统应该知道我的电话号码,为啥还要我填一次?好吧,为了免费提速,我就输入一次电话号码吧,提交后系统告诉我一个订单号,告诉我大概什么时候会搞定之类的信息。过了几天再次上这个网站,免费提速宽带的窗口又弹出来,我很烦关掉它:我已经提交订单了,还干嘛一直提示我!但它又继续弹出来,我烦了,那再提交一次订单吧,居然可以提交成功!被这样的系统折腾几次其实也不算什么,只要能免费提速也就值了,但最终的结果是电信一直没有帮我提速,我也懒得去投诉了,按照我以往投诉的历史经验,那是折腾自己的事情!
很多商家在不同时期有很多的促销等市场活动,需要软件系统来支持。我们按照木桶原理来做系统的话,看上去似乎事情变简单,但功能与功能之间其实存在很多交叉点,不考虑这些情况,会导致很多问题:
1)首先是用户体验超级不爽。有些系统甚至没有做到用户信息和权限信息共享,就好像上述这个电信例子。
2)没有能发现功能与功能之间的“重用”部分,没有从架构上和数据库底层上认真规划,其实会带来更大的总体工作量。
3)会留下一些系统漏洞甚至是安全漏洞,万一出问题后果很严重。
4.3 软件的内部架构是怎样的?
请看图:
图3.2 软件常见的工作模式
此图说明了以下问题:
1)需求并不是由一个个孤立的“用户故事"组成的,业务概念、业务流程其实是贯穿多个用户故事的,软件设计应该多从业务概念、业务流程的角度来思考;
2)表面上看上去一个用户故事对应一组界面,其实界面之间是很可能有重用和共享部分的;
3)业务逻辑层中的一些类很难将其分拆开来与用户故事、界面组一一对应,存在交叉、共享和重用的可能;
4)数据操作层的代码,有可能是用工具自动生成的、通用的;
5)数据层中的某张表,通常会支撑多个用户故事而不是一个用户故事。
下面我在列举一下无法单独考虑的设计点,以下列出来的可能都需要从软件架构上做一个整体的考虑:
1)权限控制;
2)性能要求;
3)日志记录;
4)工作流;
5)全文搜索;
6)多数据库支持;
7)搜索引擎优化;
……
实际上很少需求是可以通过单独添加一些类,加一些数据表就搞定的,需要通盘的考虑。如果我们硬生生地将系统看成是木桶型的,去添加系统的木条,会让软件很丑很难用,存在诸多漏洞,而且工作量会更大。
4.4 小结
有时候由于目前能力有限,无法全面考虑需求,只能暂时按照木桶型的方式来设计系统,这样也不是不可以的,但要注意的是至少要做到:
1)用户信息和权限信息是共享的;
2)要杜绝安全漏洞。
木桶型的设计方法其实会让系统很难用、弹性很差、工作量更大,而且部分需求我们无法通过添加木条的方式搞定,我们需要尽快升级我们的设计水平,下一节开始为你介绍比较实用的软件设计方法。
(4)——软件设计的“大道理”
十几年前刚毕业不久,我从事第一份软件开发的工作,要完成一个项目,但没有任何软件设计的思路,于是请教我的老板。我的老板给了我两种思路:1)先假设软件已经做出来了,想好软件的外在表现,由此倒推软件的实现方法;2)思考程序的数据结构,先设计数据库,然后再搭建软件的上层建筑。老板给了我很大的启发,随着工作的开展,后来我又发现了第3种设计的思路。本文将为你分享三种软件设计的思路:1)由顶而下;2)由底而上;3)由中间到上下。
5.软件设计的“大道理”
5.1 我的第一次商业软件的设计经验
1999年刚毕业不久,我从事第一份软件开发工作,当时要负责一个大型桌面软件,但不知道应该如何开展软件设计工作,于是向老板请教。老板也仅仅是年长我几岁,不过公司的核心产品是老板开发的,老板说他其实也没有什么系统的方法,不过有两种思路供我参考:
1)先假设软件已经做出来了,想好软件的外在表现,由此倒推软件的实现方法;
2)思考程序的数据结构,先设计数据库,然后再搭建软件的上层建筑。
上述的两种软件设计思路,相信很多有软件设计经验的朋友都能体会到。后来我又体会到第三种的设计思路,后文将会为你分享我对这三种设计思路的一些体会。
5.2 N层架构是怎么回事?
这三种设计思路都与软件系统的N层架构有关系,我们以常见的四层架构为例子,请看图:
图5.1 四层架构
这个是UML的包图(Package Diagram),图中好像文件夹的那个东西就是“包”,包与包之间的虚线箭头表示的是依赖关系。
上图表示的意思如下:
1)四层架构的四层,分别是指:表现层、逻辑层、数据访问层和数据层;
2)表现层依赖于逻辑层,逻辑层依赖于数据访问层,数据访问层依赖于数据层。
那“依赖”是什么意思呢?
“依赖”可以是以下情况之一:
1)A需要调用B的方法,则A依赖于B;
2)A的方法中某些参数的类型是B,则A依赖于B;
3)A的某些方法的返回值类型时B,则A依赖于B。
这样我们大概了解了四层架构是怎么回事了,但我们还会有以下问题:
1)表现层如何将数据传递给逻辑层?
2)逻辑层如何将数据传递给数据访问层?
3)数据访问层如何将数据传递给数据库?
通常我们不会这么老土通过一大堆参数来传递层与层之间的数据,通常我们会将数据装在实体类中,通过实体类来传递数据。所以图5.1可以进一步表示为图5.2:
图5.2 四层架构与实体类
补充说明一下什么实体类?
实体类通常是一个只有属性没有方法的类,通常我们会将某一业务对象的数据装在一个实体类中。例如:某请假单实体类,该类可能有请假人姓名、请假起止时间、请假类别和请假事由等属性。
5.3 “由顶而下”的设计思路
看了图5.1和图5.2,你大概就清楚了什么是软件的“顶”?什么是软件的“ 底”?“顶”就是表现层,“底”就是数据层。那么“由顶而下”的设计思路,其实就是先想清楚软件的表现层,然后再思考逻辑层、数据访问层、数据层的实现。
前文我们提到要“需求驱动设计”,这个说法有点笼统,我们需要进一步思考:“什么需求”驱动“什么设计”?
请看下图:
图5.3 由顶而下的设计思路
这是UML的活动图,横线将图分成了上下两部分,上部分是需求分析,下部分回答了“什么需求”驱动“什么设计”的问题。
说明一下:“需求驱动”及横线不是UML图的标准语法,图加上这些非UML元素是为了更好地表达问题。
“需求分析”这个活动有三种工作产品,分别是:
1)用例/用户故事;
2)业务流程图;
3)业务概念图。
你可以理解为上述三种工作产品是“需求分析”这个活动的“输出”。
“用例/用户故事”和“业务流程图”是“规划界面”这个活动的“输入”;类似,“业务流程图”和“业务概念图”是“设计逻辑层”这个活动的“输入”。其他就不再多解释了,你应该可以看懂这个图了,后续几个图的语法类似,也不再解释了。
上述是对图5.3语法及表达意思的基本解释,这里再稍微小结一下:
1)分析需求是设计的开始,我们还需要将需求至少分解为三部分:软件要满足的功能(用例/用户故事)、业务流程(业务流程图)、业务概念(业务概念图)三部分;
2)设计不同的层时,主要依赖的需求是不太一样的,上述分解的三部分需求对不同的层设计提出了不同的要求。比方说:设计数据库时主要是根据业务概念来设计的,规划界面时主要根据软件需要满足的功能点,还有业务流程来设计。
5.4 “由底而上”的设计思路
经过前面的铺垫后,这个“由底而上”的设计思路,相信你一看图就可以懂了。
图5.4:由底而上的设计思路
这个图也分成了上下两部分,上部分的内容其实和图5.3是一样的,只是左右顺序不太一样而已。
5.5 “由中间到上下”的设计思路
这种设计思路是我从事软件研发工作若干年后才认识的,当时是因为项目出现了特殊状况,为了应对这样的状况而采取的一种设计方法。
案例分享:客户要改SQLServer为Oracle
签订合同时,我们和客户约定的项目技术架构是.net+SQLServer,当时客户没有反对,我们就按这样的技术架构完成了系统,并且部署上线。但是不久客户居然提出了这样的要求:要求我们使用Oracle数据库,而不能用SQLServer数据库!我们通常是按照“由底而上”的思路来设计软件的,如果数据库要更换,基本上整个软件就等于重做!
如果你遇到这样的状况,你会怎么办呢?能不能按需求变更来处理呢?只有客户愿意付钱,我们就愿意干!但客户愿意付钱吗?这可是要付推翻重做的钱啊!!
最后我们的领导决定免费重做,领导决定免费重做的原因是:
这是公司的一个核心项目,我们期望这个项目将来能产品化,能持续赚钱。但我们技术选型主要是根据我们当前的技术情况来决定的,没有充分考虑客户的情况。客户是某重要行业的企业单位,单位体制内的所有企业基本都是用Oracle的,但我们选择“视而不见”,选择了我们最熟悉的SQLServer来开发系统,其实迟早是要遇到问题的。客户除了用我们的系统,还会用其他更大型的更重要的系统,客户的其他系统基本上都是使用Oracle数据库的。所以如果我们要在这个客户领域打开市场,将项目做好,就有必要将系统改造为Oracle数据库。
但是我们已经有部分客户使用了我们的基于SQLServer的系统了,将来也有可能会有部分客户要求用SQLServer,所以我们领导决心改造软件的架构,要让我们的软件可以支持SQLServer,也可以支持Oracle!于是我们按照“由中间到上下”的思路,重新打造了软件架构,请看下图:
图5.5 由中间到上下的设计思路
这个图也分成了上下两部分,上面部分和前面的图内容也是一样的,但下面部分就很不一样了,而且可能比较难理解。
“由中间到上下”基本的思路是这样的:
1)先不考虑表现层,也不考虑数据层;
2)先定义实体类和数据层接口;
3)接口定义好后,往上可以设计逻辑层和表现层,往下可以设计数据层接口的实现和设计数据库。
按照这样的设计思路做出来的软件架构,应该是这样的:
图5.6 由中间到上下的系统架构
图中见到数据操作层接口有两种不同的数据库实现,分别是SQLServer和Oracle,如果要考虑第三种数据库,那么再增加一个实现就搞定了,而系统的上层建筑(表现层、逻辑层)不需要改变。
这样的设计方式看上去很酷,是不是应该所有系统都要考虑用这样的方式来打造呢?
不是滴,这样的设计方式是有缺点的:
1)系统将不能充分利用数据库的特性,一般会禁止在数据库中写存储过程、触发器、甚至是视图等,程序的的性能其实会降低;
2)因为不能充分利用数据库本身的特性,所以大部分甚至是全部的业务逻辑只能靠程序搞定,这样其实增加了程序的复杂度和工作量。
所以每种设计方法都是有针对性的,都很难做到十全十美,一般只能针对主要矛盾做出一些取舍。
5.6 小结
如果系统没有多数据库的要求,我会比较建议你用“由顶而下+由底而上”的设计思路;如果程序需要支持多数据库,那么可能考虑“由中间到上下”。上面介绍的三种设计思路,其实在实际工作中我们往往不会只选其一,往往是结合了多种思路的。不要局限自己的思路,软件设计的可能性是无穷的。
|