UML总结
面向对象概念
@H_502_8@什么是面向对象
@H_502_8@什么是面向对象编程
@H_502_8@域模型
@H_502_8@域模型的分类
@H_502_8@对象
@H_502_8@类
@H_502_8@OOAD
@H_502_8@OOAD开发过程
@H_502_8@GRASP(General Responsibility Assignment Software Patterns)通用职责分配,GRASP一共包括9种模式,如何决定一个系统有多少对象,每个对象都包括什么职责,GRASP模式给出了最基本的指导原则。初学者应该尽快掌握、理解这些原则,因为这是如何设计一个面向对象系统的基础。可以说,GRASP是学习使用设计模式的基础。
@H_502_8@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(低耦合)
@H_502_8@意思就是说,不需要通信的两个对象之间,不要进行无谓的连接,连接了就有可能产生问题,不连接就一了百了了。
这里我们在订单类里增加了一个 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图分类
@H_502_8@uml的扩展机制
@H_502_8@用例图(usecase Diagrams)
@H_502_8@类图(Class Diagrams)
@H_502_8@用户根据用例图抽象成类,描述类的内部结构和类与类之间的关系,是一种静态结构图。 在UML类图中,常见的有以下几种关系:
@H_502_8@泛化
泛化是一种继承的关系,表示一般与特殊之间的关系,它指定了子类如何继承父类的所有特征和行为,例如:老虎是动物的一种,既有老虎的特征也有动物的共性。
实现
实现是一种类与接口的关系,表示类是接口所有特征与行为的实现
关联
是一种拥有的关系,它使一个类知道另一个类的属性和方法,如:老师和学生,丈夫和妻子关联可以是双向的,也可以是单向的,双向的关联可以有两个箭头也可以没有箭头,单向的关联有一个箭头。代码体现:成员变量
聚合
是整体和部分的关系,且部分可以离开整体单独存在,如车和轮胎是整体和部分的关系,轮胎离开车也可以独立存在,聚合是关联关系的一种,是强的关联关系,关联和聚合在语法上无法区分,必须考察具体的逻辑关系,带空心菱形的实线,菱形指向整体,箭头指向部分。代码体现:成员变量
组合
是整体和部分的关系,但部分不能离开整体单独存在,如公司和部门是整体和部分的关系,没有公司就不存在部门。组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。带实心菱形的实线,菱形指向整体。代码体现:成员变量
依赖
是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖。代码体现:局部变量,方法的参数或者对静态方法的调用。带箭头的虚线指向被使用者。
对象图(Object Diagrams)
描述的是参与交互的各个对象在交互过程中某一时刻的状态。对象图可以被看作是类图在某一时刻的实例。
状态图(StateChart Diagrams)
是一种由状态、变迁、事件和活动组成的状态机,用来描述类的对象所有可能的状态以及时间发生时状态的转移条件。
活动图(Activity Diagrams)
活动图是状态图的一种特殊情况,这些状态大都处于活动状态,本质是一种流程图,它描述了活动到活动的控制流。交互图强调的是对象到对象的控制流,而活动图则强调的是活动到活动的控制流。活动图是一种表述过程基理、业务过程以及工作流的技术。它可以用来对业务过程、工作流建模,也可以对用例实现甚至是程序实现来建模。
@H_502_8@带泳道的活动图,泳道表示每个活动由那些人或者那些部门负责完成。
带对象流的活动图,用活动图来描述某个对象时,可以把涉及到的对象放置在活动图中,并用一个依赖将其连接到进行创建、修改和撤销的动作或者活动状态上,对象的这种使用方法就构成了对象流,对象流用带有箭头的虚线表示。
时序图(Sequence Diagrams)
交互图的一种,描述了对象之间消息发送的先后顺序,强调时间顺序。时序图的主要用途是把用例表达的需求转化为进一步、更加正式层次的精细表达,用例常常被细化为一个或者更多的时序图,同时时序图更有效地描述如何分配各个类的职责以及各类具有相应职责的原因。
消息用从一个对象的生命线到另一个对象生命线的箭头表示。箭头以时间顺序在图中从上到下排列。
@H_502_8@生命线
生命线名称可带下划线。当使用下划线时,意味着序列图中的生命线代表一个类的特定实例。
同步消息
同步等待消息
异步消息
异步发送消息,不需等待
注释
约束
组合
组合片段用来解决交互执行的条件及方式。它允许在序列图中直接表示逻辑组件,用于通过指定条件或子进程的应用区域,为任何生命线的任何部分定义特殊条件和子进程。常用的组合片段有:抉择、选项、循环、并行。
协作图(Collaboration Diagrams)
交互图的一种,描述了收发消息的对象的组织关系,强调对象之间的合作关系。时序图按照时间顺序布图,而协作图按照空间结构布图
构件图(Component Diagrams)
构件图是用来表示系统中构件与构件之间,类或接口与构件之间的关系图。其中,构建图之间的关系表现为依赖关系,定义的类或接口与类之间的关系表现为依赖关系或实现关系。
部署图(Deployment Diagrams)
描述了系统运行时进行处理的结点以及在结点上活动的构件的配置。强调了物理设备以及之间的连接关系。
部署模型的目的:
描述一个具体应用的主要部署结构,通过对各种硬件,在硬件中的软件以及各种连接协议的显示,可以很好的描述系统是如何部署的;平衡系统运行时的计算资源分布;可以通过连接描述组织的硬件网络结构或者是嵌入式系统等具有多种硬件和软件相关的系统运行模型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。