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

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

时间:2023-04-10 22:57:26浏览次数:52  
标签:voyage 知识 cargo 模型 复杂性 第一章 之道 confirmation 规则

第一部分 让领域模型发挥作用

​ 每个模型都表示人们感兴趣的某方面显示或某种想法。模型是一种简化。它是对现实的解释,并把与解决问题密切相关的方面抽象出来,而忽略无关的细节。

​ 每个软件程序的目的都是为了执行某项活动,或是满足用户的某种需求。用户会把软件程序应用于某个主题区域,这个区域就是软件的领域。

​ 为了创建真正能为用户活动创造价值的软件,开发团队必须运用一整套与这些活动有关的知识体系。所需知识的广度可能令人望而生畏,信息量和复杂度也可能超乎想象。模型正式用于解决信息超载的问题。模型是一种知识形式,它对知识进行有选择的简化和有目的的结构化。适当的模型可以使人理解信息的意义,并专注于问题相关的信息。

建模更像是制作电影:出于某种目的而概括地反映现实。并以一种特殊方式将它们展现给观众,从而讲一个故事或阐明一个观点一样。

模型在领域驱动设计中的作用

1)模型和设计的核心互相影响

2)模型是团队所有成员所使用的交流语言的中枢

3)模型是浓缩的知识

软件的核心

​ :是为用户解决领域相关的问题的能力。所有其他特性,不管有多么重要,都要服务于这个基本目的。

​ 相反,技术人才更愿意从事精细的框架工作,试图用技术来解决领域问题。他们把学习领域只是和领域建模的工作留给别人去做。软件核心的复杂性需要我们直接去面对和解决,如果不这样做,必将导致工作重点的偏离。

image
​ 模型类图UML->原型->互动->将新学到的知识融合到模型中,然后反映到软件上。领域专家也可以从原型得到具体的反馈,从而印证自己的想法。

​ 模型将很多同义词和语言描写中的微小差别做了统一,并排除了数百条与问题没有直接关系的事实,这张图相当于一个框架,开发人员可以借助于它组织新的信息来更快地学习,从而更准确地判断哪些部分重要,哪些部分不重要,并更好地与PCB工程师进行沟通。

​ 当PCB工程师提出新的功能需求时,我就让他们带我走查对象交互的场景。当模型对象无法清楚地表达某个重要场景时,我们就通过头脑风暴活动创建新的模型对象或者修改原有的模型对象,并消化理解这些模型对象中的知识。

1.1 有效的建模要素

1)模型与实现的绑定

2)获得了一种基于模型的语言。最初,工程师们不得不向我解释基本的PCB问题,而我也必须向它们解释类图的含义。但随着项目的进展,双方都能够直接使用模型中的术语,并将它们组织为复合模型结构的语句,而且无需翻译即可理解互相要表达的意思。

3)开发一个蕴含丰富知识的模型。对象具有行为和强制性规则。模型并不仅仅是一种数据模式,它还是解决复杂问题不可或缺的部分。模型包含各种类型的知识。

4)提炼模型。在模型日趋完整的过程中,重要的概念不断被添加到模型中,但同样重要的是,不再使用或不重要的概念则从模型中删除。当一个不需要的概念与一个需要的数据有关联时,则把重要的概念提取到一个新模型中,其他那些不要的概念就可以删去了。

5)头脑风暴和实验。语言和草图,再加上头脑风暴活动,将我们的讨论变成"模型实验室",在这些讨论中可以演示、尝试和判断上百种变化。当团队走查场景时,口头表达本身就可以作为所提议的模型的可行性测试,因为人们听到口头表达后,就能立即分辨出它是表达得清楚、简洁还是表达得笨拙。

​ 正是头脑风暴的创造力和大量实验才使我们找到了一个蕴含丰富知识的模型并对它进行提炼,在这个过程中,基于模型的语言提供了很大帮助,而且贯穿整个实现过程中的反馈循环也对模型起到了"训练"作用。这种知识消化将团队的知识转化为有价值的模型。

1.2 知识消化

​ 在团队所有成员一起消化理解模型的过程中,他们之间的交互也会发生变化。领域模型的不断精化迫使开发人员学习重要的业务原理,而不是机械地进行功能的开发。领域专家被迫提炼自己所知道的重要知识的过程往往也是完善其自身理解的过程,而且他们会逐渐理解软件项目所需的概念严谨性。

​ 模型在不断改进的同时,也称为组织信息流的工具。模型聚焦于需求分析。它与编程和设计紧密交互。它通过良性循环加深团队成员对领域的理解,使他们更透彻地理解模型,并对其进一步精化。模型必须对领域实用和有用。他们必须非常精确,以便使应用程序易于实现和理解。

1.3 持续学习

​ 当开始编写软件时,其实我们所知甚少。同时,所有项目都会丢失知识。已经学到了一些知识的人可能干别的事了。团队可能由于重组而被拆散,这导致知识又重新分散开。被外包出去的关键子系统可能只交回了代码,而不会将知识传递回来。而且当使用典型的设计方法时,代码和文档不会以一种有用的形式表示出这些来之不易的知识,因此一旦由于某种原因人们没有口头传递知识,那么知识就丢失了。

​ 高效率的团队需要有意识地积累知识,并持续学习。对于开发人员来说,这意味着既要完善技术知识,也要培养一般的领域建模技巧。

​ 目的是学会与与PCB专家沟通,学会理解与应用有关的主要概念,并学会检查所构建的内容是否合理。

1.4 知识丰富的设计

​ 业务活动和规则如同所涉及的实体一样,都是领域的中心,任何领域都有各种类别的概念。知识消化所产生的模型能够反映出对知识的深层理解。在模型发生改变的同时,开发人员对实现进行重构,以便反映出模型的变化,这样,新知识就被合并到应用程序中了。

​ 当我们的建模不再局限于寻找实体和值对象时我们才能充分吸取知识,因为业务规则之间可能会存在不一致。领域专家在反复研究所有规则、解决规则之间的矛盾以及修改规则使其符合常识等一系列工作中,往往不会意识到他们的思考过长有多么复杂。软件是无法完成这一工作的。正是通过与软件专家紧密协作来消化知识的过程才使得规则得以澄清和充实,并消除规则之间的矛盾以及删除一些无用规则。

示例

一艘船在一次航程中要运载的货物
image

public int makeBooking(Cargo cargo,Voyage voyage){
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo,confirmation);
    return confirmation;
}

由于总会有人临时取消订单,因此航运业的一般做法是接受比其运载能力多一些的货物。这称为"超订"。有时使用一个简单地容量百分比来表示,例如预订110%的载货量。有时则采用一些有利于主要客户或特定种类的货物的复杂规则。
image

public int makeBooking(Cargo cargo,Voyage voyage){
    double maxBooking = voyage.capacity() * 1.1;
    if( (voyage.bookedCargoSize() * cargo.size()) > maxBooking ){
        return -1;
    }
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo,confirmation);
    return confirmation;
}

现在,一条重要的业务规则被隐藏在了上面这段方法代码的一个卫语句中。

1)如果写成上面的代码那样,不可能会有业务专家能通过阅读这段代码来检验规则,即使在开发人员的帮助下也无法完成

2)不懂此业务的技术人员很难将需求文本与代码联系起来

超订规则是一个政策。政策其实一种设计模式即策略模式。
image

public int makeBooking(Cargo cargo,Voyage voyage){
    if( !overbookingPolicy.isAllowed(cargo,voyage) ){
        return -1;
    }
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo,confirmation);
    return confirmation;
}

class OverbookingPolicy{
    public boolean isAllowed(Cargo cargo,Voyage voyage){
        return (cargo.size() + voyage.bookedCargoSize()) <= (voyage.capacity() * 1.1);
    }
}

现在所有人都可以看出超订是一个独特的政策,而且超订规则的实现是明确且独立的。

现在,我不建议将这样的精细设计应用到领域的每个细节中(参考15章,如何关注重点以及如何隔离其它问题以使这些问题最小化)。

这个例子的目的是说明领域模型和相应的设计可用来保护和共享知识。

1.5 深层模型

开发人员 货物的处理:由转包商或公司的操作人员完成,包括装货、卸货、运货。

航运专家 :各部分之间存在一系列的责任传递,法律责任和执行责任的传递有一个控制过程-从托运人传递到某个本地运输商,再从这家运输商传递到另一家运输商,最后到达收货人。

​ 认识发生变化:从"集装箱在各个地点之间的运输"转变为"运货责任在各个实体之间的传递"

标签:voyage,知识,cargo,模型,复杂性,第一章,之道,confirmation,规则
From: https://www.cnblogs.com/lhxBlogs/p/17304628.html

相关文章

  • 第一章 static、单例与继承
    目录面向对象一、static关键字1、static修饰成员变量2、static修饰成员变量内存中执行原理3、成员方法的执行原理4、工具类5、静态关键字注意事项6、代码块java静态代码块,构造方法,构造代码块的执行先后顺序1、执行顺序2、java中父类和子类代码执行顺序设计模式单例模式继承1、执行......
  • Metasploit高级技术【第一章】
    预计更新第一章Metasploit的使用和配置1.1安装和配置Metasploit1.2Metasploit的基础命令和选项1.3高级选项和配置第二章渗透测试的漏洞利用和攻击方法1.1渗透测试中常见的漏洞类型和利用方法1.2Metasploit的漏洞利用模块和选项1.3模块编写和自定义第三章Metasploit的提权......
  • VisionMobile:2013年移动开发者经济报告(三):第一章 移动双寡头(上)
    第一章:移动双寡头得益者和失落者之间越来越大的鸿沟尽管很多手机制造商感到悲观,且在2012年第3季度观察到手机出货量增速放缓,但自2009年来,行业收入年复合增长率稳定在23%。增长的背后是不断提升的智能手机销量,现在占总量40%,自2011年Q3来录得12.5个百分比的巨大增幅。这是因为低廉的A......
  • VisionMobile:2013年Q3移动开发者经济报告(二):第一章、2013年Q3设备领域的状况:拐点
    第一章:2013年Q3设备领域的状况:拐点2013年,应用生态系统在演进中出现拐点。2013年Q1,苹果的iOS和Google的Android前所未有地在智能手机总出货量中占有92%份额,宣告平台土地争夺战结束。于此同时,新的移动平台品种,黑莓10,FirefoxOS和Tizen在2013年推出手机,希望能与Apple/Google双寡头竞......
  • lvgl 经典编译错误解决之道:section `.bss' is not within region `dram0_0_seg'
    #NodeMCU##PlatformIO#或#ArduinoIDE#能规避lvgl+TFT_eSPI经典编译错误(如下所示)的点不多。Linking.pio\build\nodemcu\firmware.elfld.exe:address0x3fffd538of.pio\build\nodemcu\firmware.elfsection`.bss'isnotwithinregion`dram0_0_seg'collect2.exe......
  • 图神经网络 基础、前沿与应用 第一章 表征学习 阅读笔记
    导读表征学习的目标是从数据中提取足够但最少的信息。传统上,该目标可以通过先验知识以及基于数据和任务的领域专业知识来实现,这也被称为特征工程。特征工程是利用人类的现有知识的一种方式,旨在从数据中提取并获得用于机器学习任务的判别信息(比如从音频中通过傅立叶变换提取出mel......
  • c++ primer第一章
    11.2cinistream类型该对象被称为标准输入;coutostream对象被称为标准输出对象。cerr来输出警告和错误信息,clog来输出程序运行时的一般性消息。 写入endl的效果是结束当前行,并将与设备关联的缓冲区中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出......
  • Web开发的那点事--高效之道
    --------------------目标------------------核心目标:提高公司和个人开发效率,降低测试时间,减少Bug。--------------------指标----------------开发效率:提高开发效率20%以上。容易测试:根据源码容易判断是否正确,或者容易看到运行时效果。容易理解:具有很好的可读性和可实践性。容......
  • 第一章 1.2节 Kubeadm安装K8S高可用集群(二)
    1.1查看Token过期时间执行下面命令查看所有Token:kubectlgetsecret-nkube-system找到之前创建的new.yaml文件,进去查看使用的Token:[root@k8s-master01~]#catnew.yamlapiVersion:kubeadm.k8s.io/v1beta3bootstrapTokens:-groups:-system:bootstrappers:kube......
  • 《程序员修炼之道:从小工到专家》读后感(四)
    一个程序很有可能出现意想不到的异常,将异常用于异常的问题,通过异常处理,例程和他们的调用者被调用者更紧密的耦合在一起怎样配平资源大多数时候,资源使用遵循一种可预测的模式,分配,使用,解除其分配。对于一次不需要不只一个资源的例程,可以对资源分配的基本模式进行扩展的:以与资源分......