DDD学习笔记七

news/2024/9/13 16:44:28/ 标签: 学习, 笔记, 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)工厂组装好桥模型提供给用户使用,如“用户画像工厂”。


http://www.ppmy.cn/news/1475835.html

相关文章

C 语言 do while 语句

do while循环是 C 语言中的一种循环结构,它至少执行一次循环体内的代码,然后再根据条件判断是否继续执行。这与 while 循环不同,while循环在开始时就会检查条件,如果条件不成立,则循环体内的代码一次也不会执行。 下面…

聊聊自动驾驶中的LiDAR和Radar

LiDAR(光检测与测距)和Radar(无线电波检测与测距)是两种不同的遥感技术,它们在原理和应用上存在一些区别: 原理上的区别: LiDAR: 利用激光脉冲进行测距。通过测量激光从发射到反射…

在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)

#在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一) 前言 关键字: 机器学习 人工智能 AI chatGPT 学习 实现 使用 搭建 深度 python 事件 远程 docker mysql安全 技术 部署 技术 自动化 代码 文章目录 - -…

uniapp 实现上传文件的功能

上传单个文件 <script setup>const handleUploadClick () > {console.log("上传文件")uni.chooseImage({success: (chooseImageRes) > {const tempFilePaths chooseImageRes.tempFilePaths;console.log("用户选择的图片&#xff1a;", temp…

数字化赋能,加油小程序让出行更便捷高效

在快节奏的现代生活中&#xff0c;每一次加油不仅是车辆续航的必要步骤&#xff0c;也成为了人们日常生活中不可或缺的一环。随着科技的飞速发展&#xff0c;传统加油模式正逐步向智能化、便捷化转型&#xff0c;其中&#xff0c;加油小程序作为这股浪潮中的佼佼者&#xff0c;…

FastAPI 学习之路(四十四)WebSockets

我们之前的分析都是基于http的请求&#xff0c;那么如果是websockets可以支持吗&#xff0c;答案是可以的&#xff0c;我们来看下是如何实现的。 from fastapi import WebSocket, FastAPI from fastapi.responses import HTMLResponseapp FastAPI()html """&…

WEB前端03-CSS3基础

CSS3基础 1.CSS基本概念 CSS是Cascading Style Sheets&#xff08;层叠样式表&#xff09;的缩写&#xff0c;它是一种对Web文档添加样式的简单机制&#xff0c;是一种表现HTML或XML等文件外观样式的计算机语言&#xff0c;是一种网页排版和布局设计的技术。 CSS的特点 纯C…

[Day 29] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈的供應鏈管理應用 區塊鏈技術自2008年比特幣誕生以來&#xff0c;逐漸被廣泛應用於各種領域&#xff0c;其中供應鏈管理是其最有潛力的應用之一。區塊鏈的去中心化、不可篡改和透明性特點&#xff0c;使其在解決傳統供應鏈中的信息不對稱、數據篡改和信任問題方面具有顯…

C调用C++接口

C文件 #include <ctype.h> #include <sys/time.h> #include <sys/stat.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <unistd.h> #include <s…

Macbook pro插移动硬盘没反应,Macbook pro移动硬盘读不了怎么办 macbook插移动硬盘后无法使用

为了弥补Macbook pro硬盘容量的缺失&#xff0c;我们有时候会使用到外接硬盘或移动硬盘。一般来说&#xff0c;这些硬盘都是即插即用的&#xff0c;可能部分要安装插件。不过&#xff0c;在一些特殊情况下&#xff0c;也会遇到插硬盘没反应等问题。本文会给大家解答Macbook pro…

RustChinaConf 2024(Rust中国大会2024)号集令

自六月官宣以来&#xff0c;Rust中国大会2024受到了众多厂商的青睐。目前已经确定的重量级赞助商有&#xff1a; ICP&#xff08;互联网计算机&#xff09;非凸科技在线途游蚂蚁金服JetBrain GEAR Foundation INFINI Labs Greptime 等 其中钻石赞助仅剩少量名额 请有意向赞助大…

勒索防御第一关 亚信安全AE防毒墙全面升级 勒索检出率提升150%

亚信安全信舷AE高性能防毒墙完成能力升级&#xff0c;全面完善勒索边界“全生命周期”防御体系&#xff0c;筑造边界勒索防御第一关&#xff01; 勒索之殇&#xff0c;银狐当先 当前勒索病毒卷携着AI技术&#xff0c;融合“数字化”的运营模式&#xff0c;形成了肆虐全球的网…

Spring Boot 3.3 【二】Spring Boot自动配置机制深度解析

简单动作&#xff0c;深刻联结。在这技术海洋&#xff0c;我备好舟&#xff0c;等你扬帆。启航吧&#xff01; &#x1f31f;点击【关注】&#xff0c;解锁定期的技术惊喜&#xff0c;让灵感与知识的源泉不断涌动。 &#x1f44d;一个【点赞】&#xff0c;如同心照不宣的默契&a…

【数智化案例展】吉林省消防救援总队——基于大语言模型的119智慧助手

‍ 嘉诚信息案例 本项目案例由嘉诚信息投递并参与数据猿与上海大数据联盟联合推出的《2024中国数智化转型升级创新服务企业》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着信息时代的迅猛发展&#xff0c;消防人员正面临前所未有的知识爆炸挑战。为了高…

【数据结构】:时间和空间复杂度

目录 如何衡量一个代码的好坏 时间复杂度 概念 计算方法 实例计算 【实例1】 【实例2】 【实例3】 【实例4】&#xff1a;冒泡排序的时间复杂度 【实例5】&#xff1a;二分查找的时间复杂度 【实例6】&#xff1a;阶乘递归的时间复杂度 【实例7】&#xff1a;斐波那契…

防火墙双机热备和带宽管理

拓扑图 实验要求 1.对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW5&#xff0c;生产区和办公区的流量走FW4 2.办公区上网用户限制流量不超过100M&#xff0c;其中销售部人员在其基础上…

类和对象(2

*续上文中的运算符重载 4 重载运算符时,有前置和后置的,运算符重载的函数名都是operator, 无法很好区分 所以c规定,后置重载时,增加一个int形参 与前置做区分 5 重载<<和>>时需要重载为全局函数, 因为重载为成员函数时, this指针默认抢占了第一个形参位, 第一个形参…

python爬虫js逆向入门

js基础 在 JavaScript 逆向工程中&#xff0c;常常会遇到一些复杂的代码结构&#xff0c;这些代码可能包含各种函数定义、对象操作、异步调用等。 ### 1. 函数声明和调用function generateSignature(uri, params) { // 将 uri 和参数对象转换为字符串 var data uri ? Objec…

微信小程序,订阅消息

微信小程序&#xff0c;订阅消息&#xff0c;完整流程 1.选择需要的模版 2.前端调用订阅消息 注&#xff1a;tmplIds&#xff1a;模板ID模版id,这里也可以选多个 wx.requestSubscribeMessage({tmplIds: [7UezzOrfJg_NIYdE1p*******],success (res) { console.log(res);wx.g…

13--memcache与redis

前言&#xff1a;数据库读取速度较慢一直是无法解决的问题&#xff0c;大型网站应对的方式主要是使用缓存服务器来缓解这种情况&#xff0c;减少数据库访问次数&#xff0c;以提高动态Web等应用的速度、提高可扩展性。 1、简介 Memcached/redis是高性能的分布式内存缓存服务器…