《软件方法(下)》8.2.5.2 属性是否直接描述类(202402更新)(2)

导致出现违反本要点的错误的原因有:

(1)缺少抽象能力

缺少抽象能力的建模人员经常会把手上素材的信息,一一对应地映射为类和属性,导致本来属于多个类的信息被合并在一个类中。

如图8-63,建模人员对照着一张货物运输托运单,直接把它映射成类,照抄上面的每一栏作为属性。

图片

图8-63 错误:直接把素材照搬成类

建模人员有时还觉得挺符合“类的属性”的。“货物运输托运单的货物名称”,没错啊,手边这张货物运输托运单上确实明晃晃地印有“货物名称”四个字嘛。

托运单、出库单、销售单等各种单据,以及身份证、工作证、图书卡、设备卡等各种卡片和证件,在信息时代之前就已经存在了。它们相当于某种“信息化”的存储结构,存储一个或多个概念的信息,只不过保存的载体不是电子载体,而是甲骨、铜器、竹片、木片、帛布、纸张。

现在,既然用信息系统取代了这些单据、卡片和证件,那么要建模的实体类应该是它们所存储的领域概念,而不是单据、卡片和证件本身。

图8-63右侧的类“货物运输托运单”应该变成如图8-64。

图片

图8-64 建模早期信息存储载体所存储的领域概念

开发团队中可能会有人唧唧歪歪,什么“性能”啦,什么“我们之前都是这样做”啦。碰到这种情况,也不用祭出鲁迅先生的“从来如此,便对么?”,你只需要问他,扔给他一张类似图8-63的**单,他有能力干脆利索地得到类似图8-64吗,没能力就让他TM的闭嘴。

★其实,如果一个人知道如何得到一个清晰、无冗余的模型,说明他具备了一定的建模能力,往往也不会在分析的时候担心这些问题,因为他知道,如果碰到性能问题,可以按照某些套路添加冗余,这些套路和目前所思考的领域知识没有关系,没有必要混杂进来。

在有能力得到图8-64的基础上,可以再来考虑需不需要一个如图8-63右侧的“货物运输托运单”类来维护当时的快照。因为随着时间的推移,对象的属性值会变化。

例如图8-64中,随着时间的推移,如果某个单位的名称或地址改掉了,此时从图8-64计算出图8-63左侧的托运单快照,和事件发生的当时按照图8-63左侧填写的信息是不一样的。

如果这样的快照很重要,可以另外加一个如图8-63右侧的快照类来维护这些信息,这个类是孤立的,和图8-64的类不存在关联。

但这样做很容易出现沿着关联线向外延伸,雪球越滚越大的情况。如图8-64,单位的联系人会换人,人员的电话会改变……最终可能需要一个巨大的类,把所有通过关联线连在一起的类的所有属性组合在一起,而背后的数据量也是庞大的。

更合理的做法是记录本质的变更来源。如果单位变更名称和地址是值得关注的事情,应该添加一个类记录单位变更名称和地址的细节,或者说,记录所有值得记录的对象属性值变更的细节。在此基础上,需要类似图8-63的某个时间点来自多个对象的属性值组合快照时,可以通过计算来还原。

在这里,我们要认清楚非常重要的一点:本质是对象之间存在关联,而不是对象属性值之间存在关联。如图8-64,两个单位之间曾经存在的某次托运关系,并不会因为单位后来改名或改地址而变化,相对于如图8-63列出一堆属性值,记住“托运”和“单位”之间的关联是更本质的——当然,并不影响从本质模型还原出各种视图或报表。

正如上文提到的,如图8-63是在信息化时代之前的一种“信息化”的存储结构。当时不要说没有方法学,即使有方法学让你先分解概念为图8-64,也没有计算设施把它们按需要组合成图8-63或更多的视图。

现在,既然有了条件,就没有必要再去模仿条件不足时的拙劣“模型”了。

很可能在这个时候,伪创新又乘机迎合那些没有抽象能力又不愿意学习的无能之辈。伪创新的说法是:图8-63的快照是发生过的事情,是不会变化的,各种所谓的“流水”才是本质!于是,无能之辈非常开心,热烈拥抱伪创新。

我们可以用科学研究类比一下:背后的规律没搞清楚时,要推测某个数据,可能是靠“经验”来推测。“经验”其实就是发生过的“流水”的记忆。当科学家研究巨量已有的“流水”(即实验数据),探索出其中的规律后,这时再推测数据,就没有必要从之前的巨量“流水”来推测了,根据归纳出来的公式推测即可。当然,之前或之后的各种“流水”可以继续保留,但它们不是本质,是现象。

何况,不是所有的系统都需要保存“流水”。电梯每天上上下下,不知发生多少次“召唤”事件,但目前的电梯系统并不会记录“召唤”事件的细节——谁召唤的、什么时候召唤的……系统只需要维护本质的行为规则,如果采用本书的方法学,可以选择用状态机来表达。

当然,也许有一天,电梯系统有了足够的存储资源,会记录所有的“召唤”流水,但这和背后的规律没有关系。系统是否记录某个事件的细节,不影响事件是否发生、事件是否产生效果,以及背后的行为规则。

(2)受关系数据库建模的影响

建模人员有时会犯这样的错误,在一个类中放上另外一个类的属性作为“外键”。比如针对上面的例子,建模人员会想:“人员”里放“组织名称”确实不合适,但是放个“组织编码”作为外键总可以吧?其实也不可以。"组织编码"是“组织”的属性,是封装在“组织”中的秘密,“人员”不应该拥有“组织”的任何属性,它只能通过关联拥有“组织”对象,然后通过访问“组织”对象公开的操作来间接访问“组织”的属性。

图片

图8-65 不需要“编码”作为“外键”

“人员”里放“组织编码”不合适,放一个无意义的标识“组织ID”呢?同样也不可以。因为这个“组织ID”是“组织”的标识,前文已经说了,标识属性此时不需要存在,所以“组织ID”在“组织”里不存在,更不要说放到其他类中作为“外键”了。

图片

图8-66 不需要“ID”作为“外键”

在设计工作流,需要把类图映射到关系数据库时,确实需要把"组织"表的主键(可能是"编码"也可能是生成的代理主键)放在"人员"表中作为外键,但正如上文所说,这同样是另一个领域的知识,而且映射规律和核心域知识无关。

状态属性和类的匹配

状态属性的名称是一个形容词,类型为布尔类型,用来标记对象是否处在某个状态,如图8-67。

图片

图8-67 状态属性

这些状态属性可能是来自素材中的定语,例如,用例规约提到“可享受优惠的顾客”,那么在识别的时候可能会先把“可享受优惠”放在“顾客”类中。

和“类的属性”刚好相反,状态属性和类连在一起说,要能说得通"属性的类"。例如,图8-67中,“可享受优惠的顾客”是说得通的。

8.2.5.3 属性是否可以从其他地方推导

如果一个属性可以从其他地方推导出来,那么这个属性就是冗余的,可以删掉。

如图8-68,人的年龄可以从出生日期计算得到,应该把年龄删掉。

图片

图8-68 年龄可以从出生日期推导

这个“其他地方”也可以是所关联的类的属性。如图8-69,订单的总金额可以由各个订单项的金额合计得到,那么可以考虑把总金额删掉。

图片

图8-69 总金额可以从各订单项金额合计

状态属性的冗余

状态属性是冗余的,背后往往隐藏着更多的逻辑,需要进一步思考,把它变成更合适的模型内容,但这涉及到还没讲到的知识点,此处只简单举例,后文还会详述。

以图8-55中的“订单”为例,如果问一个“订单”对象,你是“待支付的订单”吗?如果“订单”通过自己的资源就能回答这个问题——例如,查询是否有“支付”对象和自己关联,那么“待支付”就可以作为“订单”的状态机中的一个状态。

图片

图8-70 “待支付”变为“订单”的状态

再看图8-55中的“会议室”。如果问一个“会议室”对象,你是“合适的会议室”吗?这时的回答是犹豫的,因为会议室合适不合适,还需要看开哪个会议,会议A也许不合适,但会议B可能就合适。这样含义的“合适”不能成为“会议室”的状态。

这个“合适”的演变可能并不简单,只是在“会议室”和“会议”之间建立一个“合适”的多对多关联,可能并不能满足要求,甚至是冗余的,因为计算哪些会议室对某个会议合适,正是系统的一个责任。如果是这样,就需要进一步建模背后的规则,如图8-71。

图片

图8-71 “合适”背后的规则

但是,如果“合适”的含义是“当前使用会议室的会议是否合适”,有图8-71的加持,再加上一个“当前会议”的关联,“会议室”是可以回答这个问题的。此时,“当前会议合适”就可以作为“会议室”的状态,其他状态可能有“当前会议不合适”、“无当前会议”、“装修中”。

★把状态放在“会议”,来一个“当前会议室合适”可以吗?也可以。放在哪里更好,后文还会再探讨。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ETL、ELT区别以及如何正确运用

一、 浅谈ETL、ELT ETL与ELT的概念 ETL (Extract, Transform, Load) 是一种数据集成过程,通常用于将数据从一个或多个源系统抽取出来,经过清洗、转换等处理后,加载到目标数据存储中。这种方法适用于需要对数据进行加工和整合后再加载到目标…

Django学习笔记-HTML实现MySQL的图片上传

1.django项目编写index.html代码 创建form表单,路由指向upload,请求方式post,enctype设置"multipart/form-data", post请求添加{% csrf_token %},编写两个input,上传和提交 2.添加upload路由 3.views中创建upload 1).获取上传的文件,没有上传则返回"没有指定…

打码半年,开源一款自定义大屏设计软件!

hi,大家好,我是Tduck马马。 最近我们开源了一款大屏软件-TReport,与大家分享。 TReport是一款基于Vue3技术栈的数据可视化系统,支持静态、动态api等数据源;可用于数据可视化分析、报表分析、海报设计使用。 提供自定…

Stable Diffusion 绘画入门教程(webui)-图生图

通过之前的文章相信大家对文生图已经不陌生了,那么图生图是干啥的呢? 简单理解就是根据我们给出的图片做为参考进行生成图片。 一、能干啥 这里举两个例子 1、二次元头像 真人转二次元,或者二次元转真人都行, 下图为真人转二次…

.net6 webapi log4net完整配置使用流程

前置&#xff1a;为项目安装如下两个依赖 1.创建文件夹cfgFile 2.创建log4net.Config <?xml version"1.0" encoding"utf-8" ?> <log4net><appender name"ConsoleAppender" type"log4net.Appender.ConsoleAppender"…

使用备份工具xtrabackup进行差异备份详细讲解

差异备份 基于第一天进行差异备份 删除之前修改的数据备份 [rootservice ~]# rm -rf /data/backup/* [rootservice ~]# ls /data/backup 完整备份 [rootservice ~]# xtrabackup --defaults-file/etc/my.cnf --backup --target-dir/data/backup/base/ -uroot -pWyxbuke00. -H…

Collection集合体系(ArrayList,LinekdList,HashSet,LinkedHashSet,TreeSet,Collections)

目录 一.Collection 二.List集合 三.ArrayList集合 四.LinkedList集合 五.Set集合 六.hashSet集合 七.LinkedHashSet集合 八.TreeSet集合 九.集合工具类Collections 集合体系概述 单列集合&#xff1a;Collection代表单列集合&#xff0c;每个元素&#…

大白话说说Docker容器默认网络模型工作原理

Docker的默认网络模型 —— 桥接模式&#xff08;Bridge&#xff09; 当你不做任何特殊设置时&#xff0c;Docker会使用一种叫做“桥接模式”的网络设置。这就像是给你的容器小房子安装了一个虚拟的桥接网络。这座桥连接着容器和你的电脑&#xff08;宿主机&#xff09;&#…

Jmeter之内置函数__property和__P的区别

1. __property函数 作用 读取 Jmeter 属性 语法格式 ${__property(key,var,default)} 参数讲解 小栗子 ${__property(key)} 读取 key 属性如果找不到 key 属性&#xff0c;则返回 key&#xff08;属性名&#xff09; ${__property(key,,default)} 读取 key 属性如果找不到 k…

Flink Task退出流程与Failover机制

这里写目录标题 1 TaskExecutor端Task退出逻辑2 JobMaster端failover流程2.1 Task Execute State Handle2.2 Job Failover2.2.1 Task Failure Handle2.2.2 Restart Task2.2.3 Cancel Task&#xff1a;2.2.4 Start Task 3 Task失败的自动重启策略 1 TaskExecutor端Task退出逻辑 …

算法项目(2)—— LSTM、RNN、GRU(SE注意力)、卡尔曼轨迹预测

本文包含什么? 项目运行的方式(包教会)项目代码LSTM、RNN、GRU(SE注意力)、卡尔曼四种算法进行轨迹预测.各种效果图运行有问题? csdn上后台随时售后.项目说明 本文实现了三种深度学习算法加传统算法卡尔曼滤波进行轨迹预测, 预测效果图 首先看下不同模型的指标: 模型RM…

MySQL学习Day19——索引的数据结构

一、为什么使用索引: 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教课书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。MySQL中也是一样的道理&#xff0c;进行数据査找时&#xff0c;首先查看查询…

相机图像质量研究(26)常见问题总结:CMOS期间对成像的影响--坏点

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

FreeRTOS学习笔记——(FreeRTOS中断管理)

这里写目录标题 一、什么是中断&#xff1f;&#xff08;了解&#xff09;二、中断优先级分组设置&#xff08;熟悉&#xff09;三、中断相关寄存器&#xff08;熟悉&#xff09;四、FreeRTOS中断管理实验&#xff08;掌握&#xff09; 一、什么是中断&#xff1f;&#xff08;…

【Azure 架构师学习笔记】- Azure Databricks (8) --UC架构简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (7) --Unity Catalog(UC) 基本概念和组件 前言 UC 简单来说&#xff0c;就是管理两样东西&#xff1a;用户和元存储。 用户管理 所有Databri…

Flink 在蚂蚁实时特征平台的深度应用

摘要&#xff1a;本文整理自蚂蚁集团高级技术专家赵亮星云&#xff0c;在 Flink Forward Asia 2023 AI 特征工程专场的分享。本篇内容主要分为以下四部分&#xff1a; 蚂蚁特征平台特征实时计算特征 Serving特征仿真回溯 一、蚂蚁特征平台 蚂蚁特征平台是一个多计算模式融合的高…

小程序红包服务端请求一直是签名错误如何解决

当小程序红包服务端请求一直显示签名错误时&#xff0c;这可能是由于多种原因导致的&#xff0c;包括密钥错误、参数错误、签名算法错误、时间戳问题以及网络请求问题等。解决这个问题需要细心检查和分析&#xff0c;下面将简单的介绍一下如何针对这些可能的原因进行排查和解决…

19个Web前端交互式3D JavaScript框架和库

JavaScript &#xff08;JS&#xff09; 是一种轻量级的解释&#xff08;或即时编译&#xff09;编程语言&#xff0c;是世界上最流行的编程语言。JavaScript 是一种基于原型的多范式、单线程的动态语言&#xff0c;支持面向对象、命令式和声明式&#xff08;例如函数式编程&am…

使用 Next.js 连接 mysql 数据库

前言 本文主要为大家介绍&#xff0c;如何使用 Next 框架实现一个简单的后端接口&#xff0c;并且从数据库中请求数据返回给前端。 实现 创建api/getData文件夹 项目创建完成后在 app 文件下新建api文件夹&#xff0c;在 api 文件夹下新建 getData 文件夹&#xff0c;在 ge…

Windows使用NVM安装NodeJS

*注 1、安装NVM前&#xff0c;建议先卸载电脑上现有的NodeJS&#xff0c;避免冗余。 一、NVM介绍 NVM&#xff1a;Node Version Manage&#xff0c;即Node的版本管理工具。使用NVM&#xff0c;可以很方便地在多个NodeJS版本之间进行切换。 由于项目开发当中&#xff0c;不同…