假设一个场景:与客户讨论开始新的工作:
客户:我们的用户需要处理三种不同类型的任务:快速任务、复杂任务和监督任务。
我们:它们之间有什么区别?
客户:快速任务只是登记某人做了某事。真的很简单。
我们:嗯。
客户:复杂的任务比较麻烦,需要特殊设备和资格卡。
我们:监督任务呢?
客户:监督任务需要监督人员的关注,并给予评估反馈。而且,这些任务可能有多人参与。
我们:重要的是要记住,无论是复杂任务还是监督任务,都可能需要一些时间,我们需要知道他们的时间,我们需要知道他们的状态。
亲爱的读者,你的直觉是什么?
我们应该使用一个单独的任务表,还是每个任务都使用一个表?监督任务、复杂任务和快速任务?
那么我们可能还需要将资格卡、监督员和评估作为单独的表来表示。
啊,我们差点忘了多人参与 ComplexTask 的问题--我们的客户对底层职业的正确名称只字未提,我们就叫他们工人吧。
此外,在幕后我们还得到了更多细节,即所有类型的任务都与共同的数据集相关,例如 Worker。
语言是流动和消失的东西,它不是有形的,也可能是不稳定的。
让我们来勾勒一下:
正如您所看到的,我们可以进行扩展,因为我们有任务类型TaskType和任务状态表TaskStatus,以防客户改变主意。很聪明,不是吗?
有什么问题吗?
你可能已经对我有所了解了(我希望如此,亲爱的读者!)--我喜欢夸大其词。
我故意把注意力集中在名词上,完全忘记了问一些非常重要的问题:
- 我们的用户是谁?
- 他们将如何使用我们的系统?
- 目前满足他们需求的方式是什么?
- 这个系统应该如何帮助他们实现目标?
当然,我轻描淡写地举了个例子。
但是,在我们的日常对话中,有多少时候我们会听到状态、状态标志、实体、数据模型?
我们有多少次以 "两个实体共享相似的数据集 "为前提,并假设它们可能由同一个实体来表示?
在我们的这个演示案例中,"任务"(Task)可能被表示为一个基类,这样我们就可以避免数据重复。
没有人会反对 QuickTask 是一个任务(Task),对吗?
寻找关系
我们寻找层次,寻找事物之间的联系。
如果我们放慢脚步,扪心自问--我们想象中的客户描述了什么?
从我们称之为 "声音 "的非结构化、模拟音频信号中,我们诠释了这些词语,使它们变得更有条理。
立即关注名词、名词之间的关系,并可能关注属性(也称为数据)。
事实上,从实体关系图(ERD)的角度来思考,可以帮助我们找到所有这些关系,ERD 可能与在 SQL 数据库等持久性工具中有效表示实体和数据有关。
说到建模,这可能被认为是一个相当低的层次。
这只是一个层次--还有更多。
先有什么?实体还是实体?
在开始绘制 ERD 草图之前,让我们回想一下从故事一开始的讨论中听到的内容。
我们如何称呼所有突出显示的 "事物"?
人们用来称呼这些 "事物 "的首要标签是实体。
每个实体都有与之相关的数据。
这个词带有偏见,很容易让我们陷入非常具体、狭隘的思维中。
为了避免我们的思维与 TDD 和 DDD(表驱动开发和数据库驱动设计)纠缠不清,我喜欢用另一个词。
我喜欢用“概念Concept”标签来表示这些 "东西"。
"这只是一个概念Concept"--我不知道技术上如何实现它。
我什么都不期待,所以我做好了一切准备。
不被来自执着领域的锚束缚,就能获得解放。
我们现在可以打破常规。
概念Concept的本质是什么?
我们不需要问自己 "一项任务可以有多少设备?"- 这是次要的。
我们不需要考虑 "资格卡 "是否有名字,它的最大长度是多少--这不会造成问题。
概念没有状态,实体才有。
考虑到这一点,我们可以玩一玩概念这个名称:"已完成的快速任务 "有存在意义吗?它与 "已完成的复杂任务 "有区别吗?
记住,我们现在讨论的还不是技术实现!
在我的脑海中,概念可以自然地出现和消亡--当然不是字面上的意思。
- 它们可以通过相互转换而产生和消亡。
- 它们经过加工,演变成其他概念。
快速任务会变成复杂任务吗?
让我们设想一下,我们的客户被问到:"一项快速任务会不会因为一些意想不到的复杂因素而无法完成?
假设客户回答是的,那么任务类型就会从 "快速 "变为 "复杂"。
(虽然有些业务人员受到了数据库驱动设计的伤害--但我们需要帮助他们)
很抱歉,这听起来根本不像表达问题本身的语言。
很有可能,答案会有点不同:"是的,快速任务最终可能会变成(Become a)复杂任务"。
"Become a(成为、变成)"
- 是非常重要的表述
- 是建模成熟度等级中的最高级别。
如果我们仔细倾听自己的心声,就会发现日常生活中的各种概念正是以转化的形式表达出来的。
生生不息
我们迟早会意识到,我们会很自然地想到,例如,一份重要文件变成了 "已签名",或者背包里的旧三明治变成了 "腐烂"。
至少在我看来,用概念进行思考提供了这种可能性。
概念无法编译
是的,概念是第一步--它们不会产生任何错误,也不会导致服务器宕机(或者会吗?)
当然,有人可能会说我们在制造不必要的复杂性。
有人可能会说--"你把以前比较简单的事情复杂化了!"。
建模的成本增加了!
概念能对围绕问题域语言的 "事物 "进行建模:(banq注:围绕问题语言,也就是问题的上下文)
没有人说我们必须在代码中体现一切。
考虑到这一点,我不知道--如果我们的概念不是关系型的,而是图形型的呢?
也许并不存在我们从 SQL 数据库中了解到的关系。
我们该如何持久化我们的概念,又该如何在应用程序中表示它们--这些都是我们需要在某些时候向自己提出的完全不同的问题。
它们会出现的,不用担心。
(如何持久,是关系还是图形属于解决方案域,正如去医院看病,医院必须找出你身体的问题,也就是确认是什么病,至于如何治病是属于解决方案,不是问题域)
概念映射:从直线到箭头实现状态转换
让我们回到我们的小案例,快速任务变成复杂任务。
我们知道,复杂任务有一些与之相关的状态,对吗?
了解了这一点,让我们设想一下,我们的客户告诉我们,他们认为以下状态是有效的:
- 进行中(ongoing)
- 已分配(assigned)
- 已拒绝(rejected)
- 已阻止(blocked)
- 失败(failed)
它有自己的用武之地,但在 "领域建模 "时却不适用。
例如,当我们使用关系数据库时,它可能会大有用武之地。
因此,现在让我们试着把每个 "状态 "和复杂任务结合起来,将其视为一个独立的......概念。
这种有有箭头的概念网可以称为 "概念图"。
它能帮助我捕捉概念的转换本质,并从最高级别--"成为became a"--建立模型。
更重要的是,用户很有可能可以在 "Blocked复杂任务 "上执行某种操作,但却无法将其应用到 "Assigned复杂任务 "上。
这些都是我们需要针对每个概念提出的额外问题,幸好它们都位于建模成熟度等级的 "中间 "层。
亲爱的读者,你可能已经注意到了,它与有限状态机非常相似。
试着向你的业务人员介绍一下有限状态机,不知道他们会有什么反应。
什么是数据?
我们不应忘记每个企业和人类事业中非常重要的方面--数据。
我们也可以称之为信息--只是为了打破持久性领域的锚定。
它与我们的生活息息相关,并占有一席之地--也许并不是从第一天起就直接占有一席之地。
在我们的概念图中,每一个过渡都可能需要非常精确的细节。
如何存储这些信息并不是我们最关心的问题--至少不应该是。
实体仇敌?
我是实体憎恶者,在抱怨数据的无关性吗?
算是吧。
"万物皆有其位,万物皆有其所"。
我认为,在特定的阶段(#上下文),它们可能无关紧要,而在另一个阶段,它们却扮演着最重要的角色。
如果我们不利用我们的卓越技术,我们的用户就可能从我们的系统中获得价值。
我们不应该限制自己去探索其他人类使用的语言中的概念。
我们的概念并不附带布尔标志 IsValid 或 IsActive,尽管它们在技术上可能是这样实现的。(当谈到布尔时,您可能会对 "布尔是否有害?)
当我们从概念转向实体时,我们最终可能会谈论行为和责任。
然后,我们可能会从实体过渡到数据,因为我们需要使用信息。
这样的过程不会是离散的--它肯定会是动荡的、混乱的、流动的和充满新意的--就像生命一样。
下次,亲爱的读者,当你开始工作时,问自己一个问题:
我现在的推理水平如何?