当前课程知识点:面向对象分析与设计 >  识别设计类 >  识别子系统及接口 >  识别子系统和接口

返回《面向对象分析与设计》慕课在线视频课程列表

识别子系统和接口在线视频

下一节:描述运行态软件体系架构

返回《面向对象分析与设计》慕课在线视频列表

识别子系统和接口课程教案、知识点、字幕

同学们

今天 我们介绍面向对象分析与设计这门课的第17讲

识别子系统

在前面 我们介绍了识别设计元素

我们说设计元素主要有

设计类、子系统和接口

那么我们今天就重点讲一下

如何来识别子系统和子系统的接口

我们首先回顾一下子系统

什么是子系统呢

子系统是一个具有相对独立、功能的、封装的一个实体

我们把它定义成子系统

子系统的内部是封装起来的

对外它提供它的服务接口

或者它请求别的对象对它提供

所以每个子系统对外都会有提供至少一个提供接口

或者同时可能会具有零个或者多个请求接口

在子系统里面

一般每个子系统具有复杂的内部封装的行为

每个子系统它有相对独立性

它有它清晰明确定义的子系统的接口

一个子系统可能会实现多个接口

同样的一个接口会被多个子系统所实现

所以子系统和接口之间有一个多对多的映射关系

和子系统相接近的还有一个概念叫做包

和子系统相接近的还有一个概念叫做包

上节课我们重点讲了包

我们说包一个容器

包里面包含有多个类

或者多个相关的一些类

我们把它打包在一起

包本身是没有行为的

包的行为就是它内部所包含的这些类的行为

共同组织成包的行为

但是子系统不一样

子系统它可以提供它的行为

子系统的行为就定义在子系统所实现的提供接口里面

子系统实现的这些接口明确的 子系统对外所提供的行为

而且子系统是完全封装的

我们只能看到接口通过接口了解子系统对外提供哪些服务

但是包不是完全封装的

包的内部所有公开的类都是直接暴露出来的

可以供包的外部的其他对象去访问

子系统很容易被替换

因为它有明确的接口

能够实现相同接口的子系统之间

可以相互替换而不会引起错误

但是包的封装性是不完备的

所以包的替换可能会带来潜在的问题或错误

为什么我们要使用子系统呢

我们在软件系统设计过程中

我们使用到子系统以后可以让每个子系统独立进行使用

它可以作为一个独立的单位进行配置管理

独立的部署或者发布给用户

在开发过程中 只需要子系统的接口不变

它的内部我们如何来设计或者说我们来修改它

都不会影响到子系统外部的其他的设计元素或者对象

在分布式部署的时候

我们也可以以子系统把它部署在不同的计算节点上去

所以有了子系统以后

可以使整个系统有良好的可维护性

子系统在设计阶段

我们还可以用于解决一些特殊问题

比如说安全性

我们可以把与安全性相关的封装成一个子系统

这样可以更方便的把它保护起来

另外子系统还可以促进复用

我们在设计的时候定义一个子系统

这个子系统就可以直接选用一些已有的

比如说我们之前开发的系统里面已经开发完成的一些组件

或者第三方的商业组件 或者开源组件

这样通过子系统我们有助于实现软件系统的复用

那么我们如何来找到这些子系统呢?

我们的系统里到底定义几个或者哪些子系统呢?

首先第一个

我们来看对象的协作关系

我们在时序图或者通讯图里可以发现

有些对象它们之间的协作关系非常紧密

那我们就要考虑能不能把这些通信关系非常紧密的对象封装在一起

将它们定义成一个子系统

还有一些对象或一些类

它们描述实现系统的可选功能

那么这种情况下我们把描述实现同一个可选功能的类

可以考虑封装成一个子系统

另外有一些复杂的用户系统接口

特别是一些跟外部设备交互的接口 跟外部软件系统交互的接口

因为有复杂的通信协议

我们可以考虑把它定义成一个子系统

还有时候我们可以根据用户的角色

我们说一个软件系统可能有多个角色

我们把这些和同一个角色相关的类

就可以考虑把它封装成一个子系统

另外我们还可以根据类之间的耦合和内聚关系

我们把强耦合的

就是相互关系比较紧密的类

我们就可以考虑把它封装成一个子系统

在一个可以考虑它的可替换性

如果两个包或者两组类

它们之间的功能具有可替换性

那么我们可以考虑把这两个包或者这两组类封装成两个不同的子系统

它们来实现同一个接口来实现它们之间的相互替换

另外我们还可以考虑分布式

我们把运行在不同的计算节点上的软件组件、软件类

把它封装成一个对应的子系统

再一个就是看它的变化性

我们有可能后续在设计过程中演化或者变化的那些类

可以考虑把它封装成一个子系统

这样它的变化只是在它的内部不会扩散出去 影响到其他设计元素

在前面我们讲

我们识别出的分析类

有些复杂的分析类在识别设计元素的时候

我们可以直接把它定义或者识别为对应子系统

比如说对于一些控制类来讲

他提供一些复杂的控制逻辑或者说提供一些复杂的服务

那么这些类就可以把它定义成一个子系统

还有一些边界类

比如用户系统的、外部系统的、外部设备的接口

这样一些复杂的边界类也可以考虑把它定义成一个子系统

另外在软件设计过程中

我们推崇或提倡有效的软件复用

我们知道软件复用可以选已有的组件

这些组件已经被充分验证和应用了

它的功能是正确的

它的质量是可靠的

那么通过软件复用我们知道可以有效的降低软件开发的成本

降低软件开发的时间

那么在软件系统里面经常可以选用一些能够提供一些公共功能的软件组件

把它设计成相应的子系统

比如说在软件开发中使用到的通信软件、数据库访问软件、一些常用的典型数据结构

还有一些公共的工具比如加密、解密、压缩、解压缩这样一些程序

都可以把它封装成一个对应的子系统

这里我们给了一个例子

这个例子是一个控制类

这个控制类的控制逻辑很复杂

所以我们把它定义成一个子系统

同时定义了子系统所实现的接口

在定义了子系统的下一步

我们要定义子系统的接口

对于所有的子系统我们首先要识别出一组候选接口

然后我们要检查这些接口之间有没有相似性

然后我们需要定义接口之间的依赖关系

最后把这些接口映射到对应的子系统里面去

当然我们还要把这些接口进行管理

把它进行打包

我们通过包把他们放在一起

在接口里面要明确每个接口的名称

接口的描述

每个接口定义的子系统对应的服务或者操作

最后还要补充说明

比如说用时序图或状态图描述这些操作直接的约束或关系

这个例子里面是教学管理系统

我们在分析阶段识别的分析类

比如说跟计费系统的接口

我们这里把它定义成一个子系统然后定义它的接口

这是另外的课程目录系统所识别的子系统和它的接口

这张表列出来分析类和它对应所识别的哪些子系统

然后我们定义完子系统还要描述每个子系统所实现的接口

上面是ROSE特有的,下面是UML的描述方式

这是我们在教学系统里面识别的子系统

有课程目录系统的子系统

然后它所实现的接口 和接口和别的类之间的依赖关系

有了这个依赖关系之后 控制器这个类依赖于这样一个接口

他会请求这个接口 而这个接口被下面的子系统所实现

最终通过接口回请求到后面实现的子系统

这是另外一个计费系统的例子

在识别完子系统和接口以后

下一步我们要识别复用机会

在软件设计中我们提倡进行软件复用

软件复用刚才讲 可以降低成本、降低开发时间、提高软件质量

那么如何找到复用机会呢?

首先来找子系统接口有没有相似性

如果有相似性 我们就不需要定义新的子系统

我们就可以考虑进行复用

当然 要两个接口完全一样可能是有困难的

我们就可以把一个新的接口进行修改

使得它尽可能与已有子系统接口一样或匹配

这样就可以复用以及实现已有接口的子系统

最后我们把已定义的候选的子系统和已有组件

我们把接口替换以后

那么实现同一个接口的一些已有组件就可以替换我们所定义的这些子系统

那么如何找到可能的复用机会呢?

首先从系统开发的内部

我们把跨包的或者多个子系统公共访问的功能

我们就可以考虑把它识别出来

把它单独定义成一个子系统供多个包同时访问

这叫内部复用

那么还有一种更常用的外部复用

比如说要求选用外部已有的商用组件、开源组件

或者逆向工程从之前的软件版本里面提取出来的已开发过的组件

这是一个内部复用的例子

我们可以看到新定义的一个包要使用到之前的一个包里面的功能

但是它俩在同一层

我们说在层次化软件架构里面他不能够直接访问

那么我们就可以把上面的包里面被他调用的功能放在下面来

这样的话他就可以直接调用下面这个包的功能

等到后面迭代的时候 可以看到之前重复的功能就去掉了

这两个包都复用到下一层里面的包的功能模块

这样就实现内部复用

在接口定义完以后 我们还要更新其架构

之前我们介绍了一种常用的架构模式是层次化的

它有系统层、中间件层、业务领域层和应用层

那么在分层的时候我们讲上层依赖于下层

所以要考虑层次间的接口

使得上层通过接口访问下层 有相对独立性

通过层次化使得如果上层变更

因为上层单向依赖下层 所以不会影响到下层

反过来通过标准化层次间接口以后

下层变化以后也不会影响到上层去

在层次划分里面越抽象的元素应该实现公共功能 所以应该在底层

和应用相关的具体的应该在应用层、上层

层的数量一般来讲为三到四层比较合适

复杂的系统也不适合层次过多 比如说在五到七层就可以

这是一个简单的例子 我们划分了三层

这是教学系统里面 我们划分的层次

最下面是中间件层 这是业务逻辑层 最上面是应用层

在层的划分时 主要考虑第一个是耦合内聚关系

第二个是考虑用户 面向不同的用户 它应该在划分在不同的包或子系统里面

再一个是考虑一致性 另外考虑系统分布式部署

还有一些安全性的考虑 比如说安全性不同的 我们要划分到不同的组件或者包里面

再一个是变化性 把容易变化的部分应集中放在同一个包里面

在层的划分里面 最关键的就是避免循环依赖

这是我们划分的 我们看上面这些类的关系比较紧密

我们把它划分在一个包 放在一个层

那么下面这些类的关系也比较紧密 我们把它划分在另一个包 放在下面的层里去

这是教学管理系统里面 我们划分的应用层有一个注册的包

这是在业务逻辑层 它有外部系统接口 安全性 还有大学

这样一个包他和应用层的包之间建立了依赖关系

这是业务服务层里面所定义的子系统接口 还有其他一些包

这是中间件层他们之间的依赖关系

这是中间件层里定义的两个子系统 或者说可复用的组件 分别是SQL和com.odi

同学们 今天我们主要讲了一下如何来识别子系统

以及如何来识别子系统之间的接口

然后我们通过子系统实现的接口来找到复用机会

比如说我们在设计的时候 定义了子系统和它的接口

可能发现这个接口和已有的某个组件的接口是类似的

那么可以通过对这个接口的修改 直接使用已有的商业、开源、或之前开发出来的组件

来直接替换或直接实现我们所设计的候选的子系统

这样我们可以实现大规模的软件复用

今天的课就到这里 谢谢大家

面向对象分析与设计课程列表:

面向对象概述

-软件开发过程中的主要问题和好的解决方法

--软件开发过程中的主要问题和好的解决方法

--软件开发过程中的主要问题和好的解决方法

统一软件开发(RUP)

-RUP软件开发模型的特点

--RUP软件开发模型的特点

--RUP软件开发模型的特点

面向对象建模

-四个基本原则

--四个基本原则

--四个基本原则

-对象和类

--对象和类

--对象和类

-类之间的关系

--类之间的关系

--类之间的关系

需求概述

-用例模型

--用例模型

--用例模型

-用例之间的关系

--用例之间的关系

--用例之间的关系

-用例建模

--用例建模

--用例建模

分析与设计概述

-分析与设计概述

--分析与设计概述

--分析与设计概述

架构分析

-架构分析基本概念

--架构分析基本概念

--架构分析基本概念

-定义模型的高层组织结构

--定义模型的高层组织结构

--定义模型的高层组织结构

-确定分析机制、确定关键概念、创建用例实现

--确定分析机制、确定关键概念、创建用例实现

--确定分析机制、确定关键概念、创建用例实现

用例分析概述

-用例分析概述

--用例分析概述

--用例分析概述作业

-控制类

--控制类

--控制类

-用例行为和类的关系

--用例行为和类的关系

--用例行为与类的关系

识别设计类

-识别设计元素概述

--识别设计元素概述

--识别设计元素概述

-识别子系统及接口

--识别子系统和接口

--识别子系统及接口

描述运行态软件体系架构

-描述运行态软件体系架构

--描述运行态软件体系架构

--描述运行态软件体系架构

描述分布式系统架构

-描述分布式系统架构概述

--描述分布式系统架构概述

--描述分布式系统架构概述

用例设计

-用例设计描述

--用例设计描述

--用例设计描述

子系统设计

-子系统设计概述

--子系统设计概述

--子系统设计概述

类设计

-创建初始设计类、定义类操作方法

--创建初始设计类、定义类操作方法

--创建初始设计类、定义类操作方法

-定义类状态

--定义类状态

--定义类状态

-定义类之间的依赖关系、关联关系以及多重性设计

--定义类之间的依赖关系、关联关系以及多重性设计

--定义类之间的依赖关系、关联关系以及多重性设计

-定义类的泛化关系、解决用例冲突、非功能性需求

--定义类的泛化关系、解决用例冲突、非功能性需求

--定义类的泛化关系、解决用例冲突、非功能性需求

识别子系统和接口笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。