首页 > 代码库 > Mooc软件工程-02面向对象泛型

Mooc软件工程-02面向对象泛型

1 内聚

  模块

    语义上连续的一系列语句, 由边界符界定, 并且有一个聚集标识符

  常见的模块

    在面向对象中的 类, 方法

    在面向过程的 函数

  模块功能单一, 内部交互程度最大, 模块之间交互程度为最小

  模块的内聚: 模块内部的交互程度

  模块的耦合: 模块之间的交互程度

  模块的内聚性从低到高分为7种:

    偶然内聚 --> 逻辑内聚 --> 时间内聚 --> 过程内聚 --> 通信内聚 --> 功能内聚 --> 信息内聚

  软件模块的内聚性越低越差, 越高越好

  1) 偶然内聚: 模块内部的内容毫不相干

    问题: 可读性低, 可维护性低, 可重用性低

    解决: 拆分成不同的模块

  2) 逻辑内聚: 合并后的EFG就是逻辑性内聚

  技术分享

    问题: 接口复杂, 内部复杂, 内部难以修改, 效率低, 增加了调用模块和被调用模块的耦合度

  3) 时间性内聚: 在相同时间需要做的一些操作, 但是可能在本质上没有什么关联性

    问题: 模块内部关联度比较弱, 但是和别的模块可能关联性较强, 一般不可重用

  4) 过程内聚: 模块内部操作必须有先后顺序

    问题: 内部之间多个操作不是相互关联的, 只是有先后顺序, 因此该代码不容易被重用

  5) 通信内聚: 模块内部可能有多个操作, 这些操作是基于相同的输入数据或者输出数据

    问题: 主要是重用性较低

  6) 功能内聚:只具有一个功能或者一个操作

    将之前的内容进行拆分形成的

    具有较高的重用性

    纠错修改也比较容易, 减少更少的回归错误

    更加容易扩展

  7) 信息内聚: 执行多个任务, 每个任务都有自己的入口点,相对独立的代码, 并且在相同的数据结构进行操作

  技术分享

2 耦合

  模块的耦合, 模块之间的交互程度, 越低越好

  内容耦合 --> 公共耦合 --> 控制耦合 --> 印记耦合 --> 数据耦合

  1) 内容耦合: 一个模块可以直接访问另一个模块内部内容

    实例: 在一个类中, 可以直接访问类中某个变量并且可以进行一系列的操作

class A:    name = ‘a‘class B:    mA = A()    def setItem(self):        self.mA.name = ‘aa‘

  2) 公共耦合: 两个模块存取相同的变量(常见的是全局变量)

    尽量减少公共耦合, 尽量减少全局变量的使用, 防止全局变量在多个模块被修改

  3) 控制耦合: 一个模块向另一个模块传递控制参数, 最常见的就是传递开关变量, 而且必然导致被调用模块的逻辑内聚

  技术分享

    解决办法, 把逻辑判断模块写到A中, 将B的两个功能拆分成两个模块

  4) 印记耦合: 一个模块传入另一个模块的封装数据, 但是具体在模块中只使用一部分数据

    例如在类A中传入B的对象, 在A中只是使用B的两个成员变量

class A:    name = ‘a‘    age = 18    sex = ‘male‘    class B:    def setItem(self, obj):        self.name = obj.name        self.age = obj.age    b = B( A() )

    问题: 接口不清晰, 如果不通读代码, 不会知道哪些数据是需要的哪些是不需要的, 降低了可读性, 非常难重用

  5) 数据耦合: 所有参数都是同构的参数, 或者简单的数据, 或者是简单的数据结构且内部的数据都被使用

3 数据封装和信息隐藏      

  诸如操作系统的任务队列

  如果对每个操作写成一个模块, 固然是好事, 但是如果操纵的数据结构更改则所有就要更改

  所以形成新一个模块, 给各个操作共同使用一个数据结构

  这样就形成了信息内聚, 也是对数据的一种封装

  数据封装的优势:

    1) 这样的数据结构+数据操作 就形成了数据抽象, 使得编写最开始专注于数据结构和操作, 而不局限于怎么实现某些操作

    2) 在维护上, 数据封装可以使以后代码改动最小化, 减少出现回归错误的出现可能性

  信息隐藏: 对外提供接口, 而隐藏具体的实现细节

4 类的继承

  类: 抽象数据类型

  对象: 类派生出来的实例

  继承: 子类继承父类, 会取得父类所有的公开内容

  在UML中, 继承是用一个空心箭头指向, 被指向的是父类, 指向出去的是子类

    一个类基本由三部分组成, 第一部分是类名; 第二部分是由成员变量组成, 前面加上减号表示; 第三部分是成员函数, 由加号前面表示

  继承之间的关系可以用 is a kind of 来表示

5 类的聚合

  类的聚合是指多个类共同组成了一个大类

  具体有两个例子

  技术分享

  技术分享

  其中空心菱形表示脱离聚合的大类, 原有组成的小类可以继续存在

  实心菱形表示, 脱离了聚合的大类之后, 原有组成的小类将不可继续存在

6 类的关联和多重性

  类的关联关系是, 两个类之间, 既不是继承也不是聚合也不是组合关系, 两者之间可以通过一个动作来关联, 共同构成了主动宾关系

  如学生上课, 顾客下订单

  技术分享

  如果有多个动作关系, 那应该都列举出来, 例如借书的人与书之间的关系有借书, 还书, 续借, 预约

  技术分享

  具体在代码中的表现就是, 类中包含其他类的对象

  在描述类之间的关系的时候, 还需要考虑多重性

  也就是一对多, 多对一,多对多等之间的关系, 具体可以查看多重性指示器

  技术分享

7 多态与动态绑定

  在运行中, 正确的方法被激活, 这就是动态绑定

  方法可以被不同的类的对象调用, 这也就是多态  

8 面向对象泛型

  抽象数据类型的优势: 信息隐藏, 数据抽象, 过程抽象  

  结构化泛型当程序超过50000行之后, 变暴露出问题了

  此时使用面向对象泛型更为合适

  面向对象泛型主要是基于 将数据和操作绑定到一起; 或者说形成对象, 利用对象来绑定操作

9 UML

  UML 统一建模语言

  UML定义了多种图, 各种图的相互之间的关系如下

  技术分享

  用例图

  类图: 分为简单类图和复杂类图(实体类,边界类等详细类图)

  活动图

  状态图

  顺序图: 说明每个用例的具体实现过程

  协作图

  常见的UML工具

    visio; rational rose; magicdraw; argouml等 

Mooc软件工程-02面向对象泛型