1 类图概述

  • UML(Unified Modeling Language),即统一建模语言,是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。
  • UML从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、部署图等9种图。
  • 类图显示了模型的静态结构,特别是模型中存在的类、类的内部结构以及它们与其他类的关系等。类图是面向对象建模的主要组成部分,简化了人们对系统的理解。类图是系统分析和设计阶段的重要产物,是系统编码和测试的重要模型。

2 类图中类的表示方法

  • 介绍一个绘制类图的在线工具 draw
  • 也可以去draw官网下载安装客户端

2.1 普通类

  • 在UML类图中,类使用包含类名、属性和方法且带有分割线的矩形来表示。

  • 比如有这样一个类

    •  class Student {
       public:
       	int study(std::string name);
       private:
       	std::string m_name;
       	int m_code;
       };
      
  • 可以如下表示
    在这里插入图片描述

  • 访问权限

    • + 表示public
    • - 表示private
    • # 表示protect
  • 属性的完整表示方式

    • 可见性 名称: 类型
  • 方法的完整表示方式

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

2.2 抽象类

  • 有这样一个抽象类

    •  class Animal {
       public:
       	virtual void makeSound() = 0;
       	std::string getName() ;
       private:
       	std::string m_name;
       };
      
  • 可以如下表示
    在这里插入图片描述

  • 抽象类类名称用斜体表示,抽象方法用斜体表示

  • 类图边框用虚线表示(建议)

3 类与类的关系

3.1 关联关系

  • 关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,比如老师和学生等。关联关系是类与类之间最常用的一种关系,一般引用的对象,会作为另外一个类的成员变量来使用。
  • 关联关系又可以分为单向关联、双向关联和自关联。

3.1.1 单向关联

  • 有以下两个类Address和Person,其中Person有一个属性为Address,这种就称为单向关联关系。
    •   // Address类
        class Address {
        public:
        	// 获取街道信息
        	std::string getStreet() { return m_street; }
        	// 获取城市信息
        	std::string getCity() { return m_city; }
        
        private:
        	std::string m_street; // 街道信息
        	std::string m_city; //城市信息
        };
        
        // Person类,其中包含一个Address对象的指针
        class Person {
        public:
        	// 设置某人地址
        	void setAddress(Address* address) { m_address = address; }
        	// 获取某人姓名
        	std::string getName() { return m_name; };
        	// 获取某人对应地址
        	Address* getAddress() { return m_address; };
        private:
        	std::string m_name;
        	Address* m_address; // 关联关系,Person类包含一个Address类的指针
        };
      
  • 在UML类图中单向关联用一个带箭头的实线表示。
    在这里插入图片描述

3.1.2 双向关联

  • 双向关联就是双方各自含有对方类型的成员变量
    •   // 课程类
        class Course {
        public:
        	void setTeacher(Teacher* teacher) { m_teacher = teacher;}
        	std::string getName()  { return m_name; }
        	Teacher* getTeacher() { return m_teacher; }
        
        private:
        	std::string m_name;
        	Teacher* m_teacher; // 课程属于哪个教师
        };
        
        // 教师类
        class Teacher {
        public:
        	// 获取教师姓名
        	std::string getName() const { return m_name; }
        	// 给教师设置课程
        	void setCourse(Course* course) { m_courses = course;  };
        	// 获取该教师教授的所有课程
        	Course* getCourses() { return m_courses; }
        
        private:
        	std::string m_name; // 教师姓名
        	Course* m_courses; // 教师对应的课程
        };
      
  • 在UML类图中,双向关联用一个不带箭头的直线表示
    在这里插入图片描述

3.2 聚合关系

  • 这是一种特殊形式的关联,表示类之间整体与部分的关系,其中部分可以独立存在,即使整体不存在。
  • 下面实现了一个员工类和部门类,部门类中包含了员工类对象。而员工类可以离开部门类而单独存在。
    •   // 员工类
        class Employee {
        public:
        
        	std::string getName() const { return m_name; }
        	int getId() const { return m_id; }
        
        private:
        	std::string m_name;
        	int m_id;
        };
        
        // 部门类
        class Department {
        public:
        	// 添加员工
        	void addEmployee(Employee emp) {
        		m_employees.push_back(emp);
        	}
        
        	// 展示员工信息
        	void displayEmployees() {
        		
        		std::vector<Employee>::iterator iter = m_employees.begin();
        		for (; iter != m_employees.end(); iter++) {
        			std::cout << "name : " << iter->getName();
        			std::cout << "id : " << iter->getId();
        		}
        	}
        
        private:
        	std::vector<Employee> m_employees; // 部门类包含员工对象的容器,形成聚合关系
        };
      
  • UML类图中,组合关系用带空心菱形的实线表示,菱形指向整体。
    在这里插入图片描述
  • 聚合关系可以是一对一,也可以是一对多。比如Department中可以包含多个Employee数组,也可以只包含一个Employee对象。

3.3 组合关系

  • 组合表示类之间的整体与部分的关系,但它是一种更强烈的聚合关系。在组合关系中,整体对象可以控制部分对象的声明周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在。
  • 实现一个引擎类和汽车类,引擎属于汽车的一部分,且引擎不能脱离汽车而单独存在。
    •   // 引擎类,是汽车类的一部分
        class Engine {
        public:
        
        	int getHorsePower() { return m_horsePower; }
        
        private:
        	int m_horsePower;
        };
        
        // 汽车类
        class Car {
        public:
        
        	int getCarId() { return m_carId; }
        	int getEngineHorsePower() { return m_engine->getHorsePower(); }
        
        private:
        	int m_carId;
        	Engine* m_engine; // Car类组合了一个Engine对象
        };
      
  • UML类图中,组合关系用带实心菱形的实线表示,菱形指向整体。
    在这里插入图片描述

3.4 依赖关系

  • 依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。
  • 依赖关系指的是一个类依赖于另一个类的功能或服务,但并不直接拥有或包含另一个类的实例。依赖关系通常体现在一个类的方法中通过参数传递、全局函数或静态方法等方式使用另一个类。
  • 比如有一个People类和Circle类,People类中并不包含Circle,但是可以调用Circle类对象的draw方法来画一个圆。
    •   // 圆
        class Circle {
        public:
        	// 画圆
        	void draw() { }
        
        private:
        	int m_radius;
        };
        
        // 有一个人
        class People {
        public:
        	// 调用圆类的画圆方法
        	void drawCircle(Circle circle) { circle.draw(); }
        
        private:
        	string m_name;
        };
      
  • 在UML类图中,依赖关系用带箭头的虚线表示,箭头从使用类指向被依赖的类。
    在这里插入图片描述

3.5 继承(泛化)关系

  • 继承(泛化)关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系。
  • 比如学生类和教师类都继承于基本类People,有基本方法sleep和eat以及各自独有的方法study和work
    •   class People {
        public:
        	void sleep() {  }
        	void eat() { }
        
        private:
        	int m_name;
        };
        
        class Studet : public People {
        public:
        	void study() {}
        private:
        	int m_studentId;
        };
        
        class Teacher : public People {
        public:
        	void work() {}
        private:
        	int m_jobNumber;
        };
      
  • UML类图中,继承关系用带空心三角箭头的实线表示,箭头从子类指向父类。
    在这里插入图片描述

3.6 实现关系

  • 实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。
    •   // 抽象接口类,相当于UML中的Interface
        class Printable {
        public:
        	virtual void print()  = 0;
        };
        
        // 具体实现类,实现了Printable接口
        class Document : public Printable {
        public:
        
        	// 实现接口中的print()函数
        	void print() {
        		std::cout << "Content of the document: " << m_content << std::endl;
        	}
        
        private:
        	std::string m_content;
        };
      
  • 在UML类图中,实现关系使用带空心三角箭头的虚线表示
    在这里插入图片描述
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐