UML

271 阅读6分钟

1、类的UML表示法

  • 描述
    • 类一般由三个部分组成:
      1. 类名(name):类的名字,字符串
      2. 类的属性(Attributes):类的成员变量
      3. 类的操作(Operations):类的成员方法
    • 类图中属性和操作规格:
      1. 属性规格:可见性 属性名称:类型,如(- name:String)
      2. 操作规格:可见性 操作名称(参数名称:类型):返回值类型,如(+ getName():String)
      • 可见性:
        1. 公有:public,用+表示
        2. 私有:private,用-表示
        3. 受保护:protected用#表示
      • 名称:驼峰命名,首字母大写
      • 类型:属性的数据类型,基本数据类型或自定义类型
    • 类和类之间的关系主要有关联关系、依赖关系和泛化关系。
  • UML类图 类图
  • IDEA生成类图(快捷键Ctrl+Alt+U或Ctrl+Shift+Alt+U) 类图.png
  • Student类对应的Java代码
public class Student {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2、类的关联关系

  • 描述
    • 关联(Association)关系是一种结构化关系,用于表示一类对象与另一类对象之间有联系,如汽车和轮胎、师傅和徒弟、班级和学生等。在UML类图中,用实线连接有关联关系的对象所对应的类。在代码实现上,通常将一个类的对象作为另一个类的成员变量。
    • 在UML中,关联关系通常包含以下6种形式。
      1. 双向关联:在默认情况下,关联是双向的。例如,一位教师(Teacher)可以教授一或多门课程(Course),一门课程只能被一位教师教授。双向关联实例.png
        • 三角形标注:关联关系的阅读方向,是可选的。
        • 直线两边的数字:关联的重数性(Multiplicity),也是可选的,表示两个关联对象在数量上的对应关系。在UML中,对象之间的多重性可以直接在关联直线上用一个数字或数字范围表示。
        • 常见的多重性表示方式
          表示方法多重性表示方式
          1..1表示另一个类的一个对象只与该类的一个对象有关系
          0..*表示另一个类的一个对象与该类的零个或多个对象有关系
          1..*表示另一个类的一个对象与该类的一个或多个对象有关系
          0..1表示另一个类的一个对象没有或只与该类的一个对象有关系
          m..n表示另一个类的一个对象与该类最少m,最多n个对象有关系(m<=n)
      2. 限定关联(Qualified association):具有限定符(Qualifier),限定符的作用类似HashMap中的键(key),用于从一个集合中选择一个或多个对象。例如,一个用户(User)可以有多个角色(Role),但是在一个场景(Scenario)下,它只会是一种角色。对于限定关联,有一点需要注意,即多重性的变化。例如,比较图a和图b,限定减少了在关联目标端的多重性,通常是由多变为一,因为限定关联通常是从较大集合中选择一个实例。限定关联实例.png
        public class user {
            private Map<String, Role> roles;
        
            public Role getRoles(String scenario) {
                return roles.get(scenario);
            }
        }
        
        public class Role {
        }
        
      3. 单项关联:单项关联用带箭头的实线表示。例如,顾客(Customer)拥有地址(Address),则Customer类与Address类具有单项关联关系。单项关联实例.png
      4. 自关联:类的属性对象类型为该类本身。例如,一个节点类(Node)的成员又是节点Node类型的对象。设计模式中的装饰者模式也是一种自关联。自关联实例.png
        public class Node {
            private Node subNode;
        }
        
      5. 聚合关系:整体与部分的关联关系,成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。在UML中,聚合关系用带空心菱形的直线表示。例如,汽车发动机(Engine)是汽车(Car)的组成部分,但是汽车发动机可以独立存在,因此汽车和发动机是聚合关系。聚合关系实例.png
        public class Car {
            private Engine engine;
        
            // 构造注入
            public Car(Engine engine) {
                this.engine = engine;
            }
        
            // 设值注入
            public void setEngine(Engine engine) {
                this.engine = engine;
            }
        }
        
      6. 组合关系:组合关系也可以表示类之间整体和部分的关联关系,但是在组合关系中,整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也将不存在,成员对象与整体对象之间具有“同生共死”的关系。在UML中,组合关系用带实心菱形的直线表示。例如,人的头部(Head)与嘴(Mouth),嘴是头部的组成部分,如果头部不存在,那么嘴也就不存在了,因此头部和嘴是组合关系。组合关系实例.png在用代码实现组合关系时,通常在整体类的构造方法中直接实例化成员类。成员对象域整体对象有同样的生命周期,也就是要“共生死”,这也是组合和聚合的主要区别。代码上的体现是组合没有Setter方法。
        public class Head {
            private Mouth mouth;
            public Head() {
                mouth = new Mouth(); // 实例化成员类
            }
        }
        
        public class Mouth {
        }
        

3、类的依赖关系

  • 描述 依赖关系是一种使用关系,特定事物的改变可能会影响使用该事物的其它事物,在需要表示一个事物使用另一个事物时,使用依赖关系。大多数情况下,依赖关系体现在某个类的方法使用另一个类的对象作为参数。在UML中,依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方。例如,教师(Teacher)上课时使用投影仪(Projector)进行演示。
  • 在系统实施阶段,依赖关系通常通过3种方式来实现。
    1. 第一种方式(也是常用的一种方式)是将一个类的对象作为另一个类中方法的参数。依赖关系实例.png
      public class Teacher {
          public void use(Projector projector) {
              projector.demonstrate();
          }
      }
      
      public class Projector {
          public void demonstrate() {
          }
      }
      
    2. 第二种方式是在一个类的方法中奖另一个类的对象作为其局部变量。
    3. 第三种方式是在一个类的方法中调用另一个类的静态方法。

4、类的泛化关系

  • 描述 泛化(Generalization)关系也称为继承关系,用于描述父类与子类之间的关系。父类称为基类或超类,子类称为派生类。在UML中,泛化关系用带空心三角形的直线来表示。在代码实现时,我们使用面向对象的继承机制来实现泛化关系,例如,在Java语言中使用extends关键字。
  • 举例 Student类和Teacher类都是Person类的子类,Student类和Teacher类继承了Person类的属性和方法,Person类的属性包含姓名(name)和年龄(age),每一个Student和Teacher也都具有这两个属性。另外,Student类增加了属性学号(studentNo),Teacher类增加了属性教师编号(teacherNo)。泛化关系实例.png
    // 父类
    public class Person {
        protected String name;
        protected int age;
        ......
    }
    
    // 子类
    public class Student extends Person {
        private String studentNo;
        ......
    }
    
    // 子类
    public class Teacher extends Person {
        private String teacherNo;
        ......
    }
    

5、接口与实现关系

  • 描述 在接口中,通常没有属性,其操作通常都是抽象的,只有操作的声明,没有操作的实现。在UML中,类与接口之间的实现关系通常是用带空心三角形的虚线来表示。例如,每一个度量项(Metries)都是可度量的(Measurable)。实现关系实例.png需要注意的是,UML提供了多种方法表示接口实现(Interface realization)。例如,在UML2中新定义的插座表示法(Socket notation),有助于表示“类X需要(使用)接口Y”。在上面的例子中,我们有一个统计类(Statistics)要使用度量项进行统计,其插座表示法如下。接口和实现的插座表示法.png