软件项目实训及课程设计指导——如何实现程序类设计的高内聚低耦合的系统设计目标(上篇)
1、前言
为了能够设计和实现一个高内聚、低耦合的软件应用系统,软件应用系统的设计和开发人员不仅要有灵活的系统体系架构设计结果,而且也还要有良好的程序类的设计结果,因为构成软件应用系统的组成单元是程序类。
因此,软件应用系统的设计人员不仅要保证软件应用系统在整体体系架构设计方面是“高内聚、低耦合”的,更应该要保证组成软件应用系统中的各个功能程序类的结构、类之间的关系也应该是“高内聚、低耦合”!
如何合理地进行程序类的设计以提高程序类的内聚性,同时又要降低程序类之间关系的耦合度?软件应用系统的设计人员应该要遵守什么方面的设计原则?设计人员需要应用什么方面的设计理念和运用哪些设计模式?J2EE技术平台中的软件应用系统的持久层、数据访问服务层、业务处理层和表示层中的各个功能程序类又应该如何正确地进行类结构(达到高内聚效果)和类之间的关系设计(达到低耦合的关系)?等等问题…
作者一直倡导软件应用系统的设计结果应该是设计人员“理性思考”后的结果,软件应用系统的设计人员要达到理性的设计效果,则必须要遵守一些基本的设计原则和应用一些经典的设计模式、并借用一些通用的设计思想和重用成熟的设计方法。
作者从本文开始,并通过后续的多篇文章试图对这些与程序类设计有关的各种问题给读者一个明确的答案和技术指导,以期望读者(特别是在校的IT类相关专业学生)的课程设计、项目实训(包括毕业设计)等实训类型的教学项目开发能够达到一定的技术水准,同时也希望读者能够把在软件工程、计算机软件应用技术等课程中所学习到的各种软件系统的设计思想和设计原则真正地实践和体验,而不要仅仅停留在对这些设计思想、技术原理和开发工具的泛泛的了解或者简单地应用层次——“学”而时“习”之!
2、面向对象OOP编程技术中的程序类是构成软件应用系统的基本组成单元
(1)回顾面向对象OOP技术中的程序类概念
人们把众多的事物归纳并划分成一些类型是人类在认识客观世界时经常采用的思维方法。面向对象OOP编程技术中的程序类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了一个“统一的抽象描述”。这些概念对于学习过面向对象编程语言(如C++、Java及C#等)的独自来说并不陌生,作者在此也不需要再重复描述。如下示图为计算机类Compute和其它设备类之间关系的UML类图的局部截图,读者通过理解这个UML类图也能够更进一步地理解面向对象OOP技术中的程序类是对自然界中客观存在的一类实体的抽象描述。
哲学告诉我们:世界是由物质所组成的!而面向对象同样也告诉我们:世界是由对象所构成的,并且它们是由一组彼此相关并能相互通信的实体(Object,对象)所组成。
(2)程序类是构成软件应用系统的基本组成单元
OOP编程技术中的程序类的内部组成主要包括成员属性和成员方法两个主要部分,其中的成员属性体现该程序类所代表的问题状态,而类中的成员方法则体现该类对外界所表现出的服务。将某个类进行具体的对象实例化而构造出该类的对象实例,各个对象之间通过相互之间所产生出的各种“消息”进行交互而构成软件应用系统中的各个业务行为。
由于程序类是构成软件应用系统的基本组成单元,因此,软件应用系统的设计人员要真正达到软件应用系统的整体体系架构的“高内聚、低耦合” 的设计效果,其实最终还要取决于构成软件应用系统中的各个程序类的结构、程序类之间的关系是否是“高内聚、低耦合” 的设计效果——木桶短板效应!
3、面向对象OOP编程技术中的程序类的设计主要体现在两个方面
其一是合理地进行程序类的职责分配,其次则是合理地进行程序类结构和类之间关系的设计。
对于如何正确地进行程序类的职责分配,软件应用系统的设计人员可以遵守通用职责分配软件模式(也就是下文所提及的GRASP)中所倡导的各个基本设计原则;而对于如何决定程序类结构和程序类之间的关系设计,软件应用系统的设计人员应该满足和遵守面向对象OOP程序类设计方法中的五大设计原则。
4、GRASP能够指导软件应用系统的设计人员合理地进行程序类的职责分配
(1)GRASP是什么?有什么主要的作用?
GRASP(General Responsibility Assignment Software Patterns,通用职责分配软件模式)描述了有关程序类设计和职责分配的最基本的设计指导原则,它不仅可以指导软件应用系统的设计人员如何把现实世界中的各种形式的业务实体抽象成软件应用系统程序中的实体类、将现实世界中的各种形式的业务功能抽象成软件应用系统程序中的业务功能类和业务功能类中的各个功能方法,也能够帮助软件应用系统设计人员决定在一个具体的软件应用系统中应该需要有哪些程序类、并且每个程序类都应该包括什么方面的职责。
(2)如何更详细地学习和了解、应用GRASP
当然,对于什么是通用职责分配软件模式、如何学习GRASP以及软件应用系统设计人员如何运用该软件模式所倡导的设计原则等具体的内容,请读者阅读作者的“J2EE项目实训——UML及设计模式”一书中的第8章“通用职责分配软件模式(GRASP)”的有关内容。
(3)GRASP体现了职责驱动设计的核心思想
职责驱动设计(RDD,Responsibility Drive Design)是Craig Larman在他的经典著作《UML和模式应用》中提出的。Craig Larman在提出职责驱动设计理论的同时,还提出了GRASP软件模式来丰富这个理论。
职责驱动设计的核心思想主要是要求软件系统分析和设计人员在对一个软件应用系统进行分析设计的时候,应当以“职责”为中心,根据职责分配行为。
这种思想首先要求我们设计的所有软件世界的对象,应当与现实世界尽量保持一致。我们经常使用的软件应用系统实际上是对现实世界的模拟——比如微软的Office办公套件,模拟和解决人们在办公过程中所涉及的一系列的事务和行为。因此,软件世界与现实世界存在着必然的联系。
当我们在进行软件应用系统的需求分析的时候,需求分析人员实际上是从客户那里了解现实世界事物的规则、工作的流程。如果我们在软件分析和设计的过程中,将软件世界与现实世界紧密地联系到一起,我们所设计和开发出的软件系统将更加本色地还原事物最本质的规律。
当软件系统设计和开发人员应用这个设计思想和遵守相关的设计原则进行软件应用系统的设计和开发实现时应该遵守如下的规则——读者可以参看如下的示图中所描述的“现实世界”和“软件世界”之间的映射关系,以方便进一步理解这个规则:
1)“现实世界”有什么事物,就映射为“软件世界”中的各种类和对象;
2)“现实世界”中的事物拥有什么样的职责(行为、功能等),在“软件世界”里的对象就拥有什么样的职责(功能或者作用);
3)在“现实世界”中的事物,因为它的职责而产生的行为,在“软件世界”中就反映为对象所拥有的函数(Function,面向过程程序设计中)或者方法(Method,面向对象程序设计中)。
5、面向对象OOP类设计方法中的五大原则指导设计人员合理地进行类之间关系的设计
软件应用系统的业务逻辑和业务流程的最终实现是通过软件应用系统中的各个程序类之间的交互而实现的,软件应用系统中的类和类之间必然要产生各种关系——就比如任何人都不能独立于他(她)所生活的群体而孤立地生活在这个世界上,人与人必须要依赖、联系和沟通、活动等。
因此,软件应用系统的设计人员如何正确而又合理地决定软件应用系统中的各个程序类之间的关系?面向对象OOP类设计方法中所倡导的五大设计原则能够指导软件应用系统设计人员正确、合理地进行程序类之间关系的设计。
为了能够让读者对低耦合的程序类之间关系有一个感性的认识,作者给出如下的示图。该示图左边所描述的各个程序类与某个子系统内的其它程序类(或者组件)之间的关系特别复杂和凌乱——千丝万缕!经过对它们进行优化设计后所产生的示图右边结果则更加清晰和简单,程序类之间的关系一旦简单,读者从直观上就应该能够感觉到对它们进行维护和完善、升级方面的工作也就容易!
6、面向对象OOP类设计中的五大设计原则是什么
面向对象OOP类设计的五大设计原则主要是指程序类在设计和开发实现时必须要遵守的如下五个设计原则:
(1)“开放-封闭原则”( OCP,Open-Close Principle)
(2)“单一职责原则”( SRP,Single-Responsibility Principle)
(3)“接口隔离原则”( ISP,Interface Segregation Principle)
(4)“Liskov替换原则”( LSP,The The Liskov Substitution Principle)
(5)“依赖倒置原则”(DIP, Dependency Inversion Principle)
软件应用系统中的程序类设计的五大设计原则之间并不是相互孤立的——它们彼此间存在着一定关联,一个设计原则可以是另一个设计原则的加强或是基础。违反其中的某一个设计原则,可能同时也违反了另一个设计原则。