zoukankan      html  css  js  c++  java
  • 学习设计模式之前你必须掌握的-看懂UML类图

    描述设计模式的时候会经常用到UML类图来描述类之间的静态结构。此篇的用意仅仅在于让各位看官能够看懂UML类图,并且弄清楚UML类图中的几种关系。

    -在之后的设计模式学习过程中仅此两点足矣,更高深的不在此篇讨论范围内。

      UML类图是UML(unified modeling language,标准建模语言)五种图示法中静态图的一种-用来描述系统中类的静态结构,不仅定义系统中的类,表示类之间的联系如关联、依赖、聚合等,也包括类的内部结构(类的属性和操作)。类图描述的是一种静态关系,在系统的整个生命周期都是有效的。

      如果诸位看官们有拜读过一些关于设计模式的动动,就一定有接触UML类图,可以说学习类图是设计模式之旅的起点,下面我们来看一个示例。

     

    一,类的表示

      想必电影终结者是深入人心,既然我的英文名与主角同名,那就来个终结者T-800(阿诺肌肉辛格)把。

        

      通常UML类图中的一个节点就是一个类或者接口。从这个T-800的类我们可以看出,

    • 类是由一个三层的矩形组成的:顶部显示类名,中部显示特性(属性或字段等),底部显示操作(方法或行为)
    • 特性的格式是: 可见性修饰符 属性名类型 <=默认值>。T-800的特性有型号,目标等。
    • 操作的格式是: 可见性修饰符 操作名(<参数列表>):返回类型。操作参数的格式则是<in/out>参数名:类型。in/out来指示参数是输入还是输出类型。T-800的操作是重启。
    • 在UML类图中可见性'+'表示public,'-'表示private,'#'则表示protected

      除了上述例子中可见的UML类图的规则之外,这里再补充几点:

    • 如果这个类是抽象类,那么类名就必须使用斜体字。
    • 如果在一个类图中我们只想显示高层细节,那下面的两个区域的信息不是必要的。
    • 操作的参数in/out,除非使用早期的编程语言,这个in/out指示器会有所帮助,一般情况下省略。

    二,接口的表示

      接口的表示有两种方式:

    • 矩形表示与类的表示相似,不过需要在接口名称上方标注<<interface>>,并且接口只有两个部份,接口名和方法。
    • 棒棒糖表示法,在棒棒糖的名字就是接口的名字,其方法写在负责实现它的类的操作部份。这里省略了T-800的特性和操作细节。

    三,UML类图中的关系

      1.泛化关系(Generalization):使用带空心三角形的实线表示。

      不管是基本款T-800还是液体金属T-1000,还是最新款的T-X,它们都属于终结者系列机器人: 

      

      

      泛化关系相当于面向对象中的继承关系。类T-800,T-1000,T-X都继承自抽象类(注意类名是斜体)终结者类,则称终结者类是前三者的一个泛化。

      在UML中对泛化关系有三个要求,

    • 子类需要继承父类所有的特性和操作,如上述的三个子类都继承了父类的型号和目标字段。
    • 子类中除了与父类一致的信息外,还应包括额外的信息。比如新的操作:T-800可以重启(重新设定目标),T-1000可以液化,T-X能控制其他机械。
    • 可以使用父类的地方,也可以使用子类。

      2.实现关系(Emlpementation):使用带空心三角形的虚线表示。

      在上面的例子中T-800实现了攻击接口,就引申出了实现关系。

      

      在UML中接口就是一个操作的集合。

      3.依赖关系(Dependency):使用带箭头的虚线表示

      机器人们依赖于内部的指令来行动。也可以通过指令来重启T-800来执行其他任务。

      

      依赖是一种最弱的横向关系。假设A类的变化引起了B类的变化,则称B依赖于A。表现在代码上依赖关系一般有如下三种情况:

    • A类是B类中(某个方法)的局部变量。
    • A类是B类中某个方法的参数。
    • A类向B类发送消息,从而影响B类变化。

      4.关联关系(Association):使用实线表示(可带箭头)。

      从这开始大家可能就会混掉了。不过没关系,最后会辨析这几种关系。如果看官们熟悉魔兽世界,两个一起打22竞技场的好基友就是1对1的关联关系。

      

      如果甲是治疗,那这个实线就可以带箭头指向乙。因为只需要前者奶好后者,后者只管砍敌人(当然这是很低端的做法吼吼)。

         关联往往是相互的。关联的两个对象彼此间没有任何强制性的约束,可以随时解除关系或是进行关联,生命期问题上没有任何约定。

      被关联的对象还可以再被别的对象关联,所以关联是可以共享的。

      数字表示了关联两者之前的多重性,一般有“*”表示不限,“1”表示有且只有一个,“0...”表示0个或多个,“0,1”表示0个或1个,“m...n”表示m~n个,“m...*”表示至少m个。

      5.聚合关系(Aggregation):使用带空心棱形的实线表示。

      聚合关系表示一种弱的整体对部份的拥有关系。主要体现在两者的生命周期不同,部份可以脱离整体存在。

      被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。

      比如魔兽中的天灾军团,天灾们受巫妖王的思想控制,现在小阿被脚男们推倒干掉了天灾军团完蛋了,

      旗下的死亡骑士们就追随黑风骑士团效忠联盟或者部落,并不意味着他们也就OVER了。

      

      其实聚合也是关联关系的一个特例。但更紧密,你会跟女朋友亲密的分享一切,但不会给一个来串门的朋友配自己家的钥匙把。

      6.组合关系(Composition):使用带实心棱形的实线表示。

      组合关系表示一种强的整体对部份的拥有关系。

      在终结者系列电影中,天网是一套拥有了自己意识军事防御体系的控制程序,控制着麾下的所有机械军团。

      天网系统被摧毁,机械军团就成了一堆废铜烂铁了。(刚才跑题到魔兽世界去了,呃....)

      

      主体控制着部份的创建和销毁或转移,部份的生命周期由主体掌握。这就是组合关系。其实也是关联关系的一种特例。

    四,几种关系的联系与区别

      泛化与实现是两个纵向关系,这两者没什么异议很好区别。

      依赖,关联,聚合,组合这四个横向关系,由弱到强,区分倒是比较麻烦。

      依赖(...use a...) 与其他三者最大的区别在于仅仅是使用,并不持有其依赖对象的引用。代码的表现就是并不是类的成员之一,而是其方法的参数或局部变量。

      聚合(... owns a ...),组合(... is a part of  ...),都是关联(...has a...)的特例。

      但关联更倾向与两个独立平等的事物之前的关系,比如好基友,或者好朋友,然而聚合和组合倾向于整体和部份的关系。

      聚合和组合的区别,只是在于整体对部份生命周期的把握程度。

      聚合就像是电脑坏了的话,硬盘之类的东西是可以继续用的。组合就像是二极管收音机坏了,那就整个报废了(对于一般人来说...高手不要吐槽说你会修...)

      ----------------------------------------------偶是分割线---------------------------------------------------

      End:补充一下类图中的注释Like this:

      

      最近在学习设计模式,可能的话后面会推出一个系列。我写的动动一般都是面对跟我一样的初学者。希望大家到时候捧场吼吼!

      以上的图都是使用MS Visio画出来的,如果大家感兴趣我也可以写一篇关于使用Visio画UML类图的文章^_^。

      

    分类: 设计模式
    标签: 设计模式
  • 相关阅读:
    leetcode10 正则表达式匹配 dp
    AS技巧合集「调试技巧篇」
    AS技巧合集「编码技巧篇」
    AS技巧合集「常用技巧篇」
    Android studio:Groovy 与 Gradle 基础【三】
    Android Studio :Android Studio 与 Gradle 深入【二】
    Android studio:从Eclipse迁移到Android Studio【一】
    Anroid Studio入门
    54. Android中adb常用命令及应用常用目录
    53. Android常用工具类
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2471966.html
Copyright © 2011-2022 走看看