2.5系统设计
2.5.1分析模型映射到设计模型
在得到分析模型的时候,我们已经获得了边界类、实体类和控制类,并且用他们在软件架构和软件框架内实现了需求。因此,在设计阶段不需要考虑设计出来的类是否满足需求,这点已经在分析阶段得到了证实。甚至不需要考虑类方法,类属性和类之间的交互。因为最关键的方法和属性也已经在分析模型中被明确了。
其实分型模型已经非常接近设计类了,我们只需要将分析类简单的一一对应转化为设计类即可。在转化的过程中需要确定开发的语言,是java开发还是c开发等等。在映射过程中,出于优化类结构的目的,我们有可能将分析类进行简单的分拆或者做一些简单的设计工作。
将分析模型映射到设计模型后,我们得到了设计类,基本就可以交付开发了。如果静态图还不足指导开发,可以在绘制设计类的交互图来说明这些类如何交互完成设计功能的。例如:
2.5.4接口设计
面向对象的一大好处是接口与实现的分离,这使得我们在考虑程序逻辑的时候完全不考虑程序怎么编写,而只考虑对象交互的接口。
接口设计需要设计师考虑的非常全面,除了考虑到解决现有问题,还要考虑将来可能带来的问题,除了考虑程序的扩展性,还要考虑接口的易用性。甚至,有的时候接口设计很像是纸上谈兵,设计师需要凭想象来决定接口的使用场景。
接口的设计就好像一个著名的脑经急转弯:把一只大象放进冰箱,总动需要几步?习惯于从实现考虑问题的人将会从怎么分解大象,制造个大大的冰箱,或者其他诸多的因素去考虑。而对于接口考虑问题的话,不管冰箱要装的是大象还是牛排,总共就几步:打开冰箱门,把大象放进去,关上冰箱门。可见,从接口考虑问题使得问题简化并且灵活。
2.5.3.1单个对象设计接口
极端的来说,应该为每个对象都设计接口,哪怕这个对象行为与其他任何对象都不一样,完全没有抽象价值,甚至看不到将来变更的可能。当不论怎样,有接口都比没有接口好,面向接口编程应当养成习惯。
2.5.3.1多个对象设计接口
在一个系统里面会有许多对象具有相同或者相似的行为模式。通常,这些对象都承担相同或相似的职责,即他们处理试听的方法差不多,但是处理的内容和具体过程有可能不同。
典型的具有相同或者相似行为模式的对象是实体对象。实体对象作用主要是封装业务数据和对业务数据的操作方法。虽然实体类对象封装的业务数据千差万别,但是操作数据的方法无非就是增删查改。例如下图的例子:
具有相似行为的对象设计接口示例
PO中的方法都是未实现的他们的方法在具体的实体类中实现。
2.5.3.1为软件个层次设计接口
一个多层次的软件架构,各层之间的交互是错综复杂的。我们将软件按层次分开的目的就是为了使得各软件层职责清晰,各负其职。如果层次之间的交付过程没有很好的接口设计,软件分层带来的好处很可能会完全丧失。例如下面例子中的web层和businessControl层之间的交互式由各种action类和BusinessControl类来完成的。Action类和BusinessControl类数量大,在没有良好的接口设计情况下,web层和BusinessControl层的交互图为:
无良好接口设计的层次交互
类与类之间盘根错节,逻辑关系非常复杂。而如果采用门面模式来处理WEB层和BusinessControl层之间的交互可以有效减少交互复杂度。例如下图:
采用门面模式后的交互层次
2.5.5包设计
包是用于在物理上组织和管理类文件的包装器。包的作用是将类文件按一定的规则有序的放置在一起,要么有利于管理这些文件,要么有利于人们理解这些文件的。软件世界分包与现实世,界的职能部门分类类似。分包的目的除了将程序文件分类管理,最重要的就是。如果让软件组织有序并且职责清晰。一般来说,分包应当遵循自顶向下原则,职能集中原则和互不交叉原则。
2.5.5.1自顶向下原则
自顶向下原则的意思是分包时候要像组织机构一样,从顶级包自顶向下延伸,避免平行化无层次分包。自顶向下原则的另一个重要含义是下层包不能否访问上层包,并且不能够夸层访问包,但是同层次包可以访问。即只允许存在自顶向下不越层的依赖。
例如下面的例子。现实世界企业最高战略是由董事会决定,CEO制定战略计划,各个部门总经理制定部门实施计划,最后是员工具体执行,执行结构反应到以数字为记录的各类业绩报表,成本核算中。而在软件世界中,用户是最高司令,用户的命令有界面传递到逻辑处理,在执行计算,反映到实体,最后进入到数据库中。
自顶向下分包原则
2.5.5.2职能集中原则
职能集中原则意思是尽量将与一组业务功能有关的类分在同一个包里面。如果违反这个原则,将与一个业务功能相关的类放置到多个包,就会出现职责不清的问题。
职能集中原则在软件世界里面反映为子系统、模块、子模块、功能模块的划分。职能集中原则应当服从于自顶向下原则。即,我们应当选应用自顶向下原则,将层次分清楚后,再来应用职能集中原则,在每个层次里面划分职能。
职能集中分包原则
2.5.5.2互不交叉原则
互不交叉原则意思是包和包之间的类尽量独立,不要让他们产生相互依赖关系。如果不可避免的要产生依赖关系,那也应当是树状的依赖关系而非网状的依赖关系。如果违反了这个原则,就会产生程序逻辑混乱、难以维护和扩展能力差的问题。
避免交叉依赖的方法有两种:
一种是将交叉依赖的类单独分包。如下图:
方案1
一种是增加新的类,并单独分包。如下图:
方案2