DDD学习笔记七

将设计模式应用于模型设计

  • 策略模式
    策略模式着重解决以下类型的需求:
    ❑ 算法与多种变体需要不时替换。
    ❑ 未来有新增的算法。
    ❑ 一个类中某个行为有较多的分支,且需要时常维护。
    ❑ 希望隐藏算法的逻辑或数据。

  • 策略模式的建模步骤如下:
    1)找到使用多种算法处理任务的领域模型,就是那种有很多逻辑分支,且不断变化,让人头疼的地方。比如订单模型Order和数据处理模型DataProcessor。
    2)运用“面对接口编程思想”,在领域模型内声明接口成员,用接口的处理替代所有的处理分支,接口方法的命名要符合通用语言。
    3)将条件分支的处理逻辑或对象封装成不同的策略类,实现上面抽象出的接口。
    4)绑定具体策略类到接口的逻辑,组合规则可以写在配置文件中由工厂完成,也可以由用户自行决定。

  • 组合模式
    组合模式的建模步骤如下:
    1)找到组合策略的应用场合:由于需要功能排列组合而产生类爆炸的地方;在用户看来是一个简单个体,但其实背后是多个个体组合的情况。
    2)根据需求提炼出这些组件的共同接口。如复杂的优惠策略中的结算费用、多级仓库中的统计库存和智能制造中的计算成本。
    3)设计组合部件,它本身要实现共同接口,另外还要声明接口的集合用来扩展。
    4)设计叶子节点,它要实现共同接口,但无须再声明接口集合成员变量。
    5)按需组合部件与叶子节点(可由工厂执行)。
    6)用户通过接口使用组合好的模型。

  • 门面模式

  • 门面模式通常出现在领域层之外的应用服务层,它的建模步骤如下:
    1)从通用语言中找到值得封装的具有业务含义的操作,其特征为:
    ❑ 业务虽然简单,但涉及多个模型的复杂交互。
    ❑ 后面隐藏着其他子系统,需要数据转换等复杂操作。
    2)用单独的类和富含业务含义的接口封装这些模型和子系统。
    3)门面可能位于领域层外的应用层中,让用户使用门面模式包装的业务接口,而不是直接使用领域模型。

  • 模板模式

  • 建模步骤如下:
    1)在领域中发掘隐含的工作流逻辑,即略有不同但是概念上相似的步骤。当然,如果工作流是显式的,那么可以直接拿来使用。
    2)创建流程抽象基类。将工作流的流转逻辑体现在基类的对应方法中(如VehicleProduct-Line中的StartWork()方法)。
    3)将后续会发生变化的处理逻辑声明为抽象方法。
    4)创建继承自基类的具体工作流对象,并实现自己具体的处理逻辑。
    5)配合工厂返回具体的工作流对象供用户使用。

  • 单例模式

  • 工具类:提供系统公用方法的工具类也会私有化构造函数,并且所有方法都为静态方法。它与单例模式的区别如下:
    ❑ 工具类不保存状态,仅提供无状态函数,而单例模式可以有状态,比如存一些统计数据等全局变量。
    ❑ 工具类不具有多态性,而单例模式可以被继承。
    ❑ 单例模式是一个模型,而工具类只是方法的集合。

  • 单例模式的建模步骤如下:
    1)找到领域中具备以下共性的需求:
    ❑ 有限资源的统一协调。
    ❑ 计算存储全局性变量。
    ❑ 解决相同对象过多的性能问题。
    2)将处理上述任务的模型单例化,需要完成以下几步:
    ❑ 私有构造函数防止在外部实例化。
    ❑ 保存唯一实例的静态的私有变量。
    ❑ 初始化并获得唯一实例的静态方法。
    3)单例化改造后,添加解决冲突的算法、资源分配方法,以及全局变量等业务方法和数据。
    4)在之前实例化模型的代码中,如果使用了构造函数或工厂,都替换为单例模式的静态方法来获得实例。

  • 观察者模式

  • 建模步骤如下:
    1)找到关心的领域事件。
    2)通过事件找到对应的触发操作,进而定位所在模型。
    3)所在模型即为观察目标,观察目标实现Object接口的3个操作(通知观察者、添加和删除观察者),同时定义一个Observer接口的集合成员。
    4)找到事件的消费者,它可能是为了解耦从观察目标拆解出来的新对象,也可能是领域中的其他模型,即观察者。
    5)观察者实现Observer接口,实现具体的事件响应逻辑。
    注意,模型的定义要符合通用语言,确保领域专家理解你的模型设计。

  • 适配器模式

  • 建模步骤如下:
    1)评估已有对象的能力能否胜任,包括评估已有对象的可见性和访问权限等因素。比如,加法运算的对象适配后可以做乘法,但其他运算可能根本就无法适配。
    2)确定任务接口。
    3)确定转换的算法,包括参数的处理等。
    4)实现适配器类。
    5)利用客户端或者通过工厂方法输出适配器类,将耦合了被包装对象的地方都替换为适配器类。

  • 代理者模式

  • 建模步骤
    代理者模式的建模步骤如下:
    1)找到符合以下需求特征的对象,为其创建代理:
    ❑ 所有远程对象。为远程对象都创建本地代理是一个屡试不爽的优秀实践。
    ❑ 访问需要控制的对象。不论是权限还是前面提到的配额等领域逻辑的控制。
    ❑ 访问比较复杂的对象。如需要通过复杂计算生成的对象。
    2)创建代理类,并按照代理对象的类别将以下内容封装到代理对象内:
    ❑ 为远程对象提供本地替身对象,在远程对象无法及时给予反馈时,使用本地对象。要综合平衡用户体验和实时性的要求。
    ❑ 访问需要控制的对象,将控制逻辑封装在代理类中。
    ❑ 访问比较复杂的对象,将复杂访问逻辑封装在代理类中。
    3)要保证代理类的接口与原始对象一致,调用者感觉不到两者的差别。
    4)将代码中所有对真实对象的访问都替换为对代理的访问。

  • 访问者模式

  • 建模步骤
    访问者模式的建模步骤如下:
    1)找到需要扩展行为的模型,让其实现被访问者接口(Accept方法)。
    2)按关注点对扩展行为进行分类,构成不同的访问者,它们都实现访问者接口(Visit方法)。
    3)在访问者类中,通过对原模型的访问实现新的业务需求。
    4)在工厂中或客户端,按需让模型接收不同的访问者即可。访问者自动完成自身的扩展逻辑,不需要额外操作。

  • 状态模式

  • 建模步骤
    状态模式的建模步骤如下:

1)找到具有多种状态的领域模型,它可能来自通用语言,也可能是那些有很多逻辑分支的地方。

2)将不同状态下的不同处理逻辑提取到状态接口或抽象类中。

3)将模型中不同的处理逻辑部分转换为由状态接口或抽象类处理。

4)按逻辑分支数量创建具体状态类,并实现状态接口或抽象类。

5)确定状态转换条件。

6)将转换条件实现在含有状态的模型中(第一个代码例子)或者具体状态类中(第二个代码例子),又或者外部的配置文件中。

可以看到,前4步与策略模式相似,最后2步是状态模式独有的,也是其能实现“自动”的原理所在。

  • 职责链模式
  • 建模步骤
    职责链模式的建模步骤如下:
    1)确定请求中需要不同处理的逻辑。
    2)为该请求设计接口。不同处理的逻辑体现为实现该接口的具体处理类。注意,每一个处理类处理的数据可能有交叉,但逻辑上不应重复或矛盾。
    3)工厂根据需求组装不同的职责链。这个任务最好不要交给客户来做。
    4)用户直接使用工厂返回的职责链的简单对象即可,无须关心职责链有多长、需要多少额外的处理。这些都是由工厂按需灵活定制的。
  • 桥接模式
  • 建模步骤
    桥接模式的建模步骤如下:

1)识别变化的维度和桥接它们的场景。

2)一个维度设计一个接口,它代表此维度对象要完成的任务。

3)将该维度所有变量继承实现该接口。

4)设计“桥”模型,它是多个维度一起工作的场景。比如“用户画像”。

5)工厂组装好桥模型提供给用户使用,如“用户画像工厂”。

相关推荐

  1. DDD学习笔记

    2024-07-17 11:18:04       25 阅读
  2. DDD学习笔记-实体定义

    2024-07-17 11:18:04       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 11:18:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 11:18:04       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 11:18:04       58 阅读
  4. Python语言-面向对象

    2024-07-17 11:18:04       69 阅读

热门阅读

  1. 怎么把VMamba作为Feature Extractor集成到现有模型

    2024-07-17 11:18:04       25 阅读
  2. AI时代的技术应用与创新:探索未来

    2024-07-17 11:18:04       18 阅读
  3. 新版本 Android Studio 没有BuildConfig ?

    2024-07-17 11:18:04       30 阅读
  4. 前缀匹配工具之IP-Prefix

    2024-07-17 11:18:04       28 阅读
  5. 高精度减法(C++)

    2024-07-17 11:18:04       24 阅读
  6. 谈人工智能在电子档案系统的应用

    2024-07-17 11:18:04       18 阅读
  7. Android 音频通道切换HDMI,蓝牙,喇叭

    2024-07-17 11:18:04       26 阅读
  8. C#拆分单页PDF

    2024-07-17 11:18:04       25 阅读
  9. TCP/IP、UDP、HTTP 协议介绍比较和总结

    2024-07-17 11:18:04       22 阅读