《设计模式解析(第2版•修订版)》—第2章 2.4节类图

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 组合和聚集都有“一个对象包含一个或多个对象”的意思,但是,组合意味着“被包含对象是包含对象的一部分”,而聚集意味着被包含对象更像是一个集合。

本节书摘来自异步社区《设计模式解析(第2版•修订版)》一书中的第2章,第2.4节类图,作者【美】Alan Shalloway(艾伦•沙洛维) , James R.Trott(詹姆斯•R.特罗特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.4 类图
设计模式解析(第2版•修订版)
基本的建模图

最基本的UML图是类图。它不仅描述了类,而且说明了类之间的关系。这些关系可能有以下这些类型。

当一个类是“一种”另一个类时:is-a(是一种/一个)关系。
当两个类之间存在关联时:
一个类“包含”另一个类:has-a(拥有一个)关系;
一个类“使用”另一个类:use-a(使用一个)关系;
一个类“创建”另一类。
这些类型还有一些变体。比如,说“什么东西包含另一个东西”时,我们可能是指:

被包含者是包含者的一部分(比如汽车中的发动机);
有一个集合,集合中东西可以独立存在(比如机场上的飞机)。
表示类信息的不同方法

第一种情况称为组合(composition),第二种情况称为聚集(aggrega- tion)1。

图2-1说明了重要的几点。首先,矩形表示一个类。在UML中,我可以表示最多三个方面的类的信息:

类名;
类的数据成员;
类的方法(函数)。


cf355d8273dbe61107a242a65852eef3729a2064

表示类的信息有三种不同方式。

最左边的矩形只显示了类名。在不需要更详细信息时,可以使用类的这种表示形式。
中间的矩形显示了类名和类的方法。在本例中,Square类2有一个display方法。display(方法名)前的加号(+)表示此方法是公开的——也就是说,不属于此类的其他对象也可以调用。
最右边的矩形除显示了前面的信息(类名和类的方法)之外,还显示了类的数据成员。在本例中,数据成员length(它是double类型的)前的减号(-)表明这个数据成员的值是私有的,也就是说,除了它所属的对象外,它对其他对象都是不可见的。3
表示访问权限的UML记号

你可以控制类的数据成员和方法成员的可访问性,也可以用UML标记所需要的每个成员的可访问性。大多数面向对象语言中都有如下三种最常见的可访问性。

公开——用一个加号(+)标记。意味着所有对象都可以访问这个 数据或方法。

保护——用一个“井”号(#)标记。意味着只有该类及其所有 派生类(包括其派生类的派生类)可以访问这个数据或方法。
私有——用减号()标记。意味着只有该类的方法可以访问这 个数据或方法。(请注意:某些语言进一步将其限制为特定对象。)

表示关系的UML记号

表示关系的UML记号有如下四种:4


fa01e8f4535cd07af0209a51f720324dfce9acd0

类图还可以表示关系

类图还可以表示不同类之间的关系。图2-2显示了Shape类和它的几个派生类之间的关系。


d65ee59b9960f472e5fa54e79d2e0c83bf060db5

表示is-a关系

图2-2说明了几件事。首先,Shape类下面的箭头的意思是:指向Shape的那些类派生自Shape类。而且,Shape类的名字是用斜体表示的,说明它是一个抽象类。抽象类就是用来为其派生类定义接口而且存放这些派生类公共数据和方法的类。接口可以看作是没有公共数据和方法的抽象类——它只用来作为一种“为要实现它的那些类的方法进行定义”的方式而已。5

表示has-a关系

如前所述,有两种不同的has-a关系。一个对象可以拥有另一个对象,其中被包含的对象是包含对象的一部分——或者不是。在图2-3中,我表示出Airport“拥有”Aircraft。Aircraft并不是Airport的一部分,但仍然可以说Airport拥有Aircraft,这种关系称为聚集。


01b809284e76a4d6f9d4c3eb969fe12a4e17e9c3

聚集

在此图中,我还表示了Aircraft要么是Jet(喷气式飞机),要么是Helicopter(直升飞机)。可以看出Aircraft类是一个抽象类或者接口6,因为它的名字是用斜体表示的。也就是说,Airport可以拥有Jet或Helicopter,但它是以相同方式对待它们的(当作Aircraft)。Airport类右边的空心(未填充的)菱形表示聚集关系。

组合

另一种has-a关系是包含,被包含对象是包含对象的一部分,这种关系也称为组合。

组合和使用

图2-4显示了Car(轿车)拥有Tire(轮胎),后者是它的一部分(也就是说,Car由Tire和其他东西组成),这种has-a关系,称为组合关系(composition),用实心菱形表示。此图上还显示了Car使用了GasStation(加油站)类,这种使用关系用带箭头的虚线表示,也称依赖关系(dependency relationship)。


d5eeccee97ceadf46191b6493cf1e4969f8856a3

组合与聚集的异同

组合和聚集都有“一个对象包含一个或多个对象”的意思,但是,组合意味着“被包含对象是包含对象的一部分”,而聚集意味着被包含对象更像是一个集合。我们可以认为组合是一种非共享的关联,被包含对象的生存周期由包含对象控制。适当使用构造函数和析构函数在这里有助于对象的创建和销毁过程。

UML中的注释

在图2-5中有一个新记号:注释。含有“空心菱形表示聚集”信息的方框就是注释。注释记号看上去好像是右角折起的纸。经常能够看到注释通过一条线与特定的类连接起来,表示它只与此类有关。


cefbdc4f82b09ca3e61ef7227271961c3a202ae1

表示另一个对象所拥有的东西的数量

类图表示的是类之间的关系,但是,对于组合和聚集来说,这两种关系更加关注该类型的具体对象。比如,Airport对象拥有Aircraft对象,但是更具体地说,是特定的机场拥有特定的飞机。于是问题出现了——“一个机场可以拥有多少架飞机呢?”这称为关系的重数(cardinality)。图2-6和图2-7说明了这一点。


b9aae9bcb1baa3cd0a6960062da5dcc842822ad1

重数
图2-6告诉我们,对于一个Airport对象,它可以拥有从0到任意数量(此处用星号表示,但有时候也可以用字母“n”)的Aircraft对象。Airport类旁的“0..1”意味着:对于一个Aircraft对象,它可以被0个或1个Airport对象包含。(0表示它可以在空中飞行,不属于任何机场)。

图2-7告诉我们,对于一个Car对象,它可以拥有4个或5个Tire对象(有或没有备胎),轮胎则只能装在一辆轿车上。我曾听一些人说,如果未指定重数,就意味着只有一个对象,这种想法是不正确的。如果未指定重数,对于对象的数量不应该做任何假设。

虚线表示依赖

和前面一样,图2-7中显示的Car和GasStation之间的虚线表示两者之间存在依赖。UML用带虚线的箭头表示两个模型元素之间的语义关系(意义)。

1 Gamma、Helm、Johnson和Vlissides的《设计模式》一书中将第一种情况称为“聚集”,而将第二种情况称为“组合”(《设计模式》一书中aggregation的确相当于本书中的组合概念,但是该书中的composition则是指对象组合,与继承相对,和本书中的聚集没有关系。——译者注)——正好与UML相反。但是,该书完成于UML标准最终定案之前,事实上书中所给出的定义是与UML一致的。这也说明了开发UML的动机。在UML出现之前已经有好几种各不相同的建模语言,每种都有自己的记号和术语。
2类名在文字中引用时,使用Courier字体表示。
3在一些编程语言中,同类型的对象可以相互共享私有数据。
4原书此段文字与“表示访问权限的UML记号”中的一段文字相同,估计是作者的失误。——译者注
5我知道自己两次使用接口一词,表示的是不同的含义。但是别为此骂我。我也希望对Java和C#的关键字——interface使用另一个名字呢。
6为了简明起见,我不再继续写“抽象类或者接口”了。往后我所称的“抽象类”,均可以视同为“抽象类或者接口”。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
2月前
|
设计模式 PHP 开发者
PHP中的设计模式:桥接模式的解析与应用
在软件开发的浩瀚海洋中,设计模式如同灯塔一般,为开发者们指引方向。本文将深入探讨PHP中的一种重要设计模式——桥接模式。桥接模式巧妙地将抽象与实现分离,通过封装一个抽象的接口,使得实现和抽象可以独立变化。本文将阐述桥接模式的定义、结构、优缺点及其应用场景,并通过具体的PHP示例代码展示如何在实际项目中灵活运用这一设计模式。让我们一起走进桥接模式的世界,感受它的魅力所在。
|
2月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将通过探讨单例模式,一种最常用的设计模式,来揭示其在PHP中的应用及优势。单例模式确保一个类仅有一个实例,并提供一个全局访问点。通过实际案例,我们将展示如何在PHP项目中有效实现单例模式,以及如何利用这一模式优化资源配置和管理。无论是PHP初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧,进而提升自己的编程实践。
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
32 1
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
【10月更文挑战第8天】 在软件开发的浩瀚宇宙中,设计模式如同星辰指引,照亮了代码设计与架构的航道。本文旨在深入探索PHP语境下策略模式(Strategy Pattern)的精髓,不仅剖析其内核原理,还将其融入实战演练,让理论在实践中生根发芽。策略模式,作为解决“如何优雅地封装算法族”的答案,以其独特的灵活性与扩展性,赋予PHP应用以动态变换行为的能力,而无需牵动既有的类结构。
35 2
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在PHP开发中,设计模式是提高代码可读性、可维护性和扩展性的重要工具。本文将深入探讨策略模式这一行为型设计模式,通过分析其定义、结构、使用场景以及在PHP中的实际应用,帮助开发者更好地理解和运用策略模式来优化自己的项目。不同于传统摘要的简洁概述,本文摘要部分将详细阐述策略模式的核心理念和在PHP中的实现方法,为读者提供清晰的指引。
|
2月前
|
设计模式 存储 测试技术
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发领域,设计模式是解决常见问题的最佳实践。本文将深入探讨单例模式,一种确保类只有一个实例的设计模式,并提供实际应用示例。我们将从单例模式的基本概念讲起,通过实际案例展示如何在PHP中实现单例模式,以及它在不同场景下的应用和优势。最后,我们会探讨单例模式的优缺点,帮助开发者在实际项目中做出明智的选择。
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在软件开发的广袤领域中,PHP以其灵活性和广泛的应用场景占据了一席之地。本文聚焦于PHP中的一个核心概念——设计模式,特别是策略模式。策略模式作为一种行为型设计模式,允许在运行时选择算法或操作的具体实现,为软件设计带来了极大的灵活性。本文将深入探讨策略模式的基本原理、应用场景以及在PHP中的具体实现方式,旨在帮助开发者更好地理解和运用这一设计模式,提升代码的可维护性和扩展性。
19 2
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第12天】 在软件开发的世界中,设计模式是解决常见问题的最佳实践。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理运用设计模式可以极大地提高代码的可维护性、扩展性和复用性。本文将深入探讨策略模式(Strategy Pattern)的原理、实现方式及其在PHP中的应用。通过具体示例,我们将展示如何利用策略模式来解耦算法与对象,从而让代码更加灵活和易于管理。
19 0
|
2月前
|
设计模式 存储 安全
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和重用性的关键技术之一。本文将深入探讨单例模式(Singleton Pattern)的原理、实现方式及其在PHP中的应用,同时通过实例展示如何在具体的项目场景中有效利用单例模式来管理和组织对象,确保全局唯一性的实现和最佳实践。
|
2月前
|
设计模式 存储 算法
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 在PHP开发领域,设计模式是提升代码可维护性、扩展性和重用性的关键技术之一。本文聚焦于策略模式这一行为型设计模式,通过理论阐述与实例分析,揭示其在PHP应用程序中优化算法切换和业务逻辑解耦方面的强大效用。不同于常规摘要,本文不直接概述研究方法或结果,而是基于实际开发场景,探讨策略模式的应用价值和实现方式,旨在为PHP开发者提供一种高效应对复杂业务需求变化和技术债务累积问题的策略思维。

推荐镜像

更多