项目训练与课程设计指导——如何实现面向对象的系统架构设计
1.什么是面向对象软件应用系统的架构设计?

从软件应用系统架构师的角度来看,所谓软件应用系统的系统架构,就是一套用于构建软件应用系统整体结构的各种设计准则。通过这套设计准则,架构师可以将一个复杂的软件应用系统划分为一些相对独立的子系统,在各种复杂的技术应用需求和功能实现中获得最优雅、简洁、合理的解决方案。
2.在软件应用系统的架构设计中,应综合应用与OOP、AOP和SOA相关的设计思想。
面向对象和面向方面的设计思想
因为面向对象和面向方面开发相关的各种设计思想和具体实现技术解决了软件应用系统内部结构设计的问题,而面向方面的设计思想弥补了面向对象设计思想在实际软件应用系统开发应用中的相关缺陷——因为面向对象编程技术无法实现软件应用系统中核心关注点和横切关注点的分离,而面向方面编程思想就是为了解决这一问题而提出的。因此,在软件应用系统的设计、开发和实现中,应该综合应用面向对象编程技术和面向方面编程技术。
下图中的程序代码混合了大量实现日志功能的程序代码,导致实现日志功能的程序代码横向分散在各个层次的对象中——这样的日志功能实现是控制层、业务层、数据访问层所需要的,与它所分布到的对象的核心功能无关。其他类型的代码也是如此,比如安全性、异常处理和透明持久性。这种分散在各处的无关代码被称为横切代码。在面向对象的设计方法中,会导致大量程序代码的重复,不利于各个功能模块的重用。
面向服务的设计思想
而面向服务的设计思想和具体实现技术,更多的是解决软件应用系统的外部结构设计问题——即如何更好地集成和互联软件应用系统,实现更高效的复用,快速满足企业不断变化的业务需求。
下图是基于面向服务设计思想的轻量级Web服务组件技术的系统架构。每个Web服务组件都通过SOAP协议传递消息。
Web服务组件技术本质上是放置在网站上的可重用组件,Web Service是基于网络的分布式模块化组件。它执行特定的任务并遵守特定的技术规范,这使得Web服务能够与其他兼容的组件进行互操作。Web服务的概念实际上是RMI、COM、CORBA等现有面向服务技术的扩展。Webservice平台是一组标准,它定义了应用程序如何在Web上实现互操作性。主要用于解决不同系统平台下应用的协同,如VS.Net平台和J2EE平台之间的信息共享和访问。
3.定义软件应用系统架构设计的设计目标。
软件架构师不仅要考虑软件系统整体结构的设计和软件系统应具备的功能,还要关注整个软件系统的可用性、可重用性、可扩展性、可靠性、安全性等相关方面的技术实现,以达到高内聚、低耦合的系统架构设计目标。
4.区分面向过程的设计方法和面向对象的设计方法的区别。
面向过程的设计方法
常用于确定软件应用系统体系结构的设计方法主要有面向过程的设计方法和面向对象的设计方法,而面向过程的设计方法是基于三个逻辑构造元素——顺序、选择和重复。而且面向过程的设计方法采用了“自上而下,逐步细化”的经典瀑布式设计方法。由于瀑布式设计方法是以“自上而下”的顺序进行的,它要求系统架构师在系统设计之初就对软件系统中应该解决的问题的各个方面有全面透彻的了解。
这种设计方法在功能复杂、需求多变的企业级应用系统的设计开发中会有一定的难度。
面向对象的设计方法
目前流行的面向对象系统架构设计方法定义了系统中各种可能的对象类型,并对每种对象类型进行细化,找出它们之间的关系。
在面向对象的设计方法中,设计人员可以充分利用对象的“抽象、封装、继承和多态”的特性。同时,面向对象的系统架构设计方法是一种“自下而上”的设计方法,其优点是形成了一种螺旋式的软件开发方法,只需局部修改或调整现有的系统设计,就能满足软件应用系统不断变化的需求。
5.为什么要用面向对象的设计方法来设计软件应用系统的架构?面向对象的体系结构设计能够适应软件系统不断变化的需求。

应用面向对象的软件应用系统体系结构设计方法可以保证软件应用系统体系结构的设计结果具有一定的可重用性和可扩展性。对于这类软件应用系统,如系统功能需要不断扩展的软件应用系统项目,或系列化产品软件的软件应用系统架构设计,应采用面向对象的软件应用系统架构设计方法进行系统设计和程序模块的功能开发。
6.遵循面向对象软件应用系统架构设计的基本原则。
垂直分离原理
对软件应用系统进行垂直分层和合理隔离,使软件应用系统中的每一层都能为其对应的上层提供功能服务,成为服务提供者。同时也作为下层的客户端,获取其他层提供的所需功能服务。因此,当使用垂直分层架构模式来组织软件应用系统时,可以构建软件应用系统的分层垂直结构。
J2EE技术规范为开发复杂的分布式企业级软件应用系统定义了一套系统架构和技术规范。它不仅提供了一整套基于标准化模块的功能服务组件,还为企业应用系统提供了标准的垂直分层设计方案。
下图是反映某个系统层次结构的UML技术规范的包图。从该图所示的UML包图可以看出,软件应用系统由表示层、控制层、业务层、数据服务层和持久层等组成。,并且各层之间只有单向依赖——从而很好地实现了各层的封装和隔离。
如果软件应用系统的设计者在系统架构设计中遵守垂直分层和隔离的原则,他将能够屏蔽各层中功能组件的具体技术实现细节,同时某一层次的模块用户只能使用目标层中组件所需的功能服务,而不知道目标层中每个组件的具体结构及其具体的技术实现细节。此外,当软件应用系统的需求发生变化时,只需要改变一些基础层中的功能服务组件,而不会影响上层服务消费者组件的技术实现和程序代码。
银行账户信息管理系统项目是本系列文章中给出的一个示例项目,它在垂直分层和隔离方面采用了四层系统架构设计。下图所示的UML包图是一个分层的包图,反映了这个软件应用系统项目的系统架构设计结果。
依赖倒置原理
反转原理的本质是软件应用系统架构设计中各层之间的关系应该基于抽象接口,上层模块不应该直接依赖下层模块,两者都依赖于一个抽象。抽象元素不能依赖于具体元素,但具体元素必须依赖于抽象元素。下图显示了软件应用系统中XML数据处理与XML文件中数据解析之间的依赖关系。
因为传统的面向过程的设计方法往往会使高层模块直接依赖于低层模块,抽象层程序依赖于具体实现层的功能组件程序。面向对象设计中提倡的依赖倒置的原理,就是要将这种错误的依赖倒置。
下图中的箭头表示面向过程编程方法中函数之间的调用关系,也是函数之间的依赖关系。如图所示,主功能依赖于它的各种子功能,而子功能又依赖于更小的子功能。在实际程序中,较小的功能往往要处理细节功能的实现,而这些特定功能的需求往往会发生变化——当软件应用系统的需求发生变化时,软件应用系统的设计者和开发者往往要来回改变这些细节的实现。
随着软件应用系统的功能越来越复杂,系统中各层、各模块之间的依赖性会逐渐加强,软件应用系统的整体可扩展性会逐渐减弱。因为面向过程的编程方法中程序的“核心逻辑”很大程度上依赖于外围程序的功能实现细节,所以程序本来应该是一个相对稳定的“核心逻辑”,但也因为依赖于可变的外围功能实现细节而变得不稳定。这时,如果软件应用系统的细节有一点小小的变化,也可能引起依赖关系的一系列“连锁”变化。
然而,如果设计者在设计软件应用系统的体系结构时遵守依赖倒置的原则,将能够减轻或避免这种设计缺陷。当然,为了满足依靠反演原理的基本要求,软件应用系统的设计者也需要使用接口作为软件应用系统中层与层之间的“粘合剂”。
接口的定义和接口的具体实现是相互分离的。
软件应用系统合理分层后,如何设计和决定层内组件之间的关系,分配各组件各自的职责?
将软件应用系统中各功能模块的接口定义与这些接口的具体实现分离开来,是解决这些问题的软件应用系统设计和实现的指导原则。
这个设计原则的基本指导思想是:为了消除两个软件模块之间的相互依赖,应该在两个软件模块之间定义一个抽象接口。上层软件模块调用这个抽象接口中定义的方法,而下层软件模块具体实现这个接口中定义的方法。因为接口可以反映问题的抽象,同时,抽象一般是相对稳定或者相对不频繁的,而具体的实现是可变的——随着应用需求的变化相应地更新和完善相关的程序功能实现。
下图是一个系统持久层中实现用户信息数据库表的函数操作的DAO组件接口UserManageDAOInterface和该DAO接口的函数实现类UserManageDAOJDBCImple之间关系的UML类图。

一旦接口的定义和接口的具体实现相互分离,就可以根据不同的应用需求,基于同一个接口提供相应的功能实现类,从而保证软件应用系统能够适应不同的应用需求,同时保证上层功能服务的调用保持不变。下面的UML类图展示了计算机与不同外部设备之间的关系,其中计算机类只依赖于USBDevice接口,而不依赖于与具体USB接口相关联的实现设备,从而保证了计算机USB设备的可扩展性和可变性。
7.在面向对象的架构设计中合理应用各种架构设计模式。
作者在《J2EE项目培训-UML和设计模式》一书的第七章中对“架构设计中的架构模式”做了详细的介绍。这里不再赘述。读者可以参考相关章节的讲解,自行学习理解。
但是,作者在这里需要补充的是,GOF设计模式中的桥、门面、中介等代码实现模式,实际上不仅可以作为代码实现模式出现,也可以作为系统架构模式出现——因为它们都可以达到“分层隔离”的效果。下图是应用中介模式将系统中的表示层组件与应用系统中的数据处理功能组件隔离开来的UML类图——通过中介对象封装一系列其他对象的交互关系,从而降低这些对象之间的耦合关系。
对象之间的“多对多”关系变成了两个“一对多”关系,可以降低软件应用系统中类之间关系的复杂性,相应地提高软件应用系统的可扩展性。


