UML (统一建模语言),对於所有学过 OOP 语言的人是一个耳熟能详的图表,UML, SysML, IDEF 都是建模语言,他们要做的事情其实都是在描述整个功能、系统的关联性。
前面一些文章也或多或少介绍了 UML 概念下产生的表达图,所以这篇文章就会专注在 Code 上。
UML 的图形元素被分成四大种,里面都有不同的表达方式:
由於项目太多,可自行到 [3] 去参考,这里介绍类别、介面、封装、以及关联性就好:
类别的表示法:
范例是一个学生类别,这个类别被 new 出来後只有姓名属性可以直接被存取,其他的都不行,方法也只有 EnrollClass() 可以直接被呼叫。
物件的表示法,就是把名称划上底线,假设要描述一个传递物件到某个参数的行为,在此先假设学生 B 已经被 new 完後传递,则可以直接使用上图,排除掉非公开的属性跟方法,画成图:
介面,则是在名称上加上 <<interface>>
:
封装的画法如下图:
不过介面里面可装的元素包含属性、类别、各种类别放在一起的 Library、或是 Interface,像是下图这样。
关联性的线则是有以下图表可以对照 [5]:
注记: 组合、聚合、依赖、继承、关联相关减少混淆解释范例,可以参考 [7] [10]。
UML 图表类型总共有 14 种:
分别是:
Structure Diagrams 结构图 (Structural Modeling):
Static Diagram 静态图
Implementation Diagram 实现图
剖面图 Profile Diagram (内部构造图)
Behaviour Diagrams 行为图 (Behavioral Modeling):
Interaction Diagrams 互动图 (Architectural Modeling):
本文章使用的是 UML 2.0 版,包含互动摘要、时序、时间图都是新增进去的功能。
模型与图形是不同的,这些独立的 UML 模型可以用来呈现不同情境:
【功能模型】,最直接的例子就是使用案例图,,主要是从使用者角度(包含工程师、终端使用者)展示系统功能,包括但不限於这个案例图来制作 [8]。
【物件模型】,就是上述介绍的类别图、物件图…ETC 等。
【动态模型】,最直接的例子就是状态图、有限状态机,这些图可以用来描述并发 (Concurrent) 状态及系统事件。
比方说,使用动态图来描述一个并发内的子状态,可以参考下图 [9]:
设计模式的书其实也会使用 UML 图来表达,而且大多都不是用复杂的 UML 图来呈现的,最主要需要了解的关联性有以下六种:
泛化 (Generalization)、实现 (Realization)、聚合 (Aggregation)、组合 (Composition)、依赖 (Dependency)、关联 (Association) 。
最後可以透过这六种图的搭配组合出不同的 UML 模式,本篇文章想要使用程序码搭配图形来解释,请见下一节。
OOP 的 IDE 像是 Visual Studio, Net Beans 都有 UML 图设计的工具,可以按照程序码产生类别图後作画, Visual Studio 里面,可以透过 add item -> diagram 就可以产生这些图了。
现在下面要试着混用 Visual Studio 介绍关联性的六种表达线。
实心箭头 + 实线表示继承,他的写法是 (C#):
abstract class 动物
{
public abstract void 行走();
public abstract void 跳();
public abstract void 叫();
}
class 猫: 动物
{
public Program many_program;
public override void 叫()
{
Console.WriteLine("Meow");
}
public override void 行走()
{
throw new NotImplementedException();
}
public override void 跳()
{
throw new NotImplementedException();
}
}
让动物变成一个抽象类别,然後让猫咪继承他之後实作。
Visual Studio 表示法有点奇特,不过空心箭头 + 虚线是指实作 Interface 的意思。
public interface I人猫通讯介面
{
void 握手();
void 吃罐罐();
}
public class 猫通讯 : I人猫通讯介面
{
void I人猫通讯介面.吃罐罐()
{
throw new NotImplementedException();
}
void I人猫通讯介面.握手()
{
throw new NotImplementedException();
}
}
猫通讯本身就是一个介面,让人类把猫通讯介面实现出来之後,透过其他神秘的方法,吃下这个介面的实现值再去执行功能,让猫猫知道你要让他吃罐罐跟握手。
依赖是虚线箭头 + 虚线构成,由於在 Visual Studio 工具箱找不到那条虚线,所以直接画图出来。
**class 股票
{
}
class 彩券
{
}
class Me
{
public void 致富(股票 股, 彩券 券)
{
// 疯狂买股买券
}
}
我看几个范例都喜欢写新陈代谢,不过我改成 Me,我离不开致富,而致富需要使用彩券 + 股票,这就形成依赖关系了 (见笑)。
关联是实现箭 + 头线现表示。
class 辣椒作物
{
// 我需要知道天气
天气 天气;
// 建构子 (请在实作时让我知道天气)
辣椒作物(天气 天气) {
this.天气 = 天气;
}
public void 成熟采收()
{
if(this.天气.目前季节() == "夏天")
{
Console.WriteLine("成熟准备采收");
}
else
{
Console.WriteLine("还不到采收季节");
}
}
}
class 天气
{
public string 目前季节 ()
{
return "冬天";
}
}
辣椒作物需要知道天气,才能让成熟采收功能运作,所谓知道的意思,也可以想成是 Class 中的属性是否有这项资料,或是从建构子带入进来哪些资料 (不一定)。
聚合是使用空心菱形 + 实线表示。
class 团体
{
public List<人> 成员; // 成员列表
internal 人 人
{
get => default;
set
{
}
}
public void 加入团体(人 某人) {
成员.Add(某人);
}
public void 退出团体() { }
}
class 人
{
public void 工作() {
}
}
人和团体是不同的概念,团体在成员属性中需要蒐集各式各样的人,这些人也因此聚合到团体中了。
组合是使用实心菱形 + 实线表示。
class 墨西哥帽子
{
}
class 棒球衣服
{
}
class 演员
{
private 墨西哥帽子 墨西哥帽;
private 棒球衣服 棒球衣;
//建构子
演员()
{
this.墨西哥帽 = new 墨西哥帽子();
this.棒球衣 = new 棒球衣服();
}
}
演员本身可以透过陈列多个属性,最後在建构子建立时,帮演员装上特定的衣服跟帽子,组合出装备。
References:
[1] https://www.tutorialspoint.com/uml/uml_basic_notations.htm
[2] https://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E5%BB%BA%E6%A8%A1%E8%AF%AD%E8%A8%80
[3] https://www.tutorialspoint.com/uml/uml_architecture.htm
[4] https://www.conceptdraw.com/How-To-Guide/uml-class
[5] https://creately.com/blog/diagrams/class-diagram-tutorial/
[6] http://www-sop.inria.fr/axis/cbrtools/usermanual-eng/Print/UMLNotationPrint.html
[7] https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-aggregation-vs-composition/
[8] https://creately.com/diagram/example/i9z1wc852/Functional%20model
[9] https://www.tutorialspoint.com/object_oriented_analysis_design/ooad_dynamic_modeling.htm
[10] https://juejin.cn/post/6844904006221824013
<<: 【Day 11】Google Apps Script - API 篇 - 转换流程架构与相关服务
资料扩增 我们组的资料扩增这部分,因为第一次比赛,这个方法效果没有到非常好,采取的是用mask的方式...
其实原本最初规画想要做Index方式的纪录,然後多增加一些没写到的面向 不过,总是计画赶不上变化 ...
人脸辨识建置的类型有两种: 第一种为使用云端计算,因需要使用云端计算,所以需要确保网路连线顺畅,在将...
常见的 HTML elements 标题 headings 在 VS code 中输入以下程序码 &...
烟囱式架构 相对於中台架构,烟囱式架构就像多个互相独立的应用系统,代表着业务流程的区隔 ─ 重复的功...