《软件方法(下)》8.3.3 泛化的一些重点讨论(202405更新)

DDD领域驱动设计批评文集

做强化自测题获得“软件方法建模师”称号

《软件方法》各章合集


8.3 建模步骤C-2 识别类的关系

8.3.3 泛化的一些重点讨论

8.3.3.1 子集的不相交和完整

泛化是集合关系,在建模泛化关系时,我们对泛化关系中的子类(子集)的要求应该严格到什么程度?例如,不同子集可以有相同的元素吗?子集的并集必须等于全集吗?

UML规范对此持宽松的态度,泛化关系缺省是无约束的。如果要表达一个元素只能出现在一个子集中,需要给泛化关系加{disjoint}约束,如果要表达一个元素必须能出现在一个子集中,需要给泛化关系加{complete}约束,如图8-98。

图片

图8-98 泛化的不相交和完整约束

(1)不相交

本书认为,同一个泛化集中的任意子类之间不相交,应该是缺省的做法。或者说,尽量把泛化建立在子类不相交的类之上。

例如,自然语言“员工有调度员、装卸工、配货员”,可能有的人画成图8-99的组合关联:

图片

图8-99 错误的关联关系

这当然是错误的。“员工有调度员、装卸工、配货员”指的是“员工”的对象集合包含了“调度员”、“装卸工”、“配货员”的对象集合,不是指一个“员工”对象由“调度员”对象、“装卸工”对象、“配货员”对象组成。这个“有”是集合的“有”,是泛化关系,如图8-100。

图片

图8-100 泛化关系

但图8-100也不是合适的建模结果,因为很可能允许员工身兼数职,同时既是调度员也是配货员。此时, “员工”的任意子集之间的交集不再为空,应该调整泛化结构所在的位置,例如改为图8-101。

图片

图8-101 调整泛化关系的位置

图8-101中,“调度员”、“装卸工”、“配货员”的概念和图8-99相比含义已经不同,它们变成了“职位”的一种。“职位”的任意子集之间的交集应该为空。

如果“调度员”、“装卸工”、“配货员”取“职位”的概念,那么类似图8-99的图8-102其实也不是不可以。

图片

图8-102 员工关联到具体职位

读者可以思考一下,如果把图8-102中的“员工”换成图8-79的“人”,下方的类换成“▲▲”和“〇〇”,可以吗?

如果对于不同职位,系统关注的差别在属性值上就可以体现,不需要在行为上体现,那么,图8-101的泛化关系可以取消,只保留“职位”,如图8-103。

图片

图8-103 删去子类以及泛化关系

★图8-101到图8-103的“职位”,严格来说应该是“职位规格”。可以看得出来,“职位”实例的属性值不会随具体员工而变化。如果要记住张三做装卸工和配货员分别干了多少活,拿了多少绩效,还需要另外的类来区分。例如“员工-任职-职位”或“员工-职位-职位规格”。

(2)完整

本书认为,不需要要求子类完整,否则会导致批量刷废话。

如图8-104,一开始A有两个子类B和C,知道应该是不完整的。如果为了完整,强行加一个口袋子类“其他A”,那么很可能所有的泛化关系都会在结尾加一个“其他*”,这种批量的废话不如不要,缺省认为其不完整即可。

而且,“其他A”的集合元素是不定的,现在的含义是“非B非C”,假设以后A再加一个子类D,“其他A”的含义就变成“非B非C非D”,元素也变少了。

图片

图8-104 不要求完整

当然,如果添加D为B或C更下一级的子类,是可以的。如果“其他A”经过时间的沉淀变成了一个领域术语,D作为“其他A”的子类也无妨——第6章所列的需求分类中的“非功能需求”就是这样的“其他A”的例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/325932.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ACE框架学习4

目录 ACE Proactor框架 异步I/O工厂类 ACE_Handler类 前摄式Acceptor-Connector类 ACE_Proactor类 ACE Streams框架 ACE_Model类 ACE_Streams类 ACE Proactor框架 ACE Proactor框架实现了proactor模式,也就是异步网络模式,允许事件驱动…

47-Qt控件详解:Buttons Containers1

一 QPushButton (命令按钮) #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QPushButton>//引入QPushButton类对应的头文件class MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWind…

基于YOLOV8复杂场景下船舶目标检测系统

1. 背景 海洋作为地球上70%的表面积&#xff0c;承载着人类生活、经济发展和生态系统的重要功能。船舶作为海洋活动的主要载体之一&#xff0c;在海上运输、资源开发、环境监测等方面发挥着重要作用。复杂海洋环境下的船舶目标检测成为了海事管理、海洋资源开发和环境保护等领…

C# winform 以modbus TCP方式读取数据

C# winform 以modbus TCP方式读取数据 一、modbus开发 //nmodbus4读取到的数据都是ushort类型TcpClient tcpClient new TcpClient();tcpClient.Connect("127.0.0.1", 502);//连接到主机ModbusIpMaster master ModbusIpMaster.CreateIp(tcpClient);//Ip 主站 byte …

【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

TCP 重传、滑动窗口、流量控制、拥塞控制 TCP 重传超时重传快速重传 滑动窗口流量控制拥塞控制慢启动拥塞避免拥塞发生快速恢复 TCP 重传 TCP重传是当发送的报文发生丢失的时候&#xff0c;重新发送丢失报文的一种机制&#xff0c;它是保证TCP协议可靠性的一种机制。 TCP重传…

Redis集群安装

将Redis安装包分别上传到3个文件夹&#xff0c;并解压缩 #编译并指定安装目录 cd /root/usr/local/redis-cluster/redis-7001/redis-6.2.6/ make make PREFIX/root/usr/local/redis-cluster/redis-7001 install # cd /root/usr/local/redis-cluster/redis-7002/redis-6.2.6/ m…

FANUC机器人初始化系统的基本方法和步骤

FANUC机器人初始化系统的基本方法和步骤 首先,在做系统初始化之前,必须做好系统的备份,这里做个镜像备份,更详细的镜像备份步骤可参考以下链接中的内容: FANUC机器人进行全部备份和镜像备份以及加载备份文件的具体操作(图文) 如下图所示,在示教器右边的USB接口上插个…

数据结构(一)绪论

2024年5月11日 一稿 数据元素+数据项 逻辑结构 集合 线性结构 树形结构 图结构

没有公网ip,如何实现外网访问内网?

目前拨号上网是最广泛的上网方式&#xff0c;这种方式优点是价格便宜&#xff0c;缺点是没有固定公网ip&#xff0c;每次重新您拨号ip地址都会变。如果有一台服务器&#xff0c;需要实现外网访问&#xff0c;在没有固定公网ip的环境下&#xff0c;该如何实现呢&#xff1f;使用…

认识卷积神经网络

我们现在开始了解卷积神经网络&#xff0c;卷积神经网络是深度学习在计算机视觉领域的突破性成果&#xff0c;在计算机视觉领域&#xff0c;往往我们输入的图像都很大&#xff0c;使用全连接网络的话&#xff0c;计算的代价较高&#xff0c;图像也很难保留原有的特征&#xff0…

如何在windows server下安装mysql5.7数据库,并使用Navicat Premium 15可视化工具新建数据库并读取数据库信息。

如何在windows server下安装mysql5.7数据库&#xff1f; MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/点击↑&#xff0c;然后选择对应版本和平台↓下载 将下载后的安装包放入固定目录&#xff08;这里以D:…

最大子矩阵:前缀和、动态规划

最近在学习动态规划&#xff0c;在牛客上刷题时碰到了这一题。其实最初的想法是暴力和前缀和&#xff0c;但是时间复杂度极高&#xff0c;需要套4层循环。后来去网上搜了一下相关的题解和做法&#xff0c;进而了解到了前缀和&#xff0b;线性动态规划的做法。但是在成功做出这题…

带头单链表 C++实现

节点定义 带头单链表&#xff1a;我们只需要一个结点指针指向整个链表的第一个节点&#xff0c;这样我们就可以通过next指针访问整个链表内的所有节点 template<class T> struct ListNode {T _val;ListNode* _next;ListNode(const T &val):_val(val),_next(nullptr){…

开发组合php+mysql 人才招聘小程序源码搭建 招聘平台系统源码+详细图文搭建部署教程

随着互联网的快速发展&#xff0c;传统的招聘方式已经不能满足企业和求职者的需求。为了提高招聘效率&#xff0c;降低招聘成本&#xff0c;越来越多的人开始关注人才招聘小程序、在线招聘平台。分享一个人才招聘小程序源码及搭建&#xff0c;让招聘更加高效便捷。系统是运营级…

【算法】滑动窗口——串联所有单词的子串

今天来以“滑动窗口”的思想来详解一道比较困难的题目——串联所有单词的子串&#xff0c;有需要借鉴即可。 目录 1.题目2.下面是示例代码3.总结 1.题目 题目链接&#xff1a;LINK 这道题如果把每个字符串看成一个字母&#xff0c;就是另外一道中等难度的题目&#xff0c;即&…

2022——蓝桥杯十三届2022国赛大学B组真题

问题分析 看到这个问题的同学很容易想到用十层循环暴力计算&#xff0c;反正是道填空题&#xff0c;一直算总能算得出来的&#xff0c;还有些同学可能觉得十层循环太恐怖了&#xff0c;写成回溯更简洁一点。像下面这样 #include <bits/stdc.h> using namespace std; in…

用 Supabase CLI 进行本地开发环境搭建

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;Supabase CLI&#xff08;1.1&#xff09;安装 Scoop&#xff08;1.2&#xff09;用 Scoop 安装 Supabase CLI &#xff08;二&#xff09;本地项目环境&#xff08;2.1&#xff09;初始化项目&#xff08;2…

C++ | Leetcode C++题解之第86题分隔链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* partition(ListNode* head, int x) {ListNode* small new ListNode(0);ListNode* smallHead small;ListNode* large new ListNode(0);ListNode* largeHead large;while (head ! nullptr) {if (head-…

Spring STOMP-消息处理流程

一旦STOMP的接口被公布&#xff0c;Spring应用程序就成为连接客户端的STOMP代理。本节描述服务端消息处理的流程。 spring-messaging模块包含消息类应用的基础功能&#xff0c;这些功能起源于Spring Integration项目。并且&#xff0c;后来被提取整合到Spring框架&#xff0c;…

Zookeeper 注册中心:单机部署

序言 本文给大家介绍 Zookeeper 单机部署流程、 如何与 Spring 整合使用。除此之外&#xff0c;还有 Zookeeper 作为注册中心与 SpringCloud 的整合流程。 一、部署流程 官网下载 Zookeeper 安装包 解压安装包到指定目录 进入 apache-zookeeper-3.8.4-bin/conf 目录&…