新書推薦:
《
空间与政治
》
售價:NT$
398.0
《
少年读三国(全套12册)
》
售價:NT$
2234.0
《
不完美之美:日本茶陶的审美变革(知名茶人李启彰老师器物美学经典代表作 饮一口茶,长一分体悟与智慧 制一件器,生一曲手与陶土的旋律 不借由任何美学架构来觉知美)
》
售價:NT$
398.0
《
现代化的迷途
》
售價:NT$
449.0
《
钛经济
》
售價:NT$
352.0
《
甲骨文丛书·无垠之海:世界大洋人类史(全2册)
》
售價:NT$
1469.0
《
中国救荒史
》
售價:NT$
500.0
《
三十六计绘本(共8册)走为上计+欲擒故纵+以逸待劳+无中生有+金蝉脱壳+浑水摸鱼+打草惊蛇+顺手牵羊 简装
》
售價:NT$
808.0
內容簡介:
使用领域驱动设计为复杂的业务问题更为
有效地构建解决方案
本书将领域驱动设计DDD思想体系的观点和理论提炼成了一本实践手册,让你可以简化复杂问题域的应用程序开发。本书专注于介绍分解复杂问题空间的原则和实践,以及构成可维护解空间的实现模式和最佳实践。你将学习如何通过使用战术模式构建有效领域模型以及如何通过应用DDD的战略模式维持其完整性。本书提供了完整的环环相扣的编码示例来揭示用于集成分解和分布式的解空间的技术,同时,最佳实践和模式的编码会为你提供如何架构可维护和可扩展的应用程序的建议。
主要内容
◆ 为专业开发人员全面介绍DDD思想体系
◆ 将领域驱动设计的理论简化成实践原则与实践做法
◆ 以实际运行的大量代码和概念示例介绍了其他书籍只进行理论描述的内容
◆ 涵盖了CQRS模式、消息传递、REST、事件溯源以及事件驱动架构的内容
◆ 适合于想要学习常见DDD实现模式的使用Java、Ruby及其他语言的开发人员阅读
◆ 以C#呈现的代码示例揭示了可在任何语言中应用的概念
關於作者:
Scott Millett是Iglu.com的IT总监,从1.0版本开始就使用.NET工作了。他在2010年和2011年获得了ASP.NET
MVP,并且还著有《ASP.NET设计模式》和《精通.NET企业项目开发:最新的模式、工具与方法》。
Nick Tune是用技术、协作和领域驱动设计为复杂业务问题提供解决方案的软件开发者。通过开发目标宏伟的产品以及与充满热情的人一起工作,他在寻求不断地自我提升。
目錄 :
目 录第Ⅰ部分 领域驱动设计的原则与实践第1章 什么是领域驱动设计31.1 为复杂问题域创建软件的挑战41.1.1 未使用通用语言创建的代码41.1.2 组织结构的缺乏51.1.3 泥球模式将扼杀开发51.1.4 缺乏对问题域的关注51.2 领域驱动设计模式如何管理复杂性61.2.1 DDD的战略模式61.2.2 DDD的战术模式81.2.3 问题空间与解空间91.3 领域驱动设计的实践与原则101.3.1 专注于核心领域101.3.2 通过协作进行学习101.3.3 通过探索和实验来创建模型101.3.4 通信111.3.5 理解模型的适用性111.3.6 让模型持续发展111.4 领域驱动设计的常见误区121.4.1 战术模式是DDD的关键121.4.2 DDD是一套框架121.4.3 DDD是一颗灵丹妙药121.5 要点13第2章 提炼问题域152.1 知识提炼与协作152.1.1 通过通用语言达成共识162.1.2 领域知识的重要性172.1.3 业务分析员的角色172.1.4 一个持续过程172.2 与领域专家一起获得领域见解182.2.1 领域专家与业务相关人员的对比182.2.2 对于业务的更深刻理解182.2.3 与你的领域专家互动192.3 有效提炼知识的模式192.3.1 专注在最有意思的对话上192.3.2 从用例开始192.3.3 提出有力的问题202.3.4 草图202.3.5 CRC卡212.3.6 延迟对模型中概念的命名212.3.7 行为驱动开发212.3.8 快速成型232.3.9 查看基于纸面的系统232.4 查看现有模型232.4.1 理解意图242.4.2 事件风暴242.4.3 影响地图252.4.4 理解业务模型262.4.5 刻意发现272.4.6 模型探讨漩涡272.5 要点28第3章 专注于核心领域313.1 为何要分解一个问题域313.2 如何捕获问题的实质323.2.1 超越需求323.2.2 为达成什么是核心内容的共识而捕获领域愿景323.3 如何专注于核心问题333.3.1 提炼问题域343.3.2 核心领域353.3.3 将你的核心领域当作一款产品而非一个项目363.3.4 通用域363.3.5 支撑域373.4 子域如何决定解决方案的形成373.5 并非一个系统的所有部分都会经过良好设计383.5.1 专注于清晰边界而非完美模型383.5.2 一开始核心领域不必总是需要是完美的393.5.3 构建用于替代而非重用的子域393.6 如果没有核心领域怎么办393.7 要点39第4章 模型驱动设计414.1 什么是领域模型414.1.1 领域与领域模型的对比424.1.2 分析模型434.1.3 代码模型434.1.4 代码模型是领域模型的主要表现444.2 模型驱动设计444.2.1 预先设计的挑战444.2.2 团队建模464.3 使用通用语言将分析和代码模型绑定在一起474.3.1 语言的生存周期将大于软件484.3.2 业务语言484.3.3 开发人员和业务之间的转译484.4 基于通用语言进行协作494.4.1 通过使用具体示例来定制出语言504.4.2 教导你的领域专家专注在问题上而不要跳到解决方案504.4.3 塑造语言的最佳实践514.5 如何创建有效的领域模型524.5.1 不要让实情妨碍一个好模型524.5.2 仅对相关内容建模534.5.3 领域模型都是暂时有用的534.5.4 要十分清楚专业术语544.5.5 限制你的抽象544.6 何时应用模型驱动设计554.6.1 如果它不值得花费精力,则不要尝试对其建模564.6.2 专注于核心领域564.7 要点56第5章 领域模型实现模式595.1 领域层595.2 领域模型实现模式605.2.1 领域模型615.2.2 事务脚本645.2.3 表模块675.2.4 活动记录675.2.5 贫血领域模型675.2.6 贫血领域模型和函数编程685.3 要点71第6章 使用有界上下文维护领域模型的完整性736.1 单个模型的挑战746.1.1 模型的复杂性可能会增加746.1.2 多个团队处理单个模型746.1.3 模型语言中的歧义756.1.4 领域概念的适用范围766.1.5 集成遗留代码或第三方代码786.1.6 领域模型并非企业模型786.2 使用有界上下文划分和破除大模型796.2.1 定义模型的边界816.2.2 子域和有界上下文之间的差异846.3 实现有界上下文856.4 要点88第7章 上下文映射917.1 一个现实情况的映射927.1.1 技术的现实927.1.2 组织的现实937.1.3 映射一个相关现实情况947.1.4 用X标记核心领域的位置947.2 认识有界上下文之间的关系947.2.1 防止损坏层957.2.2 共享内核967.2.3 开放宿主服务967.2.4 分道扬镳977.2.5 合作关系987.2.6 一种上游下游关系987.3 传递上下文映射997.4 上下文映射的战略重要性1007.4.1 保持完整性1007.4.2 解决计划的基础1017.4.3 理解所有权和职责1017.4.4 揭示业务工作流中的混乱区域1017.4.5 识别非技术障碍1017.4.6 鼓励良好的沟通1017.4.7 帮助加入的新员工1027.5 要点102第8章 应用程序架构1038.1 应用程序架构1038.1.1 分离应用程序的问题1038.1.2 从领域的复杂性中进行抽象1048.1.3 分层架构1048.1.4 依赖倒置1058.1.5 领域层1058.1.6 应用程序服务层1058.1.7 基础架构层1068.1.8 跨层通信1068.1.9 隔离测试1078.1.10 不要在有界上下文之间共享数据结构1088.1.11 应用程序架构与用于有界上下文的架构的对比1098.2 应用程序服务1108.2.1 应用程序逻辑与领域逻辑的对比1118.2.2 定义和公开能力1128.2.3 业务用例协作1128.2.4 应用程序服务表示的是用例,而不是创建、读取、更新和删除1128.2.5 作为实现详情的领域层1138.2.6 领域报告1138.2.7 读取模型与事务模型的对比1138.3 应用程序客户端1158.4 要点117第9章 团队开始应用领域驱动设计通常会遇到的问题1199.1 过分强调战术模式的重要性1209.1.1 将相同架构用于所有的有界上下文1209.1.2 力求战术模式尽善尽美1209.1.3 错误估计构造块对于DDD的价值1209.1.4 专注于代码而非DDD的原则1219.2 缺失了DDD的真实价值:协作、通信和上下文1219.2.1 由于低估上下文的重要性而产生大泥球1229.2.2 未能成功创建UL将造成歧义和误解1229.2.3 由于缺乏协作将只能设计专注于技术的解决方案1239.3 在不重要的部分花费太多时间1239.4 简单问题复杂化1239.4.1 将DDD原则应用到具有少量业务预期的琐碎领域1249.4.2 别将CRUD作为反模式1249.4.3 将领域模型模式用于每一个有界上下文1249.4.4 问一问自己:额外的复杂性是否值得1249.5 低估应用DDD的成本1259.5.1 尝试在没有积极专注的团队的情况下取得成功1259.5.2 项目背后没有领域专家时的协作尝试1259.5.3 在非迭代式开发方法中进行学习1259.5.4 将DDD应用到每一个问题1269.5.5 为不必要的纯粹性而牺牲实用主义1269.5.6 寻求验证会浪费精力1269.5.7 永远力求代码之美1279.5.8 DDD关乎的是提供价值1279.6 要点127第10章 应用DDD的原则、实践与模式12910.1 推广使用DDD12910.1.1 培训团队13010.1.2 与业务人员进行交流13010.2 应用DDD的原则13110.2.1 理解愿景13110.2.2 捕获所需的行为13110.2.3 理解环境的现实情况13210.2.4 对解决方案建模13310.3 探究和实验13910.3.1 质疑假设13910.3.2 建模是一项持续性活动13910.3.3 不存在错误的模型14010.3.4 灵活的代码有助于探索发现14010.4 让隐式内容变得显式14010.4.1 处理歧义14110.4.2 为事物命名14310.5 问题解决人先行,技术专家后行14310.6 如何才能知道我在正确地工作14310.6.1 好用就足够了14410.6.2 实践、实践、实践14410.7 要点144第Ⅱ部分 战略模式:在有界上下文之间通信第11章 有界上下文集成介绍14911.1 如何集成有界上下文15011.1.1 有界上下文是独立自主的15011.1.2 在代码层面集成有界上下文的挑战15111.1.3 使用物理边界来强制实现整洁的模型15411.1.4 集成遗留系统15511.2 集成分布式有界上下文15811.2.1 集成用于分布式有界上下文的策略15911.2.2 数据库集成15911.2.3 平面文件集成16011.2.4 RPC16111.2.5 消息传递16211.2.6 REST16211.3 DDD使用分布式系统的挑战16211.4 分布式事务将损害可扩展性和可靠性16511.4.1 有界上下文不必彼此保持一致16611.4.2 最终一致性16611.5 事件驱动响应式DDD16711.5.1 展示响应式解决方案的弹性和可扩展性16811.5.2 异步消息传递的挑战和取舍16911.5.3 RPC还有价值吗16911.6 SOA和响应式DDD17011.6.1 将你的有界上下文视作SOA服务17111.6.2 进一步处理微服务架构17411.7 要点175第12章 通过消息传递集成17712.1 消息传递基础17812.1.1 消息总线17812.1.2 可靠的消息传递18012.1.3 存储转发18012.1.4 命令和事件18012.1.5 最终一致性18112.2 使用NServiceBus构建一个电子商务应用程序18212.2.1 系统设计18312.2.2 从Web应用程序发送命令18712.2.3 处理命令和发布事件19612.2.4 使用消息传递网关让外部HTTP调用变得可靠20312.2.5 实践中的最终一致性21112.2.6 有界上下文会存储其本地所需的所有数据21212.2.7 把所有内容都放在UI中22012.3 维护消息传递应用程序22312.3.1 消息版本管理22312.3.2 监控和扩展22812.4 将有界上下文与公共传输集成23112.4.1 消息传递桥23212.4.2 公共传输23312.5 要点240第13章 通过使用RPC和REST的HTTP来集成24113.1 为何选用HTTP24213.1.1 没有平台耦合24313.1.2 每个人都理解HTTP24313.1.3 大量的成熟工具和库24313.1.4 内部测试你的API24313.2 RPC24413.2.1 在HTTP上实现RPC24413.2.2 选择一种RPC风格25913.3 REST26013.3.1 深入浅出地解释REST26013.3.2 用于有界上下文集成的REST26313.3.3 维护REST应用程序29713.3.4 将REST用于有界上下文集成的缺点29813.4 要点299第Ⅲ部分 战术模式:创建有效的领域模型第14章 构造块领域建模介绍30314.1 战术模式30414.2 对领域建模的模式30514.2.1 实体30514.2.2 值对象30814.2.3 领域服务31014.2.4 模块31214.3 生命周期模式31214.3.1 聚合31214.3.2 工厂31614.3.3 存储库31614.4 显露模式31714.4.1 领域事件31714.4.2 事件溯源31914.5 要点320第15章 值对象32315.1 何时使用值对象32415.1.1 表示描述性的、欠缺身份的概念32415.1.2 增强明确性32515.2 定义特征32715.2.1 欠缺身份32715.2.2 基于特性的相等性32715.2.3 富含行为33115.2.4 内聚33115.2.5 不可变33115.2.6 可组合性33315.2.7 自验证33515.2.8 可测试33815.3 常见的建模模式33915.3.1 静态工厂方法33915.3.2 微类型34115.3.3 规避集合34315.4 持久化34615.4.1 NoSQL34615.4.2 SQL34715.5 要点354第16章 实体35516.1 理解实体35616.1.1 具有身份和连贯性的领域概念35616.1.2 上下文依赖35616.2 实现实体35716.2.1 分配标识符35716.2.2 将行为推入到值对象和领域服务中36316.2.3 验证并强制不变性36516.2.4 专注于行为,而非数据36816.2.5 避免建模现实世界的谬误37116.2.6 分布式设计37116.3 常见的实体建模原则和模式37316.3.1 使用规范实现验证和不变条件37316.3.2 避免状态模式;使用显式建模37616.3.3 避免将接收器和设置器与备忘录模式结合使用37916.3.4 选用无隐藏意外影响的功能38016.4 要点382第17章 领域服务38317.1 理解领域服务38417.1.1 何时使用领域服务38417.1.2 领域服务解析38817.1.3 避免使用贫血领域模型38917.1.4 与应用程序服务对比39017.2 利用领域服务39017.2.1 服务层中39017.2.2 领域中39117.3 要点397第18章 领域事件39918.1 领域事件模式的实质40018.1.1 已经发生了的重要领域事件40018.1.2 响应事件40118.1.3 可选的异步性40118.1.4 内部事件与外部事件对比40218.2 事件处理操作40318.2.1 调用领域逻辑40318.2.2 调用应用程序逻辑40418.3 领域事件的实现模式40418.3.1 使用.Net框架的事件模型40418.3.2 使用内存中的总线40618.3.3 Udi Dahan的DomainEvents静态类40918.3.4 返回领域事件41218.3.5 使用IoC容器作为事件分发器41518.4 测试领域事件41618.4.1 单元测试41618.4.2 应用服务层测试41718.5 要点419第19章 聚合42119.1 管理复杂对象图形42219.1.1 选用单一遍历方向42219.1.2 合格的关联关系42419.1.3 选用ID而不是对象引用42519.2 聚合42819.2.1 围绕领域不变条件进行设计42919.2.2 高层次的领域抽象42919.2.3 一致性边界42919.2.4 选用较小的聚合43419.3 定义聚合边界43519.3.1 eBidder:在线拍卖案例研究43519.3.2 与不变条件保持一致43719.3.3 与事务和一致性保持一致43919.3.4 忽略用户界面影响44019.3.5 避免无用的集合与容器44119.3.6 不要专注于HAS-A关系44119.3.7 重构聚合44119.3.8 满足业务用例非现实环境44119.4 实现聚合44219.4.1 选择一个聚合根44219.4.2 引用其他聚合44619.4.3 实现持久化45019.4.4 实现事务一致性45419.4.5 实现最终一致性45519.4.6 实现并发性45819.5 要点459第20章 工厂46120.1 工厂的作用46120.1.1 从构造中分离出应用46220.1.2 封装内部事物46220.1.3 隐藏创建类型的决策46420.1.4 聚合上的工厂方法46620.1.5 用于重构的工厂46720.1.6 务实地使用工厂46920.2 要点469第21章 存储库47121.1 存储库47121.2 一种被误解的模式47321.2.1 存储库是一种反模式吗47321.2.2 领域模型和持久化模型之间的区别47421.2.3 通用存储库47521.3 聚合持久化策略47721.3.1 使用能在不损坏领域模型的情况下将其映射到数据模型的持久化框架47821.3.2 使用不能在不影响领域模型的情况下直接映射它的持久化框架47821.3.3 公共接收器和设置器47921.3.4 使用备忘录模式48021.3.5 事件流48221.3.6 求真务实48321.4 存储库是一个明确的约定48321.5 事务管理和工作单元48421.6 保存或不保存48821.6.1 持久化追踪领域对象变更的框架48921.6.2 必须将变更显式保存到聚合49021.7 充当防止损坏层的存储库49121.8 存储库的其他职责49121.8.1 实体ID生成49221.8.2 集合汇总49421.8.3 并发性49421.8.4 审计追踪49821.9 存储库反模式49821.9.1 反模式:不要支持即席查询49821.9.2 反模式:延迟加载是一种设计异味49921.9.3 反模式:不要为了报告需要而使用存储库49921.10 存储库实现49921.10.1 持久化框架可以在不损坏领域模型的情况下将其映射到数据模型50021.10.2 持久化框架不能在不损坏领域模型的情况下直接映射领域模型55021.11 要点586第22章 事件溯源58722.1 将状态存储为快照的限制58822.2 通过将状态存储为事件流来获得竞争优势58922.2.1 时态查询58922.2.2 投影59022.2.3 快照59122.3 源自事件的聚合59122.3.1 构造59222.3.2 持久化与再融合59622.4 构建一个事件存储60322.4.1 设计一种存储格式60422.4.2 创建事件流60522.4.3 附加到事件流60622.4.4 查询事件流60622.4.5 添加快照支持60722.4.6 管理并发性60922.4.7 一个基于SQL Server的事件存储61322.4.8 构建你自己的事件存储是一个好主意吗61922.5 使用专门构建的Event Store61922.5.1 安装Greg Young的Event Store61922.5.2 使用C#客户端库62022.5.3 运行时态查询62422.5.4 创建投影62722.6 使用事件溯源的CQRS62922.6.1 使用投影创建视图缓存63022.6.2 CQRS和事件溯源协作63022.7 简要复述事件溯源的好处63122.7.1 竞争性业务优势63122.7.2 专注于表述性行为的聚合63122.7.3 简化的持久化63222.7.4 更好的调试63222.8 衡量事件溯源的代价63222.8.1 版本控制63222.8.2 要学习的新概念和要磨练的技能63222.8.3 需要学习和掌握的新技术63322.8.4 大量的数据存储需求63322.9 额外的学习资源63322.10 要点633第Ⅳ部分 有效应用程序的设计模式第23章 应用程序用户界面的架构设计63723.1 设计考量63823.1.1 占有式UI与构成式UI的对比63823.1.2 HTML API与数据API的对比64023.1.3 客户端与服务器端聚合协作对比64123.2 示例1:用于非分布式有界上下文的一个基于HTML API的、服务器端的UI64323.3 示例2:用于分布式有界上下文的一个基于数据API的客户端UI65023.4 要点658第24章 CQRS:一种有界上下文的架构65924.1 为两个上下文维护单个模型的挑战66024.2 用于复杂有界上下文的一种更好的架构66124.3 命令端:业务任务66224.3.1 显式建模意图66224.3.2 不受展现干扰所影响的模型66324.3.3 处理业务请求66524.4 查询端:领域报告66524.4.1 直接映射到数据模型的报告66624.4.2 从领域事件中构建的具体化视图66724.5 对CQRS的误解66824.5.1 CQRS很难66824.5.2 CQRS是最终一致的66824.5.3 模型需要源自事件66924.5.4 命令应该是异步的66924.5.5 CQRS仅适用于消息传递系统66924.5.6 需要将CQRS用于领域事件66924.6 可以扩展应用程序的模式66924.6.1 扩展读取端:一个最终一致的读取模型67024.6.2 扩展写入端:使用异步命令67224.6.3 对一切进行扩展67324.7 要点674第25章 命令:用于处理业务用例的应用程序服务模式67725.1 区分应用程序逻辑和领域逻辑67825.1.1 应用程序逻辑67825.1.2 来自应用程序服务角度的领域逻辑69025.2 应用程序服务模式69025.2.1 命令处理程序69025.2.2 发布订阅69425.2.3 请求回复模式69625.2.4 asyncawait69825.3 测试应用程序服务69925.3.1 使用领域专业术语69925.3.2 测试尽可能多的功能70025.4 要点702第26章 查询:领域报告70326.1 有界上下文中的领域报告70426.1.1 从领域对象中派生报告70426.1.2 直接访问数据存储71026.1.3 从事件流构建投影71626.2 跨有界上下文的领域报告72326.2.1 复合UI72326.2.2 单独的报告上下文72426.3 要点726