深入浅出UML类图

深入浅出UML类图(一)

       UML 2.013种图形中,类图是使用频率最高的UML图之一。Martin Fowler在其著作《UML Distilled: A Brief Guide to the Standard Object Modeling Language, Third Edition》(《UML精粹:标准对象建模语言简明指南(第3版)》)中有这么一段:“If someone were to come up to you in a dark alley and say, 'Psst, wanna see a UML diagram?' that diagram would probably be a class diagram. The majority of UML diagrams I see are class diagrams.”如果有人在黑暗的小巷中向你走来并对你说:嘿,想不想看一张UML图?那么这张图很有可能就是一张类图,我所见过的大部分的UML图都是类图),由此可见类图的重要性。     

       类图用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解,是系统编码和测试的重要模型依据。

      1.

      (Class)封装了数据和行为,是面向对象的重要组成部分,它是將具有相同属性、操作之关系对象集合的总称。在定义类的时候,将类的职责分解成为类的属性操作(*即方法)。类的属性即类的数据职责,类的操作即类的行为职责。

      在软件系统运行时,类将被实例化(Instance)成对象(Object)对象对应于某个具体的事物。类图(Class Diagram)描述系统的静态结构,它用来描述不同的类以及它们之间的关系。

      在系统分析与设计阶段,通常可將类區分为三种:分别是实体类(Entity Class)控制类(Control Class)边界类(Boundary Class),下面对这三种类加以简要说明:

      (1) 实体类:实体类对应系统需求中的每个主体,它们通常需要保存在永久存储体中,一般使用数据库表或文件来记录,实体类通常来自於需求说明中的名词,如学生、商品等。

      (2) 控制类:控制类用于体现应用程序业务操作的执行逻辑,将控制类抽象出来主要可降低界面和数据库之间的耦合度。控制类一般是由(动词+名词)转化而来,如增加商品对应有一个商品增加类,注册对应有一个用户注册类等。

      (3) 边界类:边界类用于对外部用户与系统之间的交互对象进行抽象,如对话框、窗口、菜单等。

      在面向对象分析和设计的初级阶段,通常首先要识别出实体类來绘制初始类图,這種类图也可称为领域模型,包括实体类及其它们之间的相互关系。

      2. 类的UML图示

      UML中,类之使用要包含类名、属性和操作且带有分隔线的长方形来表示,如定义一个Employee类,它包含属性nameageemail,以及操作modifyInfo(),在UML类图中该类如图1所示:

https://i-blog.csdnimg.cn/blog_migrate/ff88dee494b848e720362e03d1847ba6.jpeg

1 类的UML图示

      1对应的Java代码片段如下:

public class Employee {

          private String name;

          private int age;

          private String email;

         

          public void modifyInfo() {

                   ......

          }

}

      UML类图中,类一般由三部分组成:

      (1) 第一部分是类名:类名是一个字符串。

      (2) 第二部分是类的属性(Attributes):即类的成员变量。

      UML规定属性的表示方式为:

可见性 名稱:資料型態 [ = 預設值 ]

      其中:

  • 可见性”:表示该属性对于类外是否可见,包括公有(public)、私有(private)和受保护(protected)三种,在类图中分别用符号+-#表示。
  • 名稱”:表示类的成員數據名,以字符串表示之。
  • 資料型態”:表示属性被定義之数据类型,可為系統提供之基本类型,也可是用户自定义类型
  • 預設值”:是一个可选项,代表属性的初始值

      (3) 第三部分是类的操作(Operations):即类的成员方法(method),此是作為类的实例对象可使用的行为。

      UML规定成員操作方法的表示方式为:

可见性  名称(参数列表) :返回类型

      其中:

  • 可见性:同属性定义之可见性。
  • 名称”:即方法名,一般以(動詞+名詞)之字符串表示之。
  • 参数列表”:表示方法所用的参数,其语法与成員属性的定义相似,参数个数可為任意多數或無,如多个参数之间用逗号隔开。
  • 返回类型”:表示方法回傳值之資料型態,可為基本类型或用户自定义类型,也可以是空类型(void),但須注意如果是构造方法,则无回傳类型

      在下类图2中,操作method1的可见性为public(+),带入了一个Object类型的参数par,返回值为空(void);操作method2的可见性为protected(#),无参数,返回值为String类型;操作method3的可见性为private(-),包含两个参数,其中一个参数为int类型,另一个为int[]类型,返回值为int类型。

https://i-blog.csdnimg.cn/blog_migrate/2fd37e45824461865495fc1d03adc486.jpeg

2 类图操作说明示意图

      由于在Java语言中可允许嵌入内部类,因此可能会出现包含第四个部分的类图,如图3所示:

https://i-blog.csdnimg.cn/blog_migrate/478732b6ec963829826ab530f07b5d0c.jpeg

3 嵌入内部类的类图

深入浅出UML类图(二)

类与类之间的关系(1

      在软件系统中,类并不是孤立存在的,类与类之间存在各种关系,UML提供了不同类型关系的表示方式。

      1. 关联关系

      关联(Association)关系用于表示类与另一类具有耦合联系,如汽车和轮胎、师傅和徒弟、班级和学生等等,以实线表示之,在编程语言中要实现关联关系时,則通常将类作为另一类的成员屬性。如要在类图來表示其关联关系时可在关联线上标注角色名,一般使用(动词或者名词)來表示角色名,但角色名不是必须的,可視需要作增添,主要目的是使类之间的关系更加明确。

      如在一个登录界面类LoginForm中要包含JButton类型的注册按钮loginButton,它们之间便可以关联关系表示之,代码实现时可以在LoginForm中定义一个名为loginButton的成員属性變量,其类型为JButton。如图1所示:

https://i-blog.csdnimg.cn/blog_migrate/8641d0afa657309653c53266e3a1a336.jpeg

1 关联关系实例

      1对应的Java代码片段如下:

public class LoginForm {

private JButton loginButton;           //定义为成员屬性

……

}

 

public class JButton {

    ……

}

      UML中,关联关系通常可包含如下几种形式:

      (1) 双向关联

      默认情况下,关联是双向的。例如:顾客(Customer)购买商品(Product),反之,商品也总有某个顾客与之相关联。因此,Customer类和Product类之间具有双向关联关系,如图2所示:

https://i-blog.csdnimg.cn/blog_migrate/89a88044924c6bc3516aed1469e21ddf.jpeg

2  双向关联实例

      2对应的Java代码片段如下:

public class Customer {

private Product[] products;

……

}

 

public class Product {

private Customer customer;

……

}

      (2) 单向关联

      类的关联关系也可以是单向的,单向关联用带箭头的实线表示。例如:顾客(Customer)拥有地址(Address),则Customer类与Address类則只具有单向关联关系,如图3所示:

https://i-blog.csdnimg.cn/blog_migrate/ecdce5a92434dfa3d9d0ea61de26f5f8.jpeg

3 单向关联实例

      3对应的Java代码片段如下:

public class Customer {

private Address address;

……

}

 

public class Address {

……

}

      (3) 自关联

      在系统中可能会存在一些类的成員属性为该类本身,这种特殊的关联关系称为自关联。例如:节点类(Node)的成员屬性是另一节点Node类型的对象,如图4所示:

https://i-blog.csdnimg.cn/blog_migrate/990b9ef7707878b75e6f5a5b0e3b66ac.jpeg

4 自关联实例

      4对应的Java代码片段如下:

public class Node {

private Node subNode;

……

}

      (4) 多重性

      多重性(Multiplicity)关联关系,表示两个关联对象存在数量上的对应关系。UML中,類之间的多重性可以直接在关联直线上用数字或数字范围來表示。

      類之间可存在多种之多重性关系,常见的多重性表示方式如表1所示:

多重性表示方式列表

表示方式

多重性说明

1..1

表示另一个类只与该类的一个对象有关系

0..*

表示另一个类与该类的零个或多个对象有关系

1..*

表示另一个类与该类的一个或多个对象有关系

0..1

表示另一个类没有或只与该类的一个对象有关系

m..n

表示另一个类与该类最少m,最多n个对象有关系 (m≤n)

      例如:一个界面(Form)可以拥有零个或多个按钮(Button),但是一个按钮只能属于一个界面,因此,一个Form类的对象可以与零个或多个Button类的对象相关联,但一个Button类的对象只能与一个Form类的对象关联,如图5所示:

https://i-blog.csdnimg.cn/blog_migrate/3fc65d396644533b066ed8617b596ab1.jpeg

5 多重性关联实例

      5对应的Java代码片段如下:

public class Form {

private Button[] buttons; //定义一个集合对象

……

}

 

public class Button {

……

}

      (5) 聚合关系

      聚合(Aggregation)关系表示可能存在整体与部分的关系,部份成员類是整体類的一部分,但此部份成员類可以脱离整体類而独立存在。UML中,聚合关系用带空心菱形(*whole的直线箭頭(*part)表示。例如:发动机(Engine)是汽车(Car)的组成部分,但是发动机可以独立存在,因此,汽车和发动机是聚合关系,如图6所示:

https://i-blog.csdnimg.cn/blog_migrate/d7b478685d50b0b677553f26e713270e.jpeg

6  聚合关系实例

      以代码实现聚合关系时,部份成员類通常作为Setter方法(*不含普通方法)的参数注入到整体類中,图6对应的Java代码片段如下:

public class Car {

          private Engine engine;

    

    //设值作注入

public void setEngine(Engine engine) {

    this.engine = engine;

}

……

}

 

public class Engine {

          ……

}

      (6) 组合关系

      组合(Composition)关系表示必然存在整体和部分的关系,在组合关系中整体類可以控制部份成员類的生命周期,一旦整体類不存在則部份成员類也将不存在,部份成员類与整体類之间具有同生共死的关系。在UML中,组合关系用带实心菱形(*whole的直线箭頭(*part)表示之。例如:人的头(Head)与嘴巴(Mouth),嘴巴是头的组成部分之一,而且如果头没了,嘴巴也就没了,因此头和嘴巴是必存在组合关系,如图7所示:

https://i-blog.csdnimg.cn/blog_migrate/0cf7b98d4abc7b6086aa5fb5feea8a52.jpeg

组合关系实例

      以代码实现组合关系时,須在整体类的构造方法中直接实例化部份成员类或以参数作注入,图7对应的Java代码片段如下:

public class Head {

          private Mouth mouth;

 

          public Head() {

                   mouth = new Mouth();            //实例化部份成员类

          }

 

#或

#       public Head(Mouth mouth) {  //构造注入參數

#                 this.mouth = mouth;

#       }

 

……

}

 

public class Mouth {

          ……

}

      2. 依赖关系

      依赖(Dependency)关系表示特定事物的改变会影响到使用该事物的類,在UML中,依赖关系用带箭头的虚线表示,由依赖方箭頭指向被依赖方。例如:驾驶员开车,在Driver类的drive()方法中将Car类作为参数传入,如此便可drive()方法中调用carmove()方法,表示驾驶员Driver类的drive()方法要依赖车Car类的move()方法,如图1所示:

https://i-blog.csdnimg.cn/blog_migrate/0cf9e361320bf34bfe3b106427d090d6.jpeg

1 依赖关系实例

1对应的Java代码片段如下:

public class Driver {

          public void drive(Car car) {

                   car.move();

          }

    ……

}

 

public class Car {

          public void move() {

                   ......

          }

    ……

}

     依赖关系通常可通过三种方式来实现:

  • 第一种也是最常用的一种方式是如图1所示的将一个类作为另一个类中普通方法的参数
  • 第二种方式是在一个类的普通方法中将另一个类作为其局部变量
  • 第三种方式是在一个类的普通方法中调用另一个类的静态方法

 

      3. 泛化关系

      泛化(Generalization)关系也就是俗稱之继承关系,用于描述父类与子类之间的关系,父类又称作基类(*超类),子类又称作派生类。UML中,泛化关系用带空心三角形(*基類)的直线(*子類)来表示。以代码实现时可使用面向对象的继承机制来实现泛化关系,如在Java语言中使用extends关键字、在C++/C#中使用冒号来实现。例如:Student类和Teacher类都是Person类的子类,Student类和Teacher类會继承Person类的属性和方法,當Person类的属性包含姓名(name)和年龄(age),每一个StudentTeacher也都具有这两个属性,另外Student类本身又增加了属性学号(studentNo)Teacher类本身又增加了属性教师编号(teacherNo),而Person类的方法包括行走move()和说话say()Student类和Teacher类也會继承这两个方法,而且Student类本身还新增study()方法,Teacher类本身还新增方法teach()。如图2所示:

https://i-blog.csdnimg.cn/blog_migrate/e9eb64fa1a0591339b14fbabae66e3b0.jpeg

2  泛化关系实例

      2对应的Java代码片段如下:

//父类

public class Person {

protected String name;

protected int age;

 

public void move() {

        ……

}

 

    public void say() {

    ……

    }

}

 

//子类

public class Student extends Person {

private String studentNo;

 

public void study() {

    ……

    }

}

 

//子类

public class Teacher extends Person {

private String teacherNo;

 

public void teach() {

    ……

    }

}

      4. 接口与实现关系

      在很多面向对象语言中都引入了接口的概念*代表只含抽象方法之定義),如JavaC#等,在接口中通常不帶属性定義,而且所有的操作方法都是抽象声明的,不帶真正实作內容。UML中可用如类的表示法來表示接口,如图3所示:

https://i-blog.csdnimg.cn/blog_migrate/6811e203b2699de2d0f1fae8bb4e815a.jpeg

接口的UML图示

      接口之间也存在与类之间关系相同的继承关系和依赖关系,但是接口和类之间还存在一种实现(Realization)关系,表示實現类中的操作方法实现了接口中所抽象声明的操作方法。UML中,實現类与接口之间的实现关系用带空心三角形(*接口)的虚线(*實現類)来表示例如:定义了一个交通工具Vehicle接口,內含一个抽象操作move(),而类Ship和类Car中都实现了该move()操作,但兩者具体的实现细节不一样,如图4所示:

https://i-blog.csdnimg.cn/blog_migrate/2816edbba2fe4769ac573469db39a5a6.jpeg

实现关系实例

      实现关系在编程实现时,不同的面向对象语言也提供了不同的语法,如在Java语言中使用implements关键字,而在C++/C#中使用冒号来实现。图4对应的Java代码片段如下:

public interface Vehicle {

public void move();

}

 

public class Ship implements Vehicle {

public void move() {

    ……

    }

}

 

public class Car implements Vehicle {

public void move() {

    ……

    }

}

參考 :刘伟 http://blog.csdn.net/lovelion

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值