UML图——类图

转自知乎30分钟学会UML图

UML图有很多种,但是并非必须掌握所有的UML图,才能完整系统分析和设计工作。一般说来,在UML图中,只要掌握类图、用例图、时序图的使用,就能完成大部分的工作。也就是说,掌握UML的20%,就能做80%的事情。对于程序员来说,最频繁使用的莫过于类图。因此,这里我们只讲解UML类图

类图是面向对象系统建模中最常用和最重要的图,是定义其它图的基础。类图主要是用来显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。类图中最基本的元素是类、接口。软件设计师设计出类图后,程序员就可以用代码实现类图中包含的内容

类、接口和包

  1. 在UML类图中表示具体类

具体类在类图中用矩形框表示,矩形框分为三层:第一层是类名字。第二层是类的成员变量;第三层是类的方法。成员变量以及方法前的访问修饰符用符号来表示,如下图所示

  • “+”:表示public
  • “-”:表示private
  • “#(sharp)”:表示protected
  • “”:表示default

2

  1. 在UML类图中表示抽象类

抽象类在UML类图中同样用矩形框表示,但是抽象类的类名以及抽象方法的名字都用斜体字表示,如下图所示

3

  1. 在UML类图中表示接口

接口在类图中也是用矩形框表示,但是与类的表示法不同的是,接口在类图中的第一层顶端用构造型 <<interface>>表示,下面是接口的名字,第二层是方法,如下图所示

4

  1. 在UML类图中表示包

类和接口一般都出现在包中,UML类图中包的表示形式如下图所示

5

关系

类和类、类和接口、接口和接口之间存在一定关系,UML类图中一般会有连线指明它们之间的关系。关系共有六种类型,分别是实现关系、泛化关系、关联关系、依赖关系、聚合关系、组合关系,如下图所示

1

设计模式概论

感谢隔壁雨中的博客的详细介绍

可以将23种设计模式划分成为三类:

  • 创建型模式(5):单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式
  • 行为型模式(11):模板方法模式、命令模式、迭代器模式、观察者模式、中介模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式

每种模式都尽可能地使得我们的代码符合以下7大开发原则:

原则名称 原则内容
开闭原则 对扩展开发,对修改关闭
里氏替换原则 继承必须确保父类所拥有的性质在子类中仍然成立
依赖倒置原则 要面向接口编程而非面向实现编程
单一职责原则 控制类的粒度大小,将对象解耦,提高内聚性
接口隔离原则 要为各个类建立他们需要的专用接口
迪米特原则 只与你直接的朋友交谈,不跟陌生人说话
合成复用原则 尽量使用组合或者聚合的关联关系来实现,其次才考虑使用继承关系来实现
设计模式详解

23中设计模式中,迭代器模式和适配器模式为适应设计模式;模板方法模式和工厂模式将功能交给子类;单例模式、原型模式、创作者模式以及抽象工厂模式通过生成实例来实现功能;桥接模式和策略模式将类的功能与实现分开考虑;组合模式和装饰者模式保证了一致性;访问者模式和责任链模式通过访问数据结构来实现功能;外观模式和中介者模式将功能的实现简单化;观察者模式、备忘录模式以及状态模式用来管理类的状态;享元模式和代理模式用来避免内存与性能的浪费;命令模式和解释器模式用类来表现功能

创建型模式

Factory Pattern - 工厂模式

将实例的生成交给子类

17

工厂模式是Java中最常用的设计模式之一,提供了一种创建对象的最佳方式。在创建对象时不会对客户暴露创建逻辑,并且是通过一个共同的接口来指向新创建的对象

在工厂模式中的登场角色

18

19

工厂模式分类

20

  • 其中简单工厂只有一个工厂类,用同一个方法创建多种产品
  • 多方法简单工厂同样只有一个工厂类,区别在于用不同的方法创建多种产品
  • 静态方法简单工厂,其中创建方法为静态方法,不需要创建工厂实例
  • 工厂方法模式中包含多个工厂类,全部实现工厂接口或继承于工厂抽象类,不同的工厂类用来创建不同的产品
  • 抽象工厂模式与工厂方法模式类似,区别在于可创建不同类别的产品。工厂类可理解为不同的品牌,每个品牌都可以生产鼠标和键盘

单例模式 - Singleton Pattern

只有一个实例

21

单例模式是Java中最简单的设计模式之一,同样提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,其提供了一种访问其唯一对象的方式

23

22

其中构造函数是私有的,这是为了禁止从Singleton类外部调用构造函数

在单例模式中的登场角色

24

单例模式实现方式

  1. 懒汉式 线程不安全

这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程,因为没有加锁synchronized。严格来说,这种方式不算是单例模式

1
2
3
4
5
6
7
8
9
10
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
  1. 懒汉式 线程安全

第一次调用才会初始化,避免内存浪费。但是必须加锁才能保证单例,会影响效率

1
2
3
4
5
6
7
8
9
10
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
  1. 饿汉式

这种方法比较常用,但容易产生垃圾对象。没有加锁,执行效率会提高。类加载时就初始化,浪费内存

1
2
3
4
5
6
7
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
  1. 双检锁/双重校验锁(DCL - double-checked locking)

这种方式采用双锁机制,安全且在多线程情况下依然能保持高性能,实现较为复杂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {
private volatile static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if(singleton==null) {
synchronized (Singleton.class) {
if(singleton==null) {
singleton=new Singleton();
}
}
}
return singleton;
}
}
  1. 登记式/静态内部类

这种方式能达到双检锁方式一样的功效,但实现较为简单

1
2
3
4
5
6
7
8
9
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE=new Singleton();
}
private Singleton() {}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}

Prototype Pattern - 原型模式

通过复制生成实例

25

原型模式是用于创建重复的对象,同时又能保证性能。这种模式是实现了一个原型接口,该接口用于于创建当前对象的克隆,当直接创建对象的代价比较大时,则采用这种模式。将已创建的对象存在缓存中(在实现时可使用Map来模拟)

原型模式中的登场角色

26

27

Builder Pattern - 建造者模式

组装复杂的实例

28

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。创建Builder类一步一步构造最终的对象,且建造者类是独立于其他对象的

29

在建造者模式中的登场角色

32

30

31

Abstract Factory Pattern - 抽象工厂模式

将关联零件组装成产品

33

抽象工厂模式是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。在这个模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象

34

在抽象工厂模式中的登场角色

35

36

37

38

结构型模式

Adapter Pattern - 适配器模式

增加适配器便于复用

10

适配器模式是作为两个不兼容的接口之间的桥梁,结合了两个独立接口的功能。在适配器模式种涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。将两个原本无法合作的类联系起来。适配器模式包含类适配器模式(使用继承的适配器)以及对象适配器模式(使用委托的适配器)

类承适配器模式

12

对象适配器模式

13

在适配器模式中的登场角色

11

压转换为直流12伏特电压的适配器。在示例程序中,由PrintBanner类扮演这个角色。在类适配器模式中,Adapter角色通过继承来使用Adaptee角色;而在对象适配器模式中,Adapter角色通过委托来使用Adaptee角色

Bridge Pattern - 桥接模式

将类的功能与实现分离

39

桥接模式是用于把抽象化与实现化解耦,使得二者可以独立变化

40

在桥接模式中的登场角色

41

42

43

Composite Pattern - 组合模式

容器与内容的一致性

48

组合模式又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象,组合模式依据树形结构来组合对象,用来表示部分以及整体层次。创建了一个包含自己对象组的类,该类提供了修改相同对象组的方式

49

50

在组合模式中的登场角色

51

52

Decorator Pattern - 装饰器模式

装饰边框与被装饰物的一致性

53

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构

54

Facade Pattern - 外观模式

简单窗口 隐藏系统复杂性

57

Flyweight Pattern - 享元模式

共享对象 避免浪费

62

Proxy Pattern - 代理模式

必要时生成实例 否则代理使用

63

行为型模式

Iterator Pattern - 迭代器模式

遍历对象内容

9

迭代器模式是用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。在Java语言中可以使用for循环语句便利数组,将循环体中的循环变量的作用抽象化、通用化后形成的模式即为迭代器模式

在迭代器模式中,Aggregrate接口是所要遍历的集合的接口,实现了该接口的类像数组一样成为一个可以保存多个元素的集合

6

7

Iterator接口中主要实现的方法有hasNext()以及next()

在迭代器模式中所登场的角色

8

Template Pattern - 模板方法模式

将具体处理交给子类

14

模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行

例如创建一个定义操作的Game抽象类,CriketFootball是扩展了Game的实体类,它们重写了抽象类的方法,如下所示

15

在模板方法模式中的登场角色

16

Strategy Pattern - 策略模式

整体地替换算法

44

策略模式中,一个类的行为或其算法可以在运行时修改

45

在策略模式中的登场角色

46

47

Visitor Pattern - 访问者模式

访问数据结构并处理数据

55

Chain of Responsibility Pattern - 责任链模式

推卸责任 使用责任链处理问题

56

Mediator Pattern - 中介者模式

只有一个仲裁者

58

Observer Pattern - 观察者模式

广播发送状态变化通知

59

Memento Pattern - 备忘录模式

保存对象状态

60

State Pattern - 状态模式

用类表示状态 类的行为基于状态改变

61

Command Pattern - 命令模式

以类作为命令 传给对象执行命令

64

Interpreter Pattern - 解释器模式

以类作为语法规则 解析句法的语义

65