《软件方法(下)》8.3.4.1 关联是不得不记住的关系

DDD领域驱动设计批评文集

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

《软件方法》各章合集


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

8.3.4 识别关联关系

本节的内容更应该放到“识别泛化关系”的前面来讲,但考虑到关联的内容比较多,决定还是放在“识别泛化关系”的后面。

所以,有必要在这个地方提醒一下,把泛化放在关联前面讲解,不意味着泛化比关联重要,事实恰好相反。

在建模分析模型的时候,不使用泛化关系仅使用关联关系的情况并不罕见,反过来,如果仅使用泛化关系,就要怀疑是不是犯了前面所提到的拼凑泛化“or、er”伪面向对象错误。

8.3.4.1 关联是不得不记住的关系

前面已经说过,泛化和关联是类的静态关系,是系统要记住的关系。这个地方为什么又要强调一遍呢?

因为我们很少看见类似图8-113的泛化错误:

图片

图8-113 我们一般不会犯这样的泛化错误

我们把图8-113的泛化替换成关联,得到图8-114。建模的时候,出现类似8-114的情况很多。

图片

图8-114 类似这样的关联关系很常见

图8-113肯定是错的,图8-114则有可能正确,也有可能错误。所以,我们得来看一看,需要建模的关联关系是怎样的。

假设目标系统是一个企业管理系统。

这个系统可能需要知道一个字符串是否包含另一个字符串,例如“马宝国”里面是否包含“马宝”?

是否需要像图8-115那样,建立字符串的自反关联?

图片

图8-115 字符串的自反关联

不需要,因为这个问题已经有人解决了,例如.NET中的String.Contains。目标系统不需要一个个记住字符串之间的包含关系。

再来看.NET的这个Contains,它是怎样实现的?

是不是通过维护类似下面的字符串之间的关联:

{(“马宝国”,“马”),(“马宝国”,“宝”),(“马宝国”,“国”),(“马宝国”,“马宝”),(“马宝国”,“马国”),……}

然后查询这些关联得到结果?

同样不是。Contains从来没有,也不需要建立和维护这样的“关联”,它的结果是通过已经掌握的规律计算出来的。

★.NET(或Java)的String.Contains(背后是IndexOf)如何实现,读者可自行查询。

目标系统可能还需要计算一个数的立方,例如,x=3,x的立方等于多少?

同理,系统也不需要记住{(1,1),(2,8),(3,27),(4,64),……}这样的对应。

★花絮:国内的某本领域驱动设计名著说,函数式编程的加1函数add1,是根据x的值进行模式匹配得到结果的,还给出代码:

def add1(x: Int): Int=>x match{

case 0 =>1

case 1 =>2

case 2 =>3

case 3 =>4

//...

}

这就相当于建立自反关联了,如图8-116:

图片

图8-116 整数的自反关联

可是,这个add1函数,其定义域和值域都是整数。那可是一个无限集,代码是这样干的吗,这样干行吗?

另外,既然说是“模式匹配”,“模式”这个词蕴含把许许多多个例归纳或分类的意思。模式的个数应该是少量的,例如一个枚举“商品类型”。

这个add1却是把每一个整数做模式匹配,岂不是有无限个模式?

我不是函数式编程专家,只是提出疑问,各位读者有空赐教。

**********

回到正题。

目标系统可能还要知道,如果一名员工的工号是20249527,那么他的直接上级的工号是什么?

这个就不一样了,我们能找到像下面这样的“工号→直接上级工号”背后的计算规律吗?

先判断工号的奇偶,如果是奇数,则乘以3再加1,如果是偶数,除以2,重复以上过程,直至得到1。把停止后得到的数字序列按照UTF-8编码转成字符串,即可得到直接上级工号。

可惜,目前并没有发现这样的规律。

这时候,才需要我们建立关联来解决问题,如图8-117。

图片

 图8-117 员工的自反关联

系统得老老实实维护“员工→员工”之间的“直接上级(直接下级)”关联,例如数据库的“员工”表有这样的一些行:

图片

图8-118 数据库里的“员工”表

然后,目标系统在需要时查询这些数据。

我们要建模的,是当前无法计算的内容。

世界上万事万物,只要我们乐意,都可以找出它们之间的关系,但我们要建模的关联,是系统不得不一个个记住的内容,如果不记住,系统当前就无法完成满足需求的计算。

注意“当前”二字。

“工号→直接上级工号”到底有没有一个计算公式呢?

也许是有的,如果我们宇宙是由神级文明创造和控制的,一切运行都有其规律。如果有一天,我们掌握了其规律,很可能系统只需要记住少量参数,就可以完成任意“工号→直接上级工号”的计算。

我们用椭圆来类比。如果不了解椭圆的规律,要记住一个椭圆,需要记住很多个点的坐标值,而且得到的椭圆还不精确。后来,我们掌握了椭圆的方程,只需要记住4个值:两个焦点F1和F2,两个轴长a和b,如图8-119。

图片

图8-119 没掌握规律的椭圆和掌握了规律的椭圆

**********

了解了以上的知识,我们在建模关联的时候,要学会分辨哪些是不得不记住的,哪些是可以计算得到的。

例如,我们把图8-114的下半部图形的内容改成一个大多数人都很熟悉的领域,并把每两个类之间的“关联”补全(共C(4,2)=6条边),得到图8-120。

图片

图8-120 满满的“关联”,需要保留哪些?

删去3条边,只保留3条边就够了,结果如图8-121:

图片

图8-121 删去冗余“关联”后的结果

当然,这种情况下,那些刷废话的无能之辈可能会祭出“性能”的遮羞布,应对方法前文已讲述。

遮羞布的出现,有助于帮助我们识别无能之辈。初步鉴别之后,如果我们有心去翻查他的各种工件,大概率会发现各种各样的脓包。脓包在手,退可以求团结,需要亮剑时,严谨的建模匕首轻轻一划,脓包破裂飞溅满地。

  • 39
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值