首页 > 其他分享 >领域驱动设计-软件核心复杂性应对之道:第七章

领域驱动设计-软件核心复杂性应对之道:第七章

时间:2023-05-22 18:44:06浏览次数:39  
标签:cargo 运输 复杂性 之道 carrier 第七章 enterprise segment 货物

第七章 使用语言:一个扩展的实例

7.1 货物运输系统简介

1)跟踪客户货物的主要处理部署

2)事先预约货物

3)当货物到达其处理过程中的某个位置时,自动向客户寄送发票

一个货物从货主手上通过托运公司运输货物,从起始点到目的地,托运公司(可能只负责一段路途,再由合作伙伴/外包/私人等接力)负责计划路线,可能由多种运输方式组成,还要区分比如:省内,省外,跨国运输等。空运+水运+陆路运输(大卡车/火车)等,每种运输都有中转点(换人不换运输方式,换人换方式,交接手续),最终到达目的地

  • cargo(货物 大宗货物 比如大米,有几十个集装箱。石油,多少罐)
  • customer(客户:货主,收货人,货运公司,货轮,航空公司,货车司机,火车货运公司,海关,港口码头,仓库管理公司),客户角色
  • specification(规格)
  • carrier(运输载具):车/船/飞机/火车/人力
  • carrier movement(运输动作):某个carrier(车/船)执行的一个从一个location(地点)到另一个location的旅程,cargo被装上carrier后,通过carrier的一个或多个carrier movement,就可以在不同地点之间转移
  • handing event(处理事件:装货,卸货,收货人提货)
  • delevery history(运输历史):反映了cargo实际上都发生了什么事情

成功的运输将会是一个满足delevery specification目标的delevery history对象

7.2 隔离领域:应用程序的引入

1)tracking query,跟踪查询,访问某个cargo过去和现在的处理情况

2)booking application(预定应用),允许注册一个新的cargo,并使系统准备好处理它

3)incident(事件) logging application(事件日志应用),它记录对cargo的每次处理(提供通过tracking query找到的信息)

7.3 将entity和value object区别开

  • customer ENTITY

  • cargo ENTITY

  • handing event ENTITY

  • carrier movement ENTITY

  • location 名称相同的两个地点不是同一个位置,经纬度可以提供一个唯一键,但这并不是一个非常可行的方案,location更可能是某种地理模型的一部分,这个模型根据运输航线和其他特定于领域的关注点将地点关联起来。因此使用任何一种自动生成的内部标识符就足够了。

  • delivery history ENTITY (流转历史)

  • delevery specification VALUE OBJECT (路线规划)

  • role VALUE OBJECT (客户角色)

7.4 设计运输系统中的关联

image

7.5 aggregate边界

customer、location、carrier movement、cargo(delivery history、delivery specification、handing event)

7.6 选择repository

有5个entity是aggregate的根,因此在选择存储库时只需考虑这5个实体,因为其他对象都不能有repository
image

7.7 场景走查

7.7.1 应用程序特性举例:更改cargo的目的地

delevery specification删除,创建新的

7.7.2 应用程序特性举例:重复业务

相同customer的重复预订往往是类似的,因为他们想要将旧cargo作为新cargo的原型。原型模式

  • delevery history:创建新的
  • customer roles:复制
  • tracking id:提供新的tracking id,它应该来自创建新cargo时的同一个来源

7.8 对象的创建

7.8.1 cargo的factory和构造函数

//cargo是aggregate的根
public Cargo(String id){
  trackingID = id;
  deleveryHistory = new DeleveryHistory(this);
  customerRoles = new HashMap();
}

7.8.2 添加一个handing event

货物在真实世界中每次处理,都会有人输入一条handing event记录

//CARGO ID,完成时间和事件类型
public handingEvent(Cargo c,String eventType,Date timeStamp){
  handler = c;
  type = eventType;
  completionTime = timeStamp;
}

//装货事件
public static HandingEvent newLoading(Cargo c,CarrierMovement loadedOnto,Date timeStamp){
  HandingEvent result = new HandlingeVENT(C,loading_event,timeStamp);
  result.setCarrierMovent(loadedOnto);
  return result;
}

模型中的Handing Event是一个抽象,它可以把各种专用的Handing Event类封装起来,包括装货、卸货、密封、存放以及其他与Carrier无关的活动。它们可以被实现为多个子类,或者通过复杂的初始化过程来实现,也可以将这两种方法结合起来使用。通过在基类(handing event)中为每个类型添加factory method,可以将实例创建的工作抽象出来,这样客户就不必知道实现的知识。factory必须知道哪个类需要被实例化,以及应该如何对它初始化。

image

7.9 停下来重构:cargo aggregate的另一种设计

image

7.10 运输模型中的modele

image

7.11 引入新特性:配额检查

公司可以根据货物类型、出发地和目的地或任何可作为分类名输入的其他因素来制定不同类型货物的运输配额。这些配额构成了各类货物的运输量目标,这样利润较低的货物就不会占满 配额而导致无法努书利润较高的货物,同时避免预定量不足(没有充分利用运输能力)或过量预订(导致因频繁地运输超出运输能力而取消客户预订,最终损害客户关系)

现在,他们希望把这个功能集成到预订系统中。这样,当客户进行一个预订时,可以根据这些配额来检查是否应该接受预订。
image
连接两个系统

销售管理系统和运输系统,创建一个类,做模型和销售管理系统语言之间的翻译。

划分业务

这种类型的货物可以接受多少预订,cargo的类型是什么

企业部门单元(enterprise segment),value object,每个cargo都必须获得一个enterprise segment类

image
allocation checker将充当enterprise segment与外部系统的类别名称之间的翻译。cargo repository还必须提供一种基于enterprise segment的查询。在这两种情况下,我们可以利用与enterprise segment对象之间的协作来进行操作,而不破坏segment的封装。

问题:

  1. 给预订系统分配了一个不该由它执行的公众,执行业务规则属于领域层的职责,而不该在应用层执行
  2. 没有清楚地表名预订系统是如何得出企业部门单元(enterprise segment)的
    image
    1.获得货物的enterprise segment

2.根据enterprise segment获得预订的数量

3.传入cargo和已预订的数量,查询是否在范围内?

enterprise segment是一组维度,他们定义了一种对业务进行划分的方式。这些维度可能包括我们在运输业务中已经提到的所有划分方法,包括时间维度

标签:cargo,运输,复杂性,之道,carrier,第七章,enterprise,segment,货物
From: https://www.cnblogs.com/lhxBlogs/p/17421441.html

相关文章

  • 《程序员修炼之道》笔记3
     最后,具体到实际问题,当我们在编程时,项目开始之前,应该注意一些什么呢?                本书作者郑重提倡开始编程之前,请深思熟虑,不要靠巧合编程,所谓巧合编程,就是不加思索,接到任务开始coding,run一下,正常运行了,甚至于自己都不清楚它为什么能运行,作者批注这是由于......
  • 《程序员修炼之道》笔记1
       首先不得不说这是一本熔知识,哲理,幽默与实践与一炉的奇书,引导你领悟程序设计的真谛,只可惜我没能好好的理解透彻,更加难得可贵的是它是一本英文原著,却有着丰富的难词和背景信息注释。本书出版之后,两位作者都参与起草了敏捷运动的纲领性文件《敏捷宣言》,所以敏捷软件开发可以......
  • 《程序员修炼之道》笔记2
    通过阅读书籍,想和同学们分享简单介绍几个非常重要的原则和习惯:1,DRY—don’trepeatyourself     由于各种原因,代码的复制有时候难以避免,为了你的代码效率,千万不要自我复制。复制的代价可想而知,当你修改一处时,你必须得修改其他代码,这样的代码是难以管理的,更不幸的是你常......
  • 《程序员修炼之道--从小工到专家》阅读笔记02
    《程序员修炼之道--从小工到专家》第二章和第三章的主题是“实践”和“注重实效”,本文是本人对这两章节的阅读笔记。第二章:实践本章的核心观点是:软件开发是一门实践性很强的技艺,需要不断地实践和锤炼,才能取得进步和提高。而编写代码需要掌握多方面的技巧和工具,并不是只要会某一门......
  • 《程序员修炼之道:从小工到专家》14
    多元程序设计和时间耦合 多元程序设计致力于通过元数据等方式使代码变得“软化”、易于修改,通过对代码的“编写”而不是未“修改”减少对代码原有结构的改变,降低BUG产生的可能性这让我想起曾经在编写“四则运算”的随即括号代码是遇到的问题,在不添加相关代码的情况下可以正常......
  • 《程序员修炼之道--从小工到专家》阅读笔记01
    《程序员修炼之道–从小工到专家》是一本经典的软件开发实践指南书籍,被许多程序员视为进阶必读之书。以下是本人对该书第一章节的阅读笔记。第一章节题为:为什么需要修炼?显然,程序员和武林中的武功修炼者一样,都需要经过长期的学习、训练和实践,才能成为真正的专家。而与武术不同的是......
  • 《程序员修炼之道:从小工到专家》12
    何时使用异常和怎样配平资源 在web编程时会用到异常,单反程序不能按照预想正常运行时就会调用异常终止程序 配平资源感觉是对程序的优化,合理的分配资源,如动态分配内存之后及时释放,避免两个进程相互调用时陷入等待的死循环等......
  • 软件系统的复杂性(译)
    软件的复杂性:必要的、意外的和偶然的随着我们工程领域的发展,软件的复杂性似乎变得越来越难以控制了。为了正确理解如何处理不断增加的复杂性,重要的是要分辨出软件复杂性的三种基本类型:基本的、偶然的和附带的复杂性。基本的复杂性这种类型的软件复杂性与我们试图建模的领域的复杂......
  • 《程序员修炼之道:从小工到专家》11
    死程序不说谎和断言式编程 没有完美的程序,再老练的程序员都可能出现“不可能”问题,在这种时候我们往往会选择关闭运行的程序以避免出现更大的损失但问题必须要解决,程序早晚要重新启动,那么对可能出现问题的地方进行提示编写就是非常有必要的——虽然这不能帮我们解决问题但是却......
  • 程序员修炼之道阅读笔记01
    程序员修炼之道—从小工到专家 是我这学期阅读的第二本书,这本书的前言中告诉了我们这本书的大体内容,它将告诉我们我们怎样以一种我们等够遵循的方式去编程。在刚开始读这本书的时候,我的收获就很大,我们要做注重实效的程序员,那么什么是注重实效的程序员呢?1、这需要我们......