烂翻译系列之学习领域驱动设计——序言
Preface
序言
I vividly remember the day I started my first real software engineering job. I was both ecstatic and terrified. After hacking software for local businesses during my high school years, I was eager to become a “real programmer” and write some code for one of the country’s largest outsourcing companies.
我清晰地记得我开始我第一份真正的软件开发工作的那一天。我既兴奋又害怕。在我高中的时候,我曾经为当地企业编写黑客软件,我渴望成为一名“真正的程序员”,为国内最大的外包公司之一编写一些代码。
In my first days there, my new colleagues were showing me the ropes. After setting up the corporate email and going through the time-tracking system, we finally moved on to the interesting stuff: the company’s coding style and standards. I was told that “here, we always write well-designed code and use the layered architecture.” We went through the definition of each of the three layers—the data access, business logic, and presentation layers—and then discussed the technologies and frameworks for addressing the layers’ needs. Back then, the accepted solution for storing data was Microsoft SQL Server 2000, and it was integrated using ADO.NET in the data access layer. The presentation layer rocked either WinForms for desktop applications or ASP.NET WebForms for the web. We spent quite some time on these two layers, so I was puzzled when the business logic layer didn’t get any attention:
我去那里的第一天,我的新同事给我指点迷津。在建立了公司的电子邮件和时间跟踪系统之后,我们最终转向了有趣的事情:公司的编码风格和标准。有人告诉我,“在这里,我们总是编写设计良好的代码,并使用分层架构”。我们讨论了三层(数据访问层、业务逻辑层和表示层)中每一层的定义,然后讨论了满足这些层需求的技术和框架。当时,公认的存储数据的解决方案是在Microsoft SQL Server 2000,在数据访问层中使用 ADO.NET 进行集成。表示层为桌面应用程序的 WinForms 或 Web 的 ASP.NET WebForms。我们在这两个层上花了相当多的时间,所以当业务逻辑层没有得到任何关注时,我感到很困惑:
“But what about the business logic layer?”
“业务逻辑层呢?”
“That one is straightforward. Here is where you implement the business logic.”
“这一点很简单,这里是您实现业务逻辑的地方。”
“But what is business logic?”
“但什么是业务逻辑?”
“Oh, business logic is all the loops and ‘if-else’ statements you need in order to implement the requirements.”
“哦,业务逻辑是实现需求所需的所有循环和“ if-else”语句。”
That day I began my journey to find out what exactly business logic is and how on earth it should be implemented in well-designed code. It took me more than three years to finally find the answer.
从那天起,我开始寻找究竟什么是业务逻辑,以及到底应该如何在设计良好的代码中实现它。我花了三年多的时间终于找到了答案。
The answer was in Eric Evans’s seminal book, Domain-Driven Design: Tackling Complexity in the Heart of Software. It turned out that I wasn’t wrong. Business logic is indeed important: it is the heart of software! Unfortunately, however, it took me another three years to understand the wisdom Eric shared. The book is very advanced, and the fact that English is my third language didn’t help.
埃里克•埃文斯的开创性著作《领域驱动设计:解决软件核心的复杂性》给出了答案。事实证明我没有错。业务逻辑确实很重要: 它是软件的核心!然而,不幸的是,我又花了三年时间才明白埃里克分享的智慧。这本书非常先进,而英语是我的第三语言,因此对我没有多大的帮助。
Eventually, though, everything fell into place, and I made peace with the domain-driven design (DDD) methodology. I learned the principles and patterns of DDD, the intricacies of modeling and implementing the business logic, and how to tackle the complexity in the heart of the software that I was building. Despite the obstacles, it definitely was worth it. Getting into domain-driven design was a career-changing experience for me.
不过,最终一切都步入正轨,我接受了领域驱动设计(DDD)方法论。我学习了 DDD 的原则和模式,建模和实现业务逻辑的复杂性,以及如何处理我正在构建的软件核心的复杂性。尽管困难重重,但这一切都是值得的,步入领域驱动设计对我来说是一次改变职业生涯的经历。
Why I Wrote This Book
我为什么写这本书
Over the past 10 years, I have introduced domain-driven design to my colleagues at different companies, conducted in-person classes, and taught online courses. The teaching perspective not only helped me deepen my knowledge, but also allowed me to optimize the way I explain the principles and patterns of domain-driven design.
在过去10年里,我在不同的公司向同事介绍过领域驱动设计,举办过面授课程,还教授过在线课程。教学视角不仅帮助我加深了知识,还让我优化了解释领域驱动设计原理和模式的方法。
As often happens, teaching is even more challenging than learning. I’m a huge fan of Eliyahu M. Goldratt’s work and teachings. Eliyahu used to say that even the most complex systems are inherently simple when viewed from the right angle. During my years of teaching DDD, I was looking for a model of the methodology that would uncover the inherent simplicity of domain-driven design.
正如经常发生的那样,教学比学习更具挑战性。我是伊利雅胡·高德拉特的工作和教学的忠实粉丝。伊利亚胡曾经说过,即使是最复杂的系统,如果从正确的角度来看,其本质也是简单的。在我教授 DDD 的那些年里,我一直在寻找一种能够揭示领域驱动设计的简单本质的方法模型。
This book is the result of my efforts. Its goal is to democratize domain-driven design; make it easier to understand and more accessible to employ. I believe that the DDD methodology is absolutely invaluable, especially when designing modern software systems. This book will give you just enough tools to start applying domain-driven design in your day-to-day work.
这本书是我努力的结果,它的目标是使领域驱动设计大众化;使它更容易理解和使用。我相信 DDD 方法是绝对无价的,特别是在设计现代软件系统时。这本书将为你开始在日常工作中应用领域驱动设计提供足够的工具。
Who Should Read This Book
谁应该读这本书
I believe that knowledge of domain-driven design principles and patterns will be useful for software engineers at all levels: junior, senior, staff, and principal. Not only does DDD provide tools and techniques for modeling and effectively implementing software, it also illuminates an often-overlooked aspect of software engineering: the context. Equipped with the knowledge of the system’s business problem, you will be much more effective at choosing the appropriate solution. A solution that is not under or over-engineered, but addresses business needs and goals.
我相信领域驱动设计原理和模式的知识对各个层次的软件工程师都是有用的:初级,高级,总监,和首席工程师。DDD 不仅提供了建模和有效实现软件的工具和技术,它还阐明了软件工程中一个经常被忽视的方面: 上下文。掌握了系统的业务问题知识,您能更有效地选择恰当的解决方案。一个不是设计不足或过度设计的解决方案,而是针对业务需求和目标的解决方案。
Domain-driven design is even more important for software architects, and even more so for aspiring software architects. Its strategic design decision tools will help you decompose a large system into components—services, microservices, or subsystems—and design how the components are integrated with one another to form a system.
领域驱动设计对于软件架构师来说更为重要,对于有抱负的软件架构师来说更是如此。它的战略设计决策工具将帮助您将一个大型系统分解为多个部件(服务、微服务或子系统) ,并设计如何将这些部件彼此集成以形成一个完整的系统。
Ultimately, in this book we will discuss not only how to design software, but also how to co-evolve the design with changes in its business context. That crucial aspect of software engineering will help you keep the system’s design “in shape” over time and prevent its degradation into a big ball of mud.
最后,在本书中,我们不仅要讨论如何设计软件,还要讨论如何根据业务环境中的变化同时演化设计(业务与设计共同演化)。软件工程的这个关键方面将帮助您随着时间的推移保持系统设计的“良好状态”,并防止其退化成一个大泥球。
Navigating the Book
本书导航
This book is divided into four parts: strategic design, tactical design, DDD in practice, and DDD’s relationships to other methodologies and patterns. In Part I, we cover tools and techniques for making large-scale software design decisions. In Part II, we focus on the code: the different ways to implement a system’s business logic. Part III discusses techniques and strategies for applying DDD in real-life projects. Part IV continues the discussion of domain-driven design, but this time in the context of other methodologies and patterns.
这本书分为四个部分: 战略设计,战术设计,DDD 实践,以及 DDD 与其他方法论和模式的关系。在第一部分中,我们将介绍用于为大规模软件做出设计决策的工具和技术。在第二部分中,我们重点讨论代码:实现系统业务逻辑的不同方法。第三部分讨论了在实际项目中应用 DDD 的技术和策略。第四部分继续讨论领域驱动设计,但这次是在其他方法论和模式的背景下。
Here is a short summary of what you will find in each chapter:以下是你将在每一章中发现的内容的简短摘要:
- Chapter 1 establishes the context of a software engineering project: the business domain, its goals, and how the software is intended to support them. 第1章 确立了软件工程项目的上下文:业务领域、其目标以及软件如何支持业务领域及其目标的实现。
- Chapter 2 introduces the notion of a “ubiquitous language”: domain-driven design’s practice for effective communication and knowledge sharing. 第2章 介绍“通用语言”的概念:领域驱动设计有效沟通和知识分享的实践。
- Chapter 3 discusses how to tackle the complexity of business domains and design the system’s high-level architectural components: bounded contexts. 第3章 讨论了如何处理业务领域的复杂性并设计系统的高级体系结构部件:有界上下文。
- Chapter 4 explores the different patterns of organizing the communication and integration between the bounded contexts. 第4章 探讨了在有界上下文之间处理通信和集成的不同模式。
- Chapter 5 starts the discussion of business logic implementation patterns with two patterns addressing the cases of simple business logic. 第5章 开始讨论业务逻辑实现模式,其中有两个模式用于处理简单业务逻辑的情况。
- Chapter 6 advances from simple to complex business logic and introduces the domain model pattern for tackling its complexity. 第6章 从简单的业务逻辑发展到复杂的业务逻辑,并介绍了解决其复杂性的领域模型模式。
- Chapter 7 adds the perspective of time and introduces an even more advanced way to model and implement business logic: the event-sourced domain model. 第7章 增加了时间的视角,并介绍了一种更高级的业务逻辑建模和实现方法: 事件溯源领域模型。
- Chapter 8 shifts the focus to a higher level and describes three architectural patterns for structuring components. 第8章 将重点转移到更高的层次,并描述了构造部件的三种体系结构模式。
- Chapter 9 provides the patterns needed to orchestrate the work of the system’s components. 第9章 提供了协调系统组件工作所需的模式。
- Chapter 10 ties together the patterns discussed in the earlier chapters into a number of simple rules of thumb that streamline the process of making design decisions. 第10章 将前几章讨论的模式结合成一些简单的经验法则,简化了设计决策的过程。
- Chapter 11 explores software design from the perspective of time and how it is supposed to change and evolve through its lifespan. 第11章 从时间的角度探讨了软件设计,以及软件设计应该如何在其生命周期中改变和发展。
- Chapter 12 introduces EventStorming: a low-tech workshop for effectively sharing knowledge, building shared understanding, and designing software. 第12章 介绍事件风暴:一个有效分享知识、建立共识和设计软件的低技术研讨会。
- Chapter 13 addresses the difficulties you may face when introducing domain-driven design to brownfield projects. 第13章 阐述了向待重新开发项目引入领域驱动设计时可能遇到的困难。
- Chapter 14 discusses the relationship between the microservices architectural style and domain-driven design: where they differ and where they complement each other. 第14章 讨论了微服务架构风格和领域驱动设计之间的关系:它们的不同之处以及它们互补的地方。
- Chapter 15 explores domain-driven design patterns and tools in the context of the event-driven architecture. 第15章 探讨事件驱动架构背景下的领域驱动设计模式和工具。
- Chapter 16 shifts the discussion from operational systems to analytical data management systems and discusses the interplay between domain-driven design and the data mesh architecture. 第16章 将讨论从业务系统转移到分析数据管理系统,并讨论了领域驱动设计和数据网格架构之间的相互作用。
All of these chapters end with a number of exercise questions to reinforce the learning. Some of the questions use the fictional company “WolfDesk” to demonstrate the various aspects of domain-driven design. Please read the following description of WolfDesk, and return to it when you answer relevant exercise questions.
所有这些章节都以一些练习题结束,以强化学习。其中一些问题使用虚构的公司“ WolfDesk”来演示领域驱动设计的各个方面。请阅读以下关于 WolfDesk 的描述,并在回答相关练习问题时重新阅读。
Example Domain: WolfDesk
示例领域:WolfDesk
WolfDesk provides a help desk tickets management system as a service. If your start-up company needs to provide support to your customers, with WolfDesk’s solution you can get up and running in no time.
WolfDesk 提供了一个服务台票务管理系统(可能类似于客户支持工单系统)作为服务。如果您的创业公司需要为客户提供支持,使用 WolfDesk 的解决方案,您可以立即启动并运行。
WolfDesk uses a different payment model than its competitors. Instead of charging a fee per user, it allows the tenants to set up as many users as needed, and the tenants are charged for the number of support tickets opened per charging period. There is no minimum fee, and there are automatic volume discounts for certain thresholds of monthly tickets: 10% for opening more than 500 tickets, 20% for opening more than 750 tickets, and 30% for opening more than 1,000 tickets per month.
WolfDesk 采用了与竞争对手不同的支付模式。它允许租户根据需要设置尽可能多的用户,根据每个收费期打开的工单数量向租户收取费用,而不是对每个用户收取费用。没有最低费用,而且对于每个月的工单阈值有自动批量折扣:打开超过500单可获九折; 打开超过750单可获八折; 打开超过1000单可获七折。
To prevent tenants from abusing the business model, WolfDesk’s ticket lifecycle algorithm ensures that inactive tickets are closed automatically, encouraging customers to open new tickets when further support is needed. Moreover, WolfDesk implements a fraud detection system that analyzes messages and detects cases of unrelated topics being discussed in the same ticket.
为了防止租户滥用业务模型,WolfDesk 的工单生命周期算法确保非活动工单自动关闭,鼓励客户在需要进一步支持时开启新工单。此外,WolfDesk 实现了一个欺诈检测系统,该系统可以分析消息,并检测在同一工单中讨论的不相关主题的情况。
To help its tenants streamline the support-related work, WolfDesk has implemented a “support autopilot” feature. The autopilot analyzes new tickets and tries to automatically find a matching solution from the tenant’s ticket history. The functionality allows for further reducing the tickets’ lifespans, encouraging customers to open new tickets for further questions.
为了帮助其租户简化与支持相关的工作,WolfDesk 实现了一个“支持的智能助手”特性。智能助手分析新的工单,并试图从租户的工单历史中自动找到匹配的解决方案。这项功能可以进一步缩短工单的使用寿命,鼓励客户打开新的工单以便进一步提问。
WolfDesk incorporates all the security standards and measures to authenticate and authorize its tenants’ users and also allows tenants to configure a single sign-on (SSO) with their existing user management systems.
WolfDesk 集成了所有的安全标准和措施,以验证和授权其租户的用户,还允许租户使用其现有的用户管理系统配置单点登录(SSO)。
The administration interface allows tenants to configure the possible values for the tickets’ categories, as well as a list of the tenant’s products that it supports.
管理界面允许租户配置工单类目的可能值,以及它支持的租户产品列表。
To be able to route new tickets to the tenant’s support agents only during their working hours, WolfDesk allows the entry of each agent’s shift schedule.
为了能够仅在租户的支持人员(客服)的工作时间内将新工单发送给他们,WolfDesk 允许输入每个客服的值班时间表。
Since WolfDesk provides its service with no minimal fee, it has to optimize its infrastructure in a way that minimizes the costs of onboarding a new tenant. To do that, WolfDesk leverages serverless computing, which allows it to elastically scale its compute resources based on the operations on active tickets.
由于 WolfDesk 提供服务时不收取最低费用,因此它必须优化其基础设施,从而最大限度地降低登记新租户的成本。要做到这一点,WolfDesk 利用了无服务器计算,这使得它可以根据对活动工单的操作弹性地扩展计算资源。
Conventions Used in This Book
本书中的约定
The following typographical conventions are used in this book:
本书使用了以下排版约定:
Italic
斜体
Indicates new terms, URLs, email addresses, filenames, and file extensions.
指示新术语、 URL、电子邮件地址、文件名和文件扩展名。
Constant width
等宽字体
Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords.
用于程序清单,以及在段落中引用程序元素,如变量或函数名、数据库、数据类型、环境变量、语句和关键字。
NOTE 注意 This element signifies a general note. 这个元素表示一个通用的注意。
Using Code Examples
使用代码示例
Supplemental material (code examples, exercises, etc.) is available for download at https://learning-ddd.com.
补充资料(代码示例、练习等)可于 https://learning-ddd.com 下载。
All the code samples presented in the book are implemented in the C# language. Generally, the code samples you see in the chapters are excerpts demonstrating the discussed concepts.
书中提供的所有代码示例都是用 C# 语言实现的。通常,您在章节中看到的代码示例是演示所讨论概念的片断。
Of course, the concepts and techniques discussed in the book are not limited to the C# language or to the object-oriented programming approach. Everything is relevant for other languages and other programming paradigms. As a result, feel free to implement the book’s samples in your favorite language and share them with me. I’ll be happy to add them to the book’s website.
当然,书中讨论的概念和技术并不局限于C#语言或面向对象程序设计方法。一切都与其他语言和其他编程范例相关。因此,您可以自由地使用您最喜欢的语言实现本书的示例,并与我分享。我很乐意把它们添加到这本书的网站上。
If you have a technical question or a problem using the code examples, please email bookquestions@oreilly.com.
如果您在使用代码示例时遇到技术问题或困难,请发送电子邮件至 bookquestions@oreilly.com。
This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.
这本书是为了帮助你完成你的工作。一般来说,您可以在程序和文档中使用本书的随书示例代码。您不需要联系我们获得许可,除非您复制了代码的重要部分。例如,编写使用本书中的几段代码的程序不需要许可。销售或分发 O’Reilly 书籍中的例子需要得到许可。通过引用本书和引用示例代码来回答问题不需要许可。将本书中的大量示例代码放入到您的产品文档中确实需要许可。
We appreciate, but generally do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Learning Domain-Driven Design by Vlad Khononov (O’Reilly). Copyright 2022 Vladislav Khononov, 978-1-098-10013-1.”
我们很感激,但一般不要求署名。一个署名通常包括标题,作者,出版商,和 ISBN。例如:“Learning Domain-Driven Design by Vlad Khononov (O’Reilly). Copyright 2022 Vladislav Khononov, 978-1-098-10013-1.”
If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com.
如果您觉得您使用的代码示例超出了合理使用的范围,或者超出了上面给出的许可,请随时与我们联系,电子邮件地址是permissions@oreilly.com。
O’Reilly Online Learning
O’Reilly 在线学习
NOTE 注意 For more than 40 years, O’Reilly Media has provided technology and business training,knowledge, and insight to help companies succeed. 40多年来,O’Reilly 传媒一直致力于提供技术和商业培训、知识和洞察力,以帮助公司取得成功。
Our unique network of experts and innovators share their knowledge and expertise through books, articles, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, visit http://oreilly.com.
我们独特的专家和创新者网络通过书籍、文章和我们的在线学习平台分享他们的知识和专长。O’Reilly 的在线学习平台可以让你按需访问现场培训课程、深度学习路径、交互式编码环境,以及 O’Reilly 和其他200多家出版商的大量文本和视频集合。如欲了解更多资料,请浏览 http://oreilly.com。
How to Contact Us
如何联系我们
Please address comments and questions concerning this book to the publisher:
请向出版商提出有关本书的意见和问题:
We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at https://oreil.ly/lddd.
我们有这本书的网页,在那里我们列出勘误表,例子,和任何其他信息。你可在 https://oreil.ly/lddd 登入此网页。
Email bookquestions@oreilly.com to comment or ask technical questions about this book.
给 bookquestions@oreilly.com 发邮件,就本书发表评论或提出技术问题。
For news and information about our books and courses, visit http://oreilly.com.
有关我们的书籍及课程的最新消息及资料,请浏览 http://oreilly.com。
Find us on Facebook: http://facebook.com/oreilly
在 Facebook 上找到我们:http://Facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
在 Twitter 上关注我们:http://Twitter.com/oreillymedia
Watch us on YouTube: http://youtube.com/oreillymedia
在 YouTube 上看我们的视频:http://YouTube.com/oreillymedia
Acknowledgments
致谢
Originally, this book was titled “What Is Domain-Driven Design?” and was published as a report in 2019. Learning Domain-Driven Design would not have seen the light of day without the report, and I’m obliged to thank those who made “What Is Domain-Driven Design?” possible: Chris Guzikowski, Ryan Shaw, and Alicia Young.
最初,这本书的标题是“什么是领域驱动设计?”并于2019年作为报告发表。如果没有这份报告,学习领域驱动设计就不会出现,我不得不感谢那些制作了《什么是领域驱动设计》的人: 克里斯 · 古兹科夫斯基、瑞恩 · 肖和艾丽西娅 · 杨。
This book also wouldn’t have been possible without O’Reilly’s Content Director and Diversity Talent Lead, Melissa Duffield, who championed the project and made it happen. Thank you, Melissa, for all your help!
如果没有 O’Reilly 的内容总监和多元化人才领导 Melissa Duffield,这本书也不可能出版。 Melissa Duffield 是这个项目的拥护者,也是这个项目的实现者。谢谢你,梅丽莎,谢谢你的帮助!
Jill Leonard was the book’s development editor, project manager, and head coach. Jill’s role in this work cannot be overstated. Jill, thank you so much for all your hard work and help! Extra thanks for keeping me motivated, even when I considered changing my name and hiding in a foreign country.
Jill Leonard 是这本书的开发编辑,项目经理和总指导。Jill 在这项工作中的作用怎么强调都不为过。Jill,非常感谢你所有的辛勤工作和帮助!特别感谢你让我保持动力,即使当我考虑改名并躲藏到国外时(压力山大)。
A huge thanks to the production team for making the book not only writable but readable: Kristen Brown, Audrey Doyle, Kate Dullea, Robert Romano, and Katherine Tozer. For that matter, I want to thank the whole O’Reilly team for the great work you do. It’s a dream come true to be working with you!
非常感谢制作团队使这本书不仅可写而且可读: Kristen Brown,Audrey Doyle,Kate Dullea,Robert Romano 和 Katherine Tozer。就此而言,我要感谢整个O’Reilly团队感谢你们所做的伟大工作。能和你一起工作真是美梦成真!
Thanks to all the people I interviewed and consulted with: Zsofia Herendi, Scott Hirleman, Trond Hjorteland, Mark Lisker, Chris Richardson, Vaughn Vernon, and Ivan Zakrevsky. Thank you for your wisdom and for being there when I needed help!
感谢所有我采访和咨询过的人: Zsofia Herendi,Scott Hirleman,Trond Hjorteland,Mark Lisker,Chris Richardson,Vaughn Vernon,和 Ivan Zakrevsky。谢谢你的智慧,谢谢你在我需要帮助的时候陪在我身边!
Special thanks to the team of reviewers who read through the early drafts and helped me shape the final book: Julie Lerman, Ruth Malan, Diana Montalion, Andrew Padilla, Rodion Promyshlennikov, Viktor Pshenitsyn, Alexei Torunov, Nick Tune, Vasiliy Vasilyuk, and Rebecca Wirfs-Brock. Your support, feedback, and critique helped immensely. Thank you!
特别感谢阅读了早期草稿并帮助我完成最后一本书的评论团队: 朱莉 · 勒曼、露丝 · 马兰、戴安娜 · 蒙尼尔森、安德鲁 · 帕迪拉、罗迪昂 · 普罗米什列尼科夫、维克托 · 普谢尼琴、阿列克谢 · 托鲁诺夫、尼克 · 图恩、瓦西里 · 瓦西柳克和丽贝卡 · 威尔夫斯-布洛克。你们的支持、反馈和批评极大地帮助了我们。谢谢!
I also want to thank Kenny Baas-Schwegler, Alberto Brandolini, Eric Evans, Marco Heimeshoff, Paul Rayner, Mathias Verraes, and the rest of the amazing domain-driven design community. You know who you are. You are my teachers and mentors. Thank you for sharing your knowledge on social media, blogs, and conferences!
我还要感谢肯尼 · 巴斯-施韦格勒、阿尔贝托 · 布兰多里尼、埃里克 · 埃文斯、马尔科 · 海梅肖夫、保罗 · 雷纳、马赛亚斯 · 维雷斯以及其他令人惊叹的领域驱动设计。你知道你是谁。你们是我的老师和导师。感谢您在社交媒体、博客和会议上分享您的知识!
I’m most indebted to my dear wife, Vera, for always supporting me in my crazy projects and trying to guard me from things that could distract me from writing. I promise to finally declutter the basement. It is going to happen soon!
我非常感谢我亲爱的妻子维拉,她总是在我的疯狂项目中支持我,并试图保护我不受那些可能会分散我写作注意力的事情的影响。我保证最终会整理好地下室。马上就要发生了!
Finally, I want to dedicate this book to our beloved Galina Ivanovna Tyumentseva, who supported me so much in this project and whom we sadly lost during the writing of this book. We will always remember you. #AdoptDontShop
最后,我想把这本书献给我们敬爱的加林娜 · 伊万诺夫娜 · 秋门采娃,她在这个项目中给予了我如此多的支持,在写这本书的过程中,我们遗憾地失去了她。我们会永远记住你。
