Python设计模式
Python设计模式
Harry J.W. Percival, Bob Gregory
柴一平, 徐海洋 译
出版时间:2025年03月
页数:304
“这是社区一直在等待的书:Python中现代应用程序架构的转变是什么样子的!Harry和Bob展示了在一个优雅、动态的语言中依赖倒置原则的美感。”
——Brandon Rhodes
Python-patterns.guide作者
“到目前为止,几乎没有任何关于如何在Python中编写可维护的大规模系统的Python原生材料。这本书展示了Python完全胜任严肃的软件开发。”
——Hynek Schlawack
Pythonista、博客作者和演讲者
随着Python的受欢迎程度不断增加,项目也变得越来越大且复杂。许多Python开发人员对高层次的软件设计模式感兴趣,例如六边形/整洁架构、事件驱动架构和领域驱动设计(DDD)推荐的战略模式。但是,将这些模式应用于Python项目中并不总是那么简单。
在这本实用指南中,来自MADE.com的Harry Percival和Bob Gregory介绍了经过验证的架构设计模式,帮助Python开发人员管理应用程序复杂性,并从他们的测试套件中获得最大价值。
每种模式都用优雅且惯用的Python实例进行了说明,避免了一些Java和C#语法的冗长。模式包括:
● 依赖倒置及其与端口和适配器(六边形/整洁架构)的联系。
● 领域驱动设计中的实体、值对象和聚合之间的区分。
● 持久存储的仓储和工作单元模式。
● 事件、命令和消息总线。
● 命令查询责任分离(CQRS)。
● 事件驱动架构和反应式微服务。
  1. 前言
  2. 第0章 概述
  3. 第一部分 构建支持领域模型的架构
  4. 第1章 领域建模
  5. 1.1 什么是领域模型
  6. 1.2 探索领域语言
  7. 1.3 单元测试领域模型
  8. 1.3.1 数据类非常适合值对象
  9. 1.3.2 值对象和实体
  10. 1.4 并非一切都必须是对象:领域服务函数
  11. 1.4.1 基于Python的魔法方法利用Python使用我们的模型
  12. 1.4.2 异常也可以表达领域概念
  13. 第2章 存储库模式
  14. 2.1 持久化我们的领域模型
  15. 2.2 一些伪代码:我们需要什么
  16. 2.3 将DIP应用于数据访问
  17. 2.4 回顾:我们的模型
  18. 2.4.1 一般的ORM方式:模型依赖于ORM
  19. 2.4.2 反转依赖关系:ORM依赖于模型
  20. 2.5 介绍存储库模式
  21. 2.5.1 抽象的存储库
  22. 2.5.2 什么是权衡
  23. 2.6 构建用于测试的假存储库现在变得微不足道
  24. 2.7 在Python中,什么是端口和适配器
  25. 2.8 总结
  26. 第3章 一个简要的插曲:关于耦合和抽象
  27. 3.1 抽象状态有助于增加可测试性
  28. 3.2 选择正确的抽象
  29. 3.3 实现我们所选择的抽象
  30. 3.3.1 使用伪造和依赖注入进行边缘到边缘测试
  31. 3.3.2 为什么不直接修补呢
  32. 3.4 总结
  33. 第4章 我们的第一个用例:Flask API和服务层
  34. 4.1 将我们的应用程序连接到真实世界
  35. 4.2 第一个端到端测试
  36. 4.3 直接实现
  37. 4.4 需要数据库检查的错误条件
  38. 4.5 引入服务层,并使用FakeRepository对其进行单元测试
  39. 4.6 为什么一切都被称为服务
  40. 4.7 将事物放入文件夹以查看它们的归属
  41. 4.8 总结
  42. 第5章 高速挡和低速挡的TDD
  43. 5.1 我们的测试金字塔看起来怎么样
  44. 5.2 应该将领域层测试转移到服务层吗
  45. 5.3 在决定编写哪种测试时
  46. 5.4 高速挡和低速挡
  47. 5.5 将服务层测试与领域完全解耦
  48. 5.5.1 改进:在Fixture函数中保留所有领域依存关系
  49. 5.5.2 添加缺失的服务
  50. 5.6 将改进贯穿到E2E测试中
  51. 5.7 总结
  52. 第6章 工作单元模式
  53. 6.1 工作单元与存储库协作
  54. 6.2 通过集成测试驱动UoW
  55. 6.3 工作单元及其上下文管理器
  56. 6.3.1 真正的工作单元使用SQLAlchemy会话
  57. 6.3.2 用于测试的假工作单元
  58. 6.4 在服务层中使用工作单元(UoW)
  59. 6.5 提交/回滚行为的显式测试
  60. 6.6 显式提交与隐式提交
  61. 6.7 示例:使用工作单元将多个操作分组到一个原子单元中
  62. 6.7.1 示例1:重新分配
  63. 6.7.2 示例2:更改批次数量
  64. 6.8 整理集成测试
  65. 6.9 总结
  66. 第7章 聚合和一致性边界
  67. 7.1 为什么不直接使用电子表格运行所有内容
  68. 7.2 不变量、约束和一致性
  69. 7.3 什么是聚合
  70. 7.4 选择聚合
  71. 7.5 一个聚合=一个存储库
  72. 7.6 关于性能
  73. 7.7 乐观并发控制与版本号
  74. 7.8 测试我们的数据完整性规则
  75. 7.8.1 使用数据库事务隔离级别强制执行并发规则
  76. 7.8.2 悲观并发控制示例:SELECT FOR UPDATE
  77. 7.9 总结
  78. 7.10 第一部分概述
  79. 第二部分 事件驱动架构
  80. 第8章 事件和消息总线
  81. 8.1 避免造成混乱
  82. 8.1.1 首先,让我们避免弄乱我们的Web控制器
  83. 8.1.2 不要弄乱我们的模型
  84. 8.1.3 或者尝试一下使用服务层
  85. 8.2 单一职责原则
  86. 8.3 全部都使用消息总线
  87. 8.3.1 模型记录事件
  88. 8.3.2 事件是简单的数据类
  89. 8.3.3 模型触发事件
  90. 8.3.4 消息总线将事件映射到处理程序
  91. 8.4 选项1:服务层从模型中获取事件并将其添加到消息总线
  92. 8.5 选项2:服务层自己触发事件
  93. 8.6 选项3:工作单元将事件发布到消息总线
  94. 8.7 总结
  95. 第9章 深入探讨消息总线
  96. 9.1 新的需求引导我们走向新的架构
  97. 9.2 将服务层方法重构为消息处理程序
  98. 9.2.1 消息总线现在从工作单元(UoW)收集事件
  99. 9.2.2 我们所有的测试也是根据事件编写的
  100. 9.2.3 丑陋的处理方法:消息总线必须返回结果
  101. 9.2.4 修改API以处理事件
  102. 9.3 实现我们的新需求
  103. 9.4 测试驱动新的处理程序
  104. 9.4.1 实现
  105. 9.4.2 领域模型的新方法
  106. 9.5 选读:使用模拟消息总线对事件处理程序进行单元测试
  107. 9.6 总结
  108. 9.6.1 我们实现了什么
  109. 9.6.2 我们为什么这么实现
  110. 第10章 命令与命令处理程序
  111. 10.1 命令与事件
  112. 10.2 异常处理的差异
  113. 10.3 讨论:事件,命令,以及错误处理
  114. 10.4 同步错误恢复
  115. 10.5 总结
  116. 第11章 事件驱动架构:使用事件集成微服务
  117. 11.1 分布式泥球和名词思维
  118. 11.2 分布式系统中的错误处理
  119. 11.3 替代方案:使用异步消息进行时间解耦
  120. 11.4 使用Redis发布/订阅通道进行集成
  121. 11.5 使用端到端测试进行全面测试驱动
  122. 11.5.1 Redis是另一个围绕消息总线的轻量适配器
  123. 11.5.2 新发出的事件
  124. 11.6 内部事件与外部事件
  125. 11.7 总结
  126. 第12章 命令–查询责任分离
  127. 12.1 领域模型用于写
  128. 12.2 大部分用户不会买你的家具
  129. 12.3 Post/Redirect/Get和CQS
  130. 12.4 抓紧你的午餐,朋友们
  131. 12.5 测试CQRS视图
  132. 12.6 “显而易见”的替代方案1:使用现有存储库
  133. 12.7 领域模型未针对读取操作进行优化
  134. 12.8 “显而易见”的替代方案2:使用ORM
  135. 12.9 SELECT N+1和其他性能考量
  136. 12.10 是时候完全随波逐流了
  137. 12.11 更改读取模型的实现很容易
  138. 12.12 总结
  139. 第13章 依赖注入和Bootstrapping
  140. 13.1 隐式依赖与显式依赖
  141. 13.2 显式依赖不是很奇怪和Java式吗
  142. 13.3 准备处理程序:带有闭包和部分函数的手动DI
  143. 13.4 使用类的备选方案
  144. 13.5 Bootstrap脚本
  145. 13.6 消息总线在运行时提供处理程序
  146. 13.7 在程序入口使用Bootstrap
  147. 13.8 在测试中初始化DI
  148. 13.9 “正确”构建适配器:一个可用示例
  149. 13.9.1 定义抽象和具体实现
  150. 13.9.2 为你的测试完成一个假的版本
  151. 13.9.3 找出如何集成测试真实事物的方法
  152. 13.10 总结
  153. 后记
  154. 附录A 图表和表格汇总
  155. 附录B 项目结构模板
  156. 附录C 交换基础设施:全部使用CSV
  157. 附录D 存储库和工作单元Django模式
  158. 附录E 验证
书名:Python设计模式
译者:柴一平, 徐海洋 译
国内出版社:中国电力出版社
出版时间:2025年03月
页数:304
书号:978-7-5198-9182-4
原版书书名:Architecture Patterns with Python
原版书出版商:O'Reilly Media
Harry J.W. Percival
 
Harry Percival做了几年的管理顾问,他对自己当时的工作并不是很感兴趣。后来他终于发现了自己真正的极客本性,幸运地结识了一群XP狂热者,创立了Resolver One电子表格,可惜的是该产品已经不存在了。Harry曾在Pythonywhere LLP工作,他一直致力于在演讲、研讨会和会议上向全世界传播TDD。现在,Harry在Made.com工作。
 
 
Bob Gregory
 
Bob Gregory是Made.com的一位在英国工作的软件架构师。十多年来,他一直在使用领域驱动设计构建事件驱动系统。
 
 
本书封面上的动物是缅甸巨蟒(学名:Python bivitattus)。如你所料,缅甸蟒蛇原产于东南亚。如今,它生活在南亚、缅甸、中国和印度尼西亚的丛林和沼泽中,在佛罗里达州的大沼泽地也被发现过。
缅甸蟒蛇是世界上最大的蛇种之一。这些夜间活动的食肉性蟒蛇可以长到23英尺,体重约200磅。普遍雌性比雄性大。缅甸蟒蛇一窝最多能产一百个蛋。在野外,缅甸蟒蛇的平均寿命为20~25年。
缅甸巨蟒身上的斑纹从头顶上的一个箭头状浅棕色斑点开始,然后沿着身体呈矩形,与褐色鳞片形成鲜明对比。缅甸蟒蛇在长到完全体型之前(需要2~3年时间),一般生活在树上捕食小型哺乳动物和鸟类。它们还可以在不需要呼吸的情况下长时间游泳,最长可达30分钟。
由于栖息地遭到破坏,缅甸蟒蛇处于弱势保护状态。O’Reilly出版物的封面上的许多动物都濒临灭绝;所有这些保护动物对我们的世界都具有重大意义。
购买选项
定价:98.00元
书号:978-7-5198-9182-4
出版社:中国电力出版社