UML-面向对象-GRASP总结
作者:互联网
UML总结
面向对象概念
-
什么是面向对象
- 面向对象(Object-Orientation,简称OO)是一种软件开发方法,一种编程范式,是一种系统建模的技术。通过分析系统内对象的交互来描述或建模一个系统,交互的对象最终以类的形式组织。OO方法由三部分组成:过程、标识、规则。
-
什么是面向对象编程
- 面向对象编程(Object-Orientation Programming,简称OOP)是按照OO的方法学来开发程序的过程。OOP的主要特征主要有以下
- 抽象(abstract)
- 忽略掉一个对象或实体的细节而只关注其本质特征的过程,简化功能与格式,帮助用户与对象交互。
- 封装(encapsulation)
- 隐藏数据和实现,提供公共方法供用户调用功能。
- 继承(inheritance)
- 通过存在的类型定义新类型的机制,通过继承实现代码重用,另外继承也是多态的基础。
- 多态(polymorphism)
- 一个名称,多种形式,基于继承的多态,调用方式时根据所给对象的不同选择不同的处理方式。
- 关联(association)
- 对象之间交互时的一种引用方式,当一个对象通过对另一个对象的引用去使用另一个对象的服务或操作时,两个对象之间便产生了关联。
- 聚合(aggregation)
- 关联关系的一种,一个对象成为另外一个对象的组成部分。是一种关系较强的关联。在两个对象之间存在"has a"这样的关系,一个对象作为另一个对象的属性存在,在外部对象被生产时,可由客户端指定与其关联的内部对象。
- 组合(composition)
- 当一个对象包含另一个对象时,外部对象负责管理内部对象的生命周期的情况,关联关系中最强烈的一种,内部对象的创建由外部对象自己控制。外部对象不存在时,内部对象也不能存在。
- 内聚和耦合(cohesion & coupling)
- 内聚:度量一个类独立完成某项工作的能力
- 耦合:度量系统内或系统之间依赖关系的复杂度。
- 设计原则:增加内聚,减少耦合。
- 抽象(abstract)
- 面向对象编程(Object-Orientation Programming,简称OOP)是按照OO的方法学来开发程序的过程。OOP的主要特征主要有以下
-
域模型
- 域模型是面向对象的,在面向对象术语中域明星也可称为设计模型,域模型由以下内容组成:具有状态和行为的域对象。
- 域对象的分类
- 实体域对象
- 实体域对象可以代表人、地点、事物或概念。
- 过程域对象
- 过程域对象代表应用中的业务逻辑或流程。
- 事件域对象
- 事件域对象代表应用中的一些事件。
- 实体域对象
- 域对象之间的关系
- 关联(Association)
- 关联指的是类之间的引用关系,这是实体域对象之间最普遍的一种关系。关联可以分为一对一、一对多和多对多关联。
- 依赖(Dependency)
- 依赖指的是类之间的访问关系。
- 聚集(Aggregation)
- 聚集指的是整体与部分之间的关系。
- 一般化(泛化)(Generalization)
- 泛化指的是类之间的继承关系。
- 关联(Association)
- 域对象的分类
- 域模型是面向对象的,在面向对象术语中域明星也可称为设计模型,域模型由以下内容组成:具有状态和行为的域对象。
-
域模型的分类
- 贫血域模型
- 只是简单的数据载体,没有任何业务。
- 充血域模型
- 除数据外还有持久化(和事务逻辑)无关的业务实现。
- 贫血域模型
-
对象
- 是一个客观存在的、唯一的实体,是面向对象编程过程中分析与解决问题的出发点和基础,拥有自己的标识、数据和行为,可以简单或者复杂,可以抽象或具体,在OOP中是一个类的动态实例。
-
类
- 类是对象的模板,对象通过类实例化产生,一个类可以创建多个对象。
-
OOAD
- OOAD(Object Oriented Analysis Design)面向对象的分析与设计是根据OO的方法学,对软件系统进行分析和设计的过程,分为OOA分析阶段、OOD设计阶段。
- 分析阶段(OOA)主要解决以下问题
- 建立针对业务问题域的清晰视图。
- 列出系统必须要完成的核心任务。
- 针对问题域建立公共词汇表。
- 列出针对此问题域的最佳解决方案。
- 设计阶段(OOD)主要解决以下问题
- 如何解决具体的业务问题。
- 引入系统工作所需的支持元素。
- 定义系统的实现策略。
- 分析阶段(OOA)主要解决以下问题
- OOAD(Object Oriented Analysis Design)面向对象的分析与设计是根据OO的方法学,对软件系统进行分析和设计的过程,分为OOA分析阶段、OOD设计阶段。
-
OOAD开发过程
- 统一软件开发过程是一个迭代、递增的开发过程。
- 迭代、递增生命周期
- 项目是迭代的、递增的,迭代指生命周期中一个步骤,迭代导致递增或者是整个项目的增长,大项目分为子项目,使用uml工具。在每个迭代的阶段,应该做以下工作。
- 选择并分析相关用例。
- 根据所选架构进行设计。
- 在组件层次实现设计。
- 验证组件满足用例的需要。
- 当一次迭代满足目标后,开发进入下一个迭代周期。
- 每一个周期包含一次或多次迭代。
- 一个阶段的结束称之为里程碑(milestone)。
- 项目是迭代的、递增的,迭代指生命周期中一个步骤,迭代导致递增或者是整个项目的增长,大项目分为子项目,使用uml工具。在每个迭代的阶段,应该做以下工作。
- 迭代、递增生命周期的主要阶段
- 初始化阶段
- 项目启动
- 建立业务类型
- 定义业务类型域
- 找出主要的风险因素
- 定义项目需求的外延
- 创建业务问题域的相关说明文档
- 细化阶段
- 高层的分析与设计
- 建立项目的基础框架
- 监督主要的风险因素
- 制定达成项目目标的创建计划
- 构建阶段
- 代码及功能的实现
- 移交阶段
- 向用户发布产品。
- beta测试
- 执行性能调优,用户培训和接收测试。
- 每一次递增都由5部分工作流组成
- 需求和初始分析
- 分析
- 设计
- 实现
- 测试
- 每一次迭代执行工作流的深度不同
- 早期的迭代在深度上覆盖初始工作流,后期迭代在深度上覆盖后期工作流。
- 初始化阶段
- 迭代、递增生命周期的优势
- 降低成本
- 便于更好的维护项目进度
- 便于团队的协作开发
- 便于适应用户需求的动态变化
- 迭代、递增生命周期
- 统一软件开发过程是一个迭代、递增的开发过程。
-
GRASP(General Responsibility Assignment Software Patterns)通用职责分配,GRASP一共包括9种模式,如何决定一个系统有多少对象,每个对象都包括什么职责,GRASP模式给出了最基本的指导原则。初学者应该尽快掌握、理解这些原则,因为这是如何设计一个面向对象系统的基础。可以说,GRASP是学习使用设计模式的基础。
-
Infomation Expert(信息专家)
信息专家模式是面向设计的最基本原则,是我们平时使用最多,应该跟我们的思想融为一体的原则。也就是说,我们设计对象(类)的时候,如果某个类拥有完成某个职责所需要的所有信息,那么这个职责就应该分配给这个类来实现。这时,这个类就是相对于这个职责的信息专家。-
示例
常见的网上商店的购物车(ShopCar),需要让每种商品(SKU)只在购物车内出现一次,购买相同商品,只需要更新商品的数量即可。如下图:
针对这个问题需要权衡的是,比较商品是否相同的方法需要放到哪个类里来实现呢?分析业务得知需要根据商品的编号(SKUID)来唯一区分商品,而商品编号是唯一存在于商品类的,所以根据信息专家模式,应该把比较商品是否相同的方法放在商品类里。
-
-
Creator(创造者)
实际应用中,符合下列任一条件的时候,都应该由类 A 来创建类 B,这时 A 是 B 的创建者:-
A 是 B 的聚合
-
A 是 B 的容器
-
A 持有初始化 B 的信息(数据)
-
A 记录 B 的实例
-
A 频繁使用 B
如果一个类创建了另外一个类,那么这两个类之间就有了耦合,也可以说产生了依赖关系。依赖或耦合本身是没有错误的,但是他们带来的问题就是在以后的维护中产生连锁反应,而必要的耦合是逃不掉的,我们能做的就是正确的创建耦合关系,不要随便建立类之间的依赖关系,那么该如何去做呢?就是要遵守创建者模式规定的基本原则,凡是不符合以上条件的,都不能随便用 A 创建 B。 -
示例 因为订单(Order)是商品(SKU)的容器,所以应该由订单来创建商品。如下图:
这里因为订单是商品的容器,也只有订单持有初始化商品的信息,所以这个耦合关系是正确的且没有办法避免的,所以由订单来创建商品。
-
-
Low coupling(低耦合)
- 低耦合模式的意思就是要我们尽可能地减少类之间的连接。其作用非常重要:
- 低耦合降低了因一个类的变化而影响其他类的范围。
- 低耦合使用类更容易理解,因为类会变得简单,更内聚。
- 下面这些情况会造成类 A、B 之间的耦合:
- A 是 B 的属性
- A 调用 B 的实例的方法
- A 的方法中引用的 B,例如 B 是 A 方法的返回值或参数。
- A 是 B 的子类,或者 A 实现 B
- 关于低耦合,还有下面一些基本原则:
- Don’t Talk to Strangers 原则
意思就是说,不需要通信的两个对象之间,不要进行无谓的连接,连接了就有可能产生问题,不连接就一了百了了。 - 如果 A 已经和 B 有连接,如果分配 A 的职责给 B 不合适的话(违反信息专家模式),那么就把 B 的职责分配给 A。
- 两个不同模块的内部类之间不能连接,否则比招报应!
- Don’t Talk to Strangers 原则
- 示例 Creator 模式的例子里,实际业务中需要另一个出货人来清点订单(Order)上的商品(SKU),并计算出商品的总价,但是由于订单和商品之间的耦合已经存在了,那么把这个职责分配给订单更合适,这样可以降低耦合,以便降低系统的复杂性。如下图:
这里我们在订单类里增加了一个 TotalPrice() 方法来执行计算总价的职责,没有增加不必要的耦合
- 低耦合模式的意思就是要我们尽可能地减少类之间的连接。其作用非常重要:
-
High cohesion(高内聚)
高内聚的意思是给类尽量分配内聚的职责,也可以说成是功能性内聚的职责。即功能性紧密相关的职责应该放在一个类里,并共同完成有限的功能,那么就是高内聚合。这样更有利于类的理解和重用,也便于类的维护。高内聚也可以说是一种隔离,就像人体由很多独立的细胞组成,大厦由很多砖头、钢筋、混凝土组成,每一个部分(类)都有自己独立的职责和特性,每一个部分内部发生了问题,也不会影响其他部分,因为高内聚的对象之间是隔离开的。-
示例 一个订单数据存取类(OrderDAO),订单即可以保存为 Excel 模式,也可以保存到数据库中;那么,不同的职责最好由不同的类来实现,这样才是高内聚的设计,如下图:
这里我们把两种不同的数据存储功能分别放在了两个类里来实现,这样如果未来保存到 Excel 的功能发生错误,那么就去检查 OrderDAOExcel 类就可以了,这样也使系统更模块化,方便划分任务,比如这两个类就可以分配到不同的人同时进行开发,这样也提高了团队协作和开发进度。
-
-
Controller(控制器)
用来接受和处理系统事件的职责,一般应该分配给一个能够代表整个系统的类,这样的类通常被命名为“XX处理器”、“XX协调器”或“XX会话”。关于控制器类,有如下原则:- 系统事件的接收与处理通常由一个高级类来代替。
- 一个子系统会有很多控制类,分别处理不同的事务。
-
Polymorphism(多态)
这里的多态跟 OO 三大基本特征之一的“多态”是一个意思。-
示例 我们想设计一个绘画程序,要支持可以画不同类型的图形,我们定义一个抽象类 Shape,矩形(Rectangle)、圆形(Round)分别继承这个抽象类,并重写(override)Shape 类里的Draw() 方法,这样我们就可以使用同样的接口(Shape抽象类)绘制出不同的图形,如下图:
这样的设计更符合高内聚和低耦合原则,虽然后来我们又增加了一个菱形(Diamond)类,对整个系统结构也没有任何影响,只要增加一个继承 Shape 类就行了。
-
-
Pure Fabrication(纯虚构)
这里的纯虚构跟我们常说说的纯虚构函数意思相近。高内聚低耦合,是系统设计的终极目标,但是内聚和耦合永远都是矛盾对立的。高内聚以为这拆分出更多数量的类,但是对象之间需要协作来完成任务,这又造成了高耦合,反过来依然。该如何解决这个矛盾呢?这个时候就需要纯虚构模式,由一个纯虚构的类来协调内聚和耦合,可以在一定程度上解决上述问题。-
示例 上面多态模式的例子,如果我们的绘图程序需要支持不同的系统,那么因为不同系统的API结构不同,绘图功能也需要不同的实现方式,那么该如何设计更合适呢?如下图:
这里我们可以看到,因为增加了纯虚构类AbstractShape,不论是哪个系统都可以通过AbstractShape 类来绘制图形,我们即没有降低原来的内聚性,也没有增加过多的耦合,可谓鱼肉和熊掌兼得。
-
-
Indirection(间接)
“间接”顾名思义,就是这个事不能直接来办,需要绕个弯才行。绕个弯的好处就是,本来直接会连接在一起的对象彼此隔离开了,一个变动不会影响另一个。就像我在前面的低耦合模式里说的一样,“两个不同模块的内部类之间不能直接连接”,但是我们可以通过中间类来间接连接两个不同的模块,这样对于这两个模块来说,他们之间仍然是没有耦合/依赖关系的。 -
Protected Variations(受保护变化)
预先找出不稳定的变化点,使用统一的接口封装起来,如果未来发生变化的时候,可以通过接口扩展新的功能,而不需要去修改原来旧的实现。也可以把这个模式理解为 OCP(开闭原则),就是说一个软件实体应当对拓展开发,对修改关闭。在设计一个模块的时候,要保证这个模块可以在不需要被修改的前提下可以得到拓展。这样做的好处就是通过拓展给系统提供了新的职责,以满足新的需求,同时又没有改变系统原来的功能。
-
-
uml:统一建模语言是一种图形化的语言,它可以帮助我们在OOAD过程中标识元素,构建模块,分析过程并通过文档说明系统中的重要细节。
-
uml图分类
- 静态模型(static model)
- 用例图(use case diagrams)
- 类图(class diagrams)
- 对象图(object diagrams)
- 组件图(component diagrams)
- 部署图(deployment diagrams)
- 动态模型(dynamic model)
- 时序图(sequence diagrams)
- 协作图(collaboration diagrams)
- 状态图(state chart diagrams)
- 活动图(activity diagrams)
- 静态模型(static model)
-
uml的扩展机制
- 注释(comments)
- 构造型(stereotypes)
- 标记值(tagged values)
- 约束(constraints)
用例图(usecase Diagrams)
- 用例图主要回答了两个问题:1、是谁用软件。2、软件的功能。从用户的角度描述了系统的功能,并指出各个功能的执行者,强调用户的使用者,系统为执行者完成哪些功能。
类图(Class Diagrams)
-
用户根据用例图抽象成类,描述类的内部结构和类与类之间的关系,是一种静态结构图。 在UML类图中,常见的有以下几种关系:
- 泛化(Generalization)
- 实现(Realization)
- 关联(Association)
- 聚合(Aggregation)
- 组合(Composition)
- 依赖(Dependency)
-
泛化
泛化是一种继承的关系,表示一般与特殊之间的关系,它指定了子类如何继承父类的所有特征和行为,例如:老虎是动物的一种,既有老虎的特征也有动物的共性。
-
实现
实现是一种类与接口的关系,表示类是接口所有特征与行为的实现
-
关联
是一种拥有的关系,它使一个类知道另一个类的属性和方法,如:老师和学生,丈夫和妻子关联可以是双向的,也可以是单向的,双向的关联可以有两个箭头也可以没有箭头,单向的关联有一个箭头。代码体现:成员变量
-
聚合
是整体和部分的关系,且部分可以离开整体单独存在,如车和轮胎是整体和部分的关系,轮胎离开车也可以独立存在,聚合是关联关系的一种,是强的关联关系,关联和聚合在语法上无法区分,必须考察具体的逻辑关系,带空心菱形的实线,菱形指向整体,箭头指向部分。代码体现:成员变量
-
组合
是整体和部分的关系,但部分不能离开整体单独存在,如公司和部门是整体和部分的关系,没有公司就不存在部门。组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。带实心菱形的实线,菱形指向整体。代码体现:成员变量
-
依赖
是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖。代码体现:局部变量,方法的参数或者对静态方法的调用。带箭头的虚线指向被使用者。
对象图(Object Diagrams)
描述的是参与交互的各个对象在交互过程中某一时刻的状态。对象图可以被看作是类图在某一时刻的实例。
状态图(StateChart Diagrams)
是一种由状态、变迁、事件和活动组成的状态机,用来描述类的对象所有可能的状态以及时间发生时状态的转移条件。
活动图(Activity Diagrams)
活动图是状态图的一种特殊情况,这些状态大都处于活动状态,本质是一种流程图,它描述了活动到活动的控制流。交互图强调的是对象到对象的控制流,而活动图则强调的是活动到活动的控制流。活动图是一种表述过程基理、业务过程以及工作流的技术。它可以用来对业务过程、工作流建模,也可以对用例实现甚至是程序实现来建模。
-
带泳道的活动图,泳道表示每个活动由那些人或者那些部门负责完成。
-
带对象流的活动图,用活动图来描述某个对象时,可以把涉及到的对象放置在活动图中,并用一个依赖将其连接到进行创建、修改和撤销的动作或者活动状态上,对象的这种使用方法就构成了对象流,对象流用带有箭头的虚线表示。
时序图(Sequence Diagrams)
交互图的一种,描述了对象之间消息发送的先后顺序,强调时间顺序。时序图的主要用途是把用例表达的需求转化为进一步、更加正式层次的精细表达,用例常常被细化为一个或者更多的时序图,同时时序图更有效地描述如何分配各个类的职责以及各类具有相应职责的原因。
消息用从一个对象的生命线到另一个对象生命线的箭头表示。箭头以时间顺序在图中从上到下排列。
- 序列图中涉及到的元素
-
生命线
生命线名称可带下划线。当使用下划线时,意味着序列图中的生命线代表一个类的特定实例。
-
同步消息
同步等待消息
-
异步消息
异步发送消息,不需等待
-
注释
-
约束
-
组合
组合片段用来解决交互执行的条件及方式。它允许在序列图中直接表示逻辑组件,用于通过指定条件或子进程的应用区域,为任何生命线的任何部分定义特殊条件和子进程。常用的组合片段有:抉择、选项、循环、并行。
-
协作图(Collaboration Diagrams)
交互图的一种,描述了收发消息的对象的组织关系,强调对象之间的合作关系。时序图按照时间顺序布图,而协作图按照空间结构布图
构件图(Component Diagrams)
构件图是用来表示系统中构件与构件之间,类或接口与构件之间的关系图。其中,构建图之间的关系表现为依赖关系,定义的类或接口与类之间的关系表现为依赖关系或实现关系。
部署图(Deployment Diagrams)
描述了系统运行时进行处理的结点以及在结点上活动的构件的配置。强调了物理设备以及之间的连接关系。
部署模型的目的:
描述一个具体应用的主要部署结构,通过对各种硬件,在硬件中的软件以及各种连接协议的显示,可以很好的描述系统是如何部署的;平衡系统运行时的计算资源分布;可以通过连接描述组织的硬件网络结构或者是嵌入式系统等具有多种硬件和软件相关的系统运行模型。
标签:关系,迭代,面向对象,对象,耦合,内聚,GRASP,UML,一个 来源: https://blog.csdn.net/wangqinyi574110/article/details/113401263