去哪儿网架构演进:微服务与DDD的融合 -- 知识铺
业务架构的演进与互联网企业的发展
架构设计理念与技术概述
架构的演进路径
业务架构的演变是一个持续的过程,它反映了企业在不同发展阶段的需求和挑战。架构的选择并非一成不变,而是需要根据企业当前的业务需求和未来的发展方向来做出最合适的决策。
1. 服务化到平台化的演进
服务化是将业务功能拆分成独立的服务单元,这些服务可以独立部署和扩展。随着企业规模的扩大和业务的复杂化,服务化架构逐渐向平台化过渡。平台化不仅提供了服务的整合,还实现了领域能力的沉淀和复用。
2. 架构设计理念
架构设计的核心在于如何合理地组织和优化系统组件,以支持业务的持续发展和快速迭代。设计原则包括但不限于模块化、可扩展性、高可用性和安全性。
3. 技术选择与应用
技术的选择应基于业务需求和团队的技术栈。随着云计算、大数据、人工智能等技术的发展,企业需要不断评估和采用新技术,以提高效率和竞争力。
架构演进的实践案例
通过具体案例分析,我们可以更深入地理解架构演进的路径和影响。例如,从单一服务到微服务的转变,再到构建企业级平台的全过程。
案例分析
- 服务拆分:如何将单体应用拆分为多个微服务。
- 服务治理:在微服务架构中实现服务的发现、监控和管理。
- 平台构建:构建统一的平台,实现服务的集成和领域能力的沉淀。
结论
架构的演进是一个动态的过程,需要企业不断地评估和调整。选择合适的架构对于支持企业的长期发展至关重要。通过持续的技术革新和架构优化,企业可以在竞争激烈的市场中保持领先地位。
业务架构的演进路径
业务架构的演变是一个动态的过程,它随着企业的发展阶段和业务需求的变化而调整。以下是业务架构演进的四个主要阶段:
单体架构
- 定义:所有业务融合于一体的架构,也称为巨石系统。
- 优势:在项目早期,有助于降低运营成本。
- 适用场景:适用于初创企业或业务较为单一的情况。
服务化架构
- 定义:随着业务发展,服务开始拆分,形成独立的服务单元。
- 过程:经历服务拆分、治理和模型抽象。
- 优势:提高系统的灵活性和可扩展性。
平台化架构
- 定义:服务化维护成本高时,转向平台化,实现服务能力沉淀和服务合并。
- 特点:领域自治,减少重复工作,提高系统交互效率。
- 适用场景:业务膨胀期过后,需要优化维护成本和系统效率。
中台化架构
- 定义:打造企业级能力复用平台,是平台化的高级阶段。
- 优势:具备数据互通能力和业务变化的高响应力。
架构设计理念架构的演进不是简单的好与坏的判断,而是根据企业当前及未来的需求来决定。选择合适的架构,能够更好地支持业务发展和技术创新。
从服务化到平台化的演进本次分享将重点介绍服务化到平台化的过程,即如何从细粒度的服务拆分过渡到领域能力的沉淀,以实现更高效的业务支持和技术创新。
结语业务架构的演进是一个持续的过程,需要企业不断地评估和调整,以适应不断变化的市场和技术环境。
架构设计的关键在于从业务出发,适应业务变化。以下是根据业务架构设计的几个维度:
1. 商业模式及成熟度
- 传统行业:业务稳定成熟,建议单一服务架构。
- 互联网行业:
- 初创公司:商业不稳定,推荐微服务架构,快速试错。
- 成熟公司:商业稳定,考虑合并微服务,降低维护成本。 以旅游行业为例,去哪儿网属于商业稳定型,建议合并微服务以减少运营成本。
2. 面向业务变化的设计
- 组件设计需围绕业务变化进行。
- 组件调用应避免强依赖。
- 业务组件需实现复用。
- 组件颗粒度应与业务成熟度相匹配。 快速适应业务变化的策略包括:
- 识别业务核心问题。
- 明确业务边界。
- 区分变与不变的业务,将变化局限在一定范围内。
3. 技术延迟决策根据《架构整洁之道》的观点,良好的架构设计应专注于用例,将用例与周边因素隔离。在初期应集中关注用例,在后期再决定使用的具体技术。
在组件拆分时,需权衡颗粒度:
- 过细的拆分虽复用性强,但组装复杂。
- 过大的拆分虽易于使用,但适用场景有限。
通过上述维度,可以构建一个既灵活又稳定的业务架构体系。
康威定律与逆康威定律
4.1 康威定律康威定律指出,产品的架构设计往往是其组织沟通结构的直接反映。在企业中,系统设计不仅体现了组织架构,而且系统各模块之间的接口也映射了部门间信息流动和合作的方式。
4.2 逆康威定律逆康威定律提出,当组织效率不足时,可以通过系统设计来推动组织结构的优化。例如,去哪儿网在2021年实施了DDD(领域驱动设计)和API(应用程序编程接口)战略,通过合理划分团队和职责,体现了逆康威定律的应用。
5 面向测试与运维测试是确保系统质量的关键环节。采用TDD(测试驱动开发)方法,可以验证架构的合理性、隔离性以及测试的便捷性。
6 软件质量属性软件的质量属性在开发和运行期间表现为可用性、可修改性、性能、安全性和易用性等。架构设计应以功能性为基础,同时依据质量属性进行增量式的迭代重构和优化。
架构关键技术分析与业务系统重构背景
一、架构关键技术概述
1. 容器与自动化公司底层架构主要依赖于容器化技术与自动化工具,以提高系统的灵活性和可维护性。
2. 监控与治理在架构的中间层,实施了监控和治理机制,确保系统的稳定运行和问题快速响应。
3. 前后端分离系统采用前后端分离的设计模式,以提高开发效率和用户体验。
4. DDD指导思想领域驱动设计(DDD)作为整个架构的指导思想,帮助团队更好地理解和应对复杂业务需求。
二、业务系统重构背景
1. 业务介绍
酒店基础信息介绍酒店的基本信息,包括但不限于酒店的地理位置、设施服务、客房类型等。
2. 重构需求分析
a. 业务增长随着业务的不断扩展,现有系统需要支持更大规模的数据处理和更复杂的业务逻辑。
b. 技术迭代技术不断进步,需要对现有技术栈进行升级,以适应新的市场需求。
c. 用户体验为了提供更加流畅和个性化的用户体验,系统需要进行界面和交互的优化。
3. 重构目标设定#### a. 性能提升通过重构提高系统的处理能力和响应速度。
b. 可维护性增强优化代码结构,提高系统的可维护性和可扩展性。
c. 用户满意度提高通过改善用户界面和交互流程,提升用户满意度和忠诚度。
去哪儿网的APP重构以提升用户体验,其中酒店基础信息部门扮演了核心角色。以下是其业务流程的详细说明:
酒店预订流程
列表页
- 用户启动APP,输入所需地址和入住时间。
- 点击搜索后,APP将展示所选地点的所有酒店列表。
详情页
- 用户选择感兴趣的酒店后,点击进入详情页。
- 详情页提供酒店的详细信息,帮助用户做出选择。
酒店Info页
- 用户点击酒店名称,将进入酒店Info页。
- 此页面提供酒店的更全面信息,包括设施、服务等。
进订页
- 用户决定预订后,点击跳转到进订页。
- 在此页面完成酒店房间的预订流程。
基础信息业务架构
业务架构是支撑去哪儿网酒店预订流程的基石,确保信息的准确性和流程的顺畅性。
去哪儿网的酒店业务架构图展示了从底层数据到顶层用户交互的完整流程。在这个架构中,酒店信息的来源多样,包括不同的代理商和集团分销渠道。信息的流动遵循自下而上的顺序,首先通过基础层,然后到达业务层,这是整个架构的核心。
酒店信息聚合业务层的关键在于酒店信息的聚合。去哪儿网将不同代理商提供的酒店信息,按照既定的业务逻辑和规则,整合成统一的Q侧物理酒店。这一过程不仅简化了用户的选择过程,也提高了用户体验。
用户体验的提升以季枫酒店为例,不同代理商可能会使用不同的命名方式,如北京店、中关村店或苏州街店。这种不一致性可能导致用户混淆。通过聚合,去哪儿网确保用户看到的是统一且唯一的酒店信息,从而避免了混淆。
酒店Tree概念酒店Tree是去哪儿网特有的概念,指的是将各个代理商投放的酒店信息映射到去哪儿网的酒店体系中。以去哪儿网的酒店作为树根,挂靠不同代理商的酒店信息,形成清晰的对应关系。
应用层信息提供我们团队的主要任务是将经过业务层处理的酒店信息,传递给应用层,比如APP。这包括搜索和筛选功能,确保用户能够在APP中方便地获取所需信息。
技术战略与债务落地技术中心战略,偿还技术债务是我们团队当前的重点工作。这意味着我们需要不断优化技术架构,提高系统的稳定性和扩展性,同时解决历史遗留的技术问题,为公司的长远发展打下坚实基础。
2022年,面对疫情对旅游行业的冲击,技术中心提出了’巩固效率之本,分担产品之忧’的战略,并启动了DDD(领域驱动设计)重构项目。以下是对重构前存在的问题以及系统重构模式选择的概述:
重构前的问题
- 核心业务分散:核心业务被耦合在多个系统中,导致业务分散,难以集中管理。
- 核心业务入侵:产品需求交付效率低,一个需求可能需要多个微服务的调整。
- 数据写入链路长:缺乏对核心业务的统一管理,导致数据更新延迟,实时查询能力缺失,其他团队需要自行拉取并缓存数据。
系统重构模式选择在系统重构过程中,我们认识到没有绝对最优的架构,只有最适合当前业务需求的架构。以下是我们考虑的几种系统重构模式:
- 模式一:介绍模式一的特点和适用场景。
- 模式二:介绍模式二的特点和适用场景。
- 模式三:介绍模式三的特点和适用场景。 每种模式都有其优势和局限性,我们将根据业务需求和团队能力,选择最合适的重构模式,以提高系统的灵活性和可维护性,同时优化产品交付流程。
结语DDD重构之路是一次对现有业务和技术架构的深度反思和优化。通过选择合适的重构模式,我们期待能够提升业务响应速度,增强系统的稳定性和扩展性,最终实现业务与技术的双赢。
在系统重构的过程中,我们通常会遇到几种不同的改造模式,每种模式都有其适用场景和优缺点。以下是对这些模式的梳理和分析:
系统重构改造模式
修缮者模式修缮者模式是在现有系统的基础上增加一个抽象层,以保证对外提供的服务或能力保持不变,同时对系统内部进行必要的改造。这种方式适用于系统需要部分更新,但整体架构仍然有效的情况。
优点
- 保证业务连续性,不影响现有业务的运行。
- 逐步改进,降低风险。
缺点
- 需要在一段时间内维护旧系统和新抽象层,增加了维护成本。
绞杀者模式当修缮者模式无法满足需求时,绞杀者模式允许我们在系统外部构建新的功能,并逐步替换旧系统中的逻辑。这是一种更为激进的重构方式。
优点
- 允许在不影响现有业务的情况下,逐步引入新功能。
- 一旦新系统稳定,可以完全替换旧系统。
缺点
- 需要同时维护两套系统,增加了开发和维护成本。
- 重构过程中可能面临技术债务和复杂性增加的问题。
演进式迭代对于逻辑已经模糊的老项目,演进式迭代是一种更为谨慎的重构方式。它从最小可行产品(MVP)开始,逐步迭代核心业务逻辑,然后逐渐将边缘业务迁移过来。
优点
- 有效控制迭代风险,避免一次性替换带来的不确定性。
- 快速上线,及时收集反馈,进行调整。
缺点
- 需要对现有业务逻辑有深入理解,以识别核心和边缘业务。
- 迭代过程中可能需要频繁调整,增加了工作量。
架构选择在选择系统重构的架构时,需要考虑业务需求、技术栈、团队能力等多方面因素。一个合理的架构应该能够支持业务的持续发展,同时保持系统的可维护性和可扩展性。
考虑因素
- 业务需求:架构应满足当前和未来的业务需求。
- 技术栈:选择与团队技能和业务需求相匹配的技术栈。
- 团队能力:考虑团队的技术能力和学习曲线。
架构原则
- 模块化:保持系统的模块化,便于独立开发和测试。
- 解耦:少组件之间的依赖,提高系统的灵活性。
- 可扩展性:设计时考虑系统的可扩展性,以适应未来的变化。
通过上述分析,我们可以得出一个适合的系统重构框架,它应该能够平衡改造的复杂性和业务的连续性,同时为系统的长期发展提供支持。
现代架构设计的关键:面向业务变化
在当今快速发展的商业环境中,架构设计的成败往往取决于其对业务变化的适应能力。领域驱动设计(DDD)作为一种设计思想,与成功架构设计的理念不谋而合。
服务业务战略
从企业架构(EA)的角度出发,DDD能够将业务架构(BA)与应用架构(AA)紧密结合,实现问题域与应用架构的有效分离。通过DDD的实践,我们可以将业务架构中的“价值流+业务能力”进行解构化分解,实现能力下沉。同时,基于DDD划分的限界上下文和聚合,构建应用架构,实现自下而上的“高内聚、低耦合”。
演进式架构
DDD的核心思想贯穿战略、战术和实现三个层面:
- 战略层面:从业务问题分析入手,分解子问题域,识别核心域,实现分而治之,降低业务复杂度。
- 战术层面:识别问题域的不同业务上下文,通过领域建模定义聚合,组件化业务需求,指导微服务的拆分。
- 实现层面:采用成熟的分层模式和依赖倒置原则,屏蔽技术细节的复杂度。DDD设计方法使微服务在限界上下文和聚合的支撑下,实现内外解耦,便于业务功能的模块化重组和更新,促进架构的持续演进。
系统重构的策略选择
在面对系统复杂度高、业务细节了解不足的挑战时,我们选择绞杀模式和演进模式进行系统重构。为了减少重构对现有业务的影响,我们将核心资源集中投入到核心业务中,以快速上线并验证效果。
微服务架构演进实践
领域驱动设计过程
在本节中,我们将详细介绍以业务为驱动的微服务架构演进实践,包括但不限于领域驱动设计的具体步骤和方法。
领域驱动设计(DDD)实战过程概述
领域驱动设计(DDD)是一种以业务为核心,通过深入理解业务领域来指导软件设计的方法。以下是DDD的完整流程和关键路径的详细介绍:
1. 团队成员定位在进行领域驱动设计时,首先要对团队成员进行定位,以确保团队成员能够发挥各自的专长:
- 领域专家:对业务领域有深刻理解的人,能够协助团队深入理解业务,是后续讨论和建模的关键。
- 技术专家:对技术有深入研究的成员,能够提供技术解决方案和建议。
- 开发团队:负责将设计转化为实际代码的团队。
2. 领域驱动设计的关键路径领域驱动设计的关键路径包括以下几个步骤:
第一步:统一语言的建立
- 业务愿景明确:领域专家和开发团队共同讨论需求,明确业务愿景。
- 需求讨论:通过讨论,形成对问题域内概念的统一认知,降低交流成本。
第二步:问题域分析与子域划分
- 子域划分:将问题域划分为核心子域、支撑子域和通用子域。
- 限界上下文构建:在各个子域内进一步划分限界上下文,并构建上下文地图。
第三步:领域建模与实现
- 模型实现:将分析结果投射到代码层面,实现领域模型。
- 关联与循环:确保统一语言与模型紧密相关联,模型与软件实践紧密相关联。在实践中不断循环提炼知识,逐步完善模型。
3. 落地实践注意事项
- 识别关键角色,确保团队成员能够充分发挥各自的作用。
- 通过不断的沟通和讨论,建立和维护统一语言,确保团队成员对业务有一致的理解。
- 在建模过程中,注重实践与理论的结合,通过不断的迭代和优化,逐步形成高质量的领域模型。
以上是对领域驱动设计实战过程的一个简要介绍,希望能够帮助团队更好地理解和应用DDD。
在实现领域驱动设计(DDD)的过程中,我们需要遵循一系列步骤以确保项目的成功落地。以下是对上述内容的重新编写和结构化:
DDD落地实践过程
1. 定位愿景
- 重要性:愿景是项目发展的方向标,它决定了整个项目的未来走向。
2. 问题域分析
- 步骤一:分析现有的业务场景,理解业务需求和操作流程。
- 步骤二:基于业务场景,划分子域,为进一步的领域建模打下基础。
3. 识别限界上下文
- 在子域的基础上,识别和定义限界上下文,明确不同子域之间的边界。
4. 领域建模与模型实现
- 在确定的限界上下文中进行深入的领域建模。
- 根据模型设计实现具体的业务逻辑。
通过上述步骤,我们可以确保DDD的落地实践既系统又高效,为项目的长期发展奠定坚实的基础。
电梯演讲的概念与应用
1. 电梯演讲的定义电梯演讲,源自麦肯锡,指的是在短时间内,如乘坐电梯的30秒内,向他人清晰、准确地传达解决方案或业务价值。它要求使用简洁的语言,精准地说明核心价值。
示例
- 去哪儿网的核心价值:‘总有你要的低价’。
2. 核心工作的落实围绕核心价值,所有工作,尤其是基础信息团队的工作,都应致力于提供多样化的信息聚合,确保信息的丰富性和准确性。
3. 领域专家的重要性产品迭代的快速性要求系统演进中必须有领域专家的参与。领域专家的确定应根据产品、QA、技术人员的顺位来决定,以确保产品方向的正确性和技术实现的可行性。
领域专家的角色
- 确保产品方向与市场需求一致。
- 促进技术实现与产品愿景的结合。
- 提供专业知识,支持产品决策和问题解决。
结构化内容的要点
- 定义:清晰阐述电梯演讲的概念。
- 应用:展示如何将电梯演讲应用于业务中。
- 领域专家:强调领域专家在产品开发中的关键作用。
- 结构性:确保内容条理清晰,逻辑性强。
以上内容以Markdown格式编写,确保了结构性和可读性,同时遵循了用户的要求。
在对原有项目的深入分析中,我们首先整理了用例图,以识别与项目愿景紧密相关的用户用例。通过团队成员的逐一分析,我们发现随着时间的流逝和商业模式的演变,一些业务已经变得不再适用。针对这些不再符合当前需求的业务,我们采取了果断措施:要么将其下线,要么重新分配资源。通过这一过程,我们成功地将原有的188个用例精简至79个,这不仅提高了工作效率,也使得项目更加聚焦于核心价值。
事件风暴概述
事件风暴是一种业务分析方法,它着重于识别和理解业务流程中的领域事件、决策命令和领域名词。以下是事件风暴的关键步骤和原则:
1. 业务视角的事件识别
- 事件风暴从业务角度出发,关注业务动作如何影响数据和业务流程状态。
- 避免过早陷入技术实现的细节,保持对业务目标的关注。
2. 思维过程:发散与收敛
- 发散阶段:鼓励团队成员自由地提出所有可能的想法和事件。
- 收敛阶段:在发散的基础上,对想法进行筛选和整合,形成清晰的业务流程。
3. 识别决策命令
- 明确哪些角色通过哪些动作触发了事件的产生。
- 这有助于理解业务流程中的决策点和责任分配。
4. 领域名词的识别
- 识别业务领域中的关键术语和概念,确保团队对业务有共同的理解。
统一语言的重要性
统一语言是确保团队成员之间有效沟通的关键。以下是实现统一语言的几个要点:
- 共同术语:确保所有团队成员使用相同的术语来描述业务概念和流程。
- 避免歧义:明确术语的含义,避免因理解不同而导致的沟通障碍。
- 持续沟通:在项目过程中持续进行语言和概念的校准,确保团队成员对业务有一致的理解。
通过遵循上述原则,事件风暴不仅帮助团队深入理解业务需求,而且为后续的领域建模提供了坚实的基础。
在软件开发过程中,DDD(领域驱动设计)经验的缺失并不妨碍团队形成统一的语言。以下是对统一语言概念的阐释和实践建议:
统一语言的重要性统一语言是团队成员之间沟通的桥梁,它有助于确保所有成员对项目目标和需求有共同的理解。例如,如果一个老系统的内部逻辑非常复杂,这部分代码的重构成本高昂,难以轻易更改,它本身就可以成为团队的统一语言。产品和技术人员通过这种语言,能够明确系统的目标、能力和应对策略。
技术与产品沟通的偏差技术人员在表达问题时往往倾向于使用代码逻辑,这可能导致与产品人员的沟通出现偏差。统一语言可以帮助双方拉齐认知,技术人员只需提出几个领域术语,产品人员即可迅速理解。
术语表的制定统一语言的术语表应该包含中英文对照,以便于在编码和解码过程中,团队成员能够在代码层面达成共识。
识别限界及子域划分在DDD实践中,识别限界上下文和进行子域划分是关键步骤。这有助于团队明确不同部分的职责和边界,从而更有效地组织工作和沟通。
通过上述内容,我们可以看到,统一语言不仅仅是技术术语的集合,它还是团队协作和沟通的基础。无论是新团队成员还是经验丰富的开发者,都应该致力于理解和使用这种语言,以促进项目的顺利进行。
在进行限界上下文的识别和划分时,我们应遵循以下原则,以降低业务、管理和技术层面的复杂度:
-
降低业务复杂度:在业务层面,必须确保语言的明确性,避免因不同角色对同一概念理解不同而产生的歧义。例如,在去哪儿网内部,商务和技术人员对’酒店’一词的理解可能存在差异,因此在划分限界上下文时,应避免此类情况发生。
-
降低管理复杂度:基于领域层的业务边界划分,进一步影响工作边界的确定。康威定律和两个披萨原则(即一个高效的技术研发团队的规模应控制在两个披萨能够满足的人数)为团队规模和工作边界的划分提供了指导。
-
降低技术复杂度:不同的限界上下文可能需要承载不同的流量。通过创建弹性边界、进行部署和可用性测试,我们可以针对不同的限界上下文采取不同的技术策略。 这些原则有助于我们更有效地管理和优化系统架构,确保系统的可维护性和可扩展性。
在设计系统架构时,上下文特征和依赖关系管理至关重要。以下是对限界上下文特征的重新梳理和结构化描述:
限界上下文特征
-
最小完备原则:每个自治单位都应具备完成其职责所需的所有信息,无需依赖其他单位。
-
自我履约原则:自治单位应自主决定其职责范围。例如,在代理商酒店数据抓取过程中,一旦完成,就无需进一步解析。
-
稳定空间原则:自治单位应保持其内部稳定,不受外部变化的影响。
-
独立进化原则:自治单位在对外提供稳定接口的同时,允许内部进行独立的变化和发展。
上下文依赖地图绘制原则
- 三不原则:在绘制上下文依赖地图时,应避免以下情况:
- 不要双向依赖:避免形成相互依赖的循环。
- 不要循环依赖:确保依赖关系清晰,不形成闭环。
- 不要过长依赖:保持依赖链的简洁,避免冗长和复杂的依赖关系。
循环依赖问题及解决方案
在制作上下文依赖地图时,我们发现存在循环依赖问题,例如:
-
酒店解析依赖于酒店抓取。
-
酒店抓取又依赖于酒店聚合信息。
-
酒店聚合信息依赖于静态信息。
-
静态信息最终又依赖于酒店解析。 这种循环依赖导致划分方式不合适。为解决这一问题,我们采取了以下措施:
-
创造新环节:引入“酒店上下文”环节,以打破原有的循环依赖,实现依赖关系的合理化。 通过上述措施,我们能够确保系统的模块化和解耦,提高系统的可维护性和可扩展性。
在进行系统设计时,识别和划分核心域、支撑域和通用域是至关重要的。这一过程不仅有助于明确业务愿景,还能优化资源配置和需求管理。以下是对这一过程的详细阐述:
-
核心域识别:核心域是与业务愿景紧密相关的领域,通常代表了企业的核心竞争力。识别核心域有助于企业集中资源,加强创新和市场竞争力。
-
支撑域划分:支撑域虽然不直接贡献于业务愿景,但对核心域的运作至关重要。它们提供了必要的支持和功能,确保核心域能够高效运作。
-
通用域界定:通用域是那些在多个业务领域中普遍存在的功能或服务,如用户管理、支付处理等。它们通常可以跨多个业务线复用。
-
资源分配:明确了各域的划分后,可以更合理地分配人员和机器资源,确保关键领域得到足够的支持。
-
需求评估与优先级:通过识别哪些需求位于核心领域内,可以更有效地评估产品需求的优先级,确保资源被投入到最有价值的地方。
-
领域建模:领域建模是一种分析和设计方法,通过识别业务领域中的实体、关系和规则,构建出业务模型。这有助于更好地理解业务需求,指导系统设计。 通过上述步骤,企业可以更清晰地了解自身的核心竞争力,同时在内部实现资源的合理分配和需求的有效管理。
构建领域模型是软件开发过程中的一项重要活动,它有助于明确业务需求并指导系统设计。以下是对领域建模的重新整理和阐述:
1. 建模的意义
- 高内聚低耦合:聚合的使用有助于实现业务逻辑的高内聚和低耦合性。
- 降低复杂度:通过抽象和简化业务流程,降低系统的复杂度,使其更易于管理和适应变化。
2. 建模过程
- 识别关键元素:识别实体和值对象,丰富领域逻辑。
- 定义聚合:明确聚合的边界,识别聚合根,这是建模过程中最具挑战性的部分。 在建模过程中,我们面临的一个难题是如何确定模型的规模。建议是团队成员之间达成共识,即使这个共识可能不是绝对正确的,但在当前阶段是可接受的。因为建模是一个不断迭代和提炼的过程,随着对业务理解的深入,先前的结论可能会被推翻。
3. 分层架构中的注意事项
- 在分层架构中,领域层和业务层的功能划分至关重要。避免将所有功能和用例盲目地加入到领域层,以免造成领域层的膨胀,影响系统的复用性和业务表达力。
4. 建模原则
- 核心域建模:集中资源和注意力在核心领域上。
- 聚合的规模:聚合应尽量小,以适应快速变化的业务需求。
- 一致性:聚合边界内应保持强一致性。
- 抽象:避免过度简化模型,防止属性被过度扁平化,这会导致模型失去可识别性。
建模是一个动态的过程,需要团队成员的共同努力和不断的沟通与调整。
在软件开发和系统设计中,领域模型的构建是一个关键环节。以下是对领域模型构建原则的重新梳理和阐述,以确保模型的合理性和实用性。
领域模型构建原则
-
共性业务能力下沉:在设计领域模型时,应优先考虑将共性的业务能力下沉到具体的领域服务中,这有助于实现服务的复用和模块化。
-
技术问题抽象化:面对技术问题,应将其抽象成业务问题,通过业务逻辑来解决,这样可以提高系统的可维护性和扩展性。
领域模型的共识与检验
-
没有绝对完美的模型,领域模型的正确性取决于团队的共识。共识的形成是模型构建过程中的关键步骤。
-
团队的综合能力直接影响模型的完善程度。一个团队的技术、业务和沟通能力,共同决定了模型的上限。
-
检验模型的技巧:在模型构建完成后,应使用实际的业务场景来检验模型的完整性和适用性。通过不断的迭代和优化,模型将更加贴近实际业务需求。
持续迭代与优化
-
领域模型的构建是一个动态的过程,需要根据业务发展和技术进步不断进行迭代和优化。
-
模型的完善是一个持续的过程,需要团队成员的共同努力和智慧。 通过上述原则和方法,可以构建出既符合业务需求又具备技术前瞻性的领域模型。
在微服务架构的落地实施中,合理划分微服务是关键。以下是对微服务划分的详细步骤和注意事项的梳理:
微服务划分依据
- 业务边界:根据业务流程和功能模块确定服务边界。
- 康威定律:遵循组织结构与系统设计相匹配的原则。
- 业务变更频率:高变更频率的业务应独立为一个服务。
- 弹性边界:识别并划分出可独立扩展的服务。
- 技术选型:根据技术栈和团队能力选择合适的技术实现。
微服务划分注意事项
- 一个微服务可以包含多个限界上下文。
- 微服务应专注于一种子域类型,如核心、通用或支撑。
- 避免将核心域与支撑域混合在同一服务中,以防支撑域的问题影响核心业务。
模型实现#### 业务流程与领域模型映射
- 步骤1:分析业务流程,识别关键业务活动。
- 步骤2:根据业务活动构建领域模型。
- 步骤3:将领域模型与业务流程相对应,确保模型的实用性和准确性。
通过上述步骤,可以确保微服务的划分既符合业务需求,又能够适应快速变化的市场环境。
图片
如上所示,业务流程或业务用例被分为不同阶段,每个阶段又被分为不同活动,我们将这些业务活动与整个分层架构联系起来,构建映射关系。
构建映射关系的好处是,在分层架构和领域模型高度内聚、完善的情况下,方便后续需求接入和扩展。自上而下分解业务流程,分层映射,隔离技术负责度。
② 模型映射代码清单
应用架构概述
在软件开发过程中,为了提高团队合作效率和项目可维护性,我们采用分层架构的方法组织代码。以下是对应用层、领域层和基础设施层的详细说明,以及如何通过代码清单来加强团队协作和知识传递。
应用层(Application Layer)应用层是用户与系统交互的界面,负责协调用户请求和系统响应。它调用领域层的服务来完成业务逻辑,并可以处理诸如用户认证、输入验证等任务。
- 能力:提供用户界面,处理用户输入和系统输出。
- 领域对象:通常包括控制器、服务等。
- 前置依赖:依赖领域层提供的服务。
领域层(Domain Layer)领域层是业务逻辑的核心,包含了业务规则和业务实体。它与应用层和基础设施层解耦,确保业务逻辑的独立性和可复用性。
- 能力:实现业务规则和业务逻辑。
- 领域对象:包括实体(Entity)、聚合(Aggregate)、领域服务(Domain Service)等。
- 前置依赖:可能依赖基础设施层提供的数据访问服务。
基础设施层(Infrastructure Layer)基础设施层提供了技术实现的细节,如数据库访问、消息传递等。它为领域层提供必要的技术支撑,但不涉及业务逻辑。
- 能力:提供技术实现,如数据库操作、网络通信等。
- 领域对象:通常包括数据访问对象(Repository)、消息队列等。
- 前置依赖:无前置依赖,但可能被领域层所依赖。
代码清单的作用构建代码清单有助于:
- 多人合作:确保团队成员对项目结构和业务逻辑有清晰的认识,便于协作开发。
- 新人熟悉:为新成员提供快速了解项目核心逻辑和架构的途径。
- 维护性:随着项目的发展,代码清单可以帮助维护和重构代码。
代码清单示例以下是代码清单的一个示例,展示了如何组织每一层的类和方法:
-
应用层:
-
包名:
com.example.application
-
类名:
UserController
-
方法名:
login()
,register()
-
领域层:
-
包名:
com.example.domain
-
类名:
OrderService
-
方法名:
placeOrder()
,cancelOrder()
-
基础设施层:
-
包名:
com.example.infrastructure
-
类名:
DatabaseRepository
-
方法名:
save()
,load()
结构化与条理性确保代码清单的结构化和条理性,有助于团队成员快速定位和理解代码。使用清晰的命名规范和组织结构,可以显著提高开发效率和代码质量。
开发阶段技术选型
在项目开发过程中,我们决定采用开源框架COLA,其架构设计遵循分层原则,具体分为以下几层:
- 适配层:负责与外部系统或服务的交互。
- 领域层:核心层,包含业务逻辑和稳定的领域模型。
- 应用层:处理应用程序的业务逻辑。
- 基础设施层:提供底层支持,如数据库访问等。 无论是COLA还是DDD(领域驱动设计),它们都强调以业务需求为中心,构建稳定且可扩展的领域模型,并通过分层架构对外提供服务。
选择COLA的理由
- 定义良好的分层结构:COLA提供了清晰的分层规范,有助于团队成员理解项目结构。
- 聚合分包,功能分类:COLA的内部结构设计,使得代码更加模块化,便于管理和维护。
- 最佳实践模板:与《领域驱动设计》一书提供的理论指导相比,COLA给出了更具体的实践模板,方便团队快速落地应用架构。
微服务实践
我们团队在内部实施了基于COLA架构的微服务实践,通过下图可以直观地看到我们的实现方式。(此处应有图,但因格式限制无法展示)
结语
通过采用COLA框架,我们的项目在架构设计上更加清晰,团队协作也更加高效。我们相信,随着项目的深入,COLA将为我们带来更多的便利和优势。
系统架构设计概述
1. 多端适配 (Adaptor)多端适配是确保系统能够在不同平台和设备上正常运行的关键技术。它涉及到对不同操作系统、浏览器和设备的适配,以保证用户界面(UI)和用户体验(UX)的一致性。
2. 业务接口 (Client)业务接口是系统对外提供服务的接口,例如Dubbo框架。这些接口允许外部系统通过标准化的方式与我们的业务逻辑进行交互。
3. 应用层 (APP)应用层是业务用例的编排中心,包括执行器(executor)、发布(publish)和调度(qschedule)等组件。它负责将业务规则和逻辑转化为具体的操作流程。
3.1 业务规则的可视化业务规则的可视化是将业务逻辑以直观的方式展现出来,包括逻辑判断和对象设值。这一过程是纯内存操作,不涉及持久化存储。
3.2 实体与领域服务
- 实体 (Entity) 解决单个对象的逻辑变更,是业务领域中具有持久状态和行为的对象。
- 领域服务 解决涉及多个对象的业务逻辑变更,通常跨越多个实体的边界。
3.3 聚合与限制
- 聚合 是一组相关对象的集合,它们一起作为数据修改的单元。
- 不允许跨聚合调用 意味着每个聚合都应该独立处理其内部逻辑,不应直接操作其他聚合的对象。
3.4 充血模型充血模型是一种设计模式,其中对象具有丰富的行为,能够执行其业务逻辑,而不仅仅是数据的载体。
4. 基础设施层 (Infrastructure)基础设施层包括:
- Repository实现 为领域模型提供数据访问和持久化机制。
- ACL (访问控制列表) 的定义和实现,确保系统的安全性和权限控制。
5. 公共层 (Common)公共层包含系统所需的公共属性和工具类。这些通常由领域层(domain)调用,以实现代码复用和减少冗余。
在软件架构设计中,CQRS模式是一种常见的设计方法,它将命令(Command)和查询(Query)的职责分离,以提高系统的可扩展性和可维护性。以下是对前一张图描述的重构过程的详细阐述:
架构重构前的状况
- 核心业务渗透:业务逻辑分散在各个服务中,缺乏统一的聚合层。
- 业务耦合问题:由于缺乏清晰的界限,服务之间的耦合度高。
通过限界划分和领域建模实现分离
- 限界划分:明确系统的边界,为不同的业务领域建立独立的服务。
- 领域建模:通过建模来定义领域内的实体、值对象、聚合根等,以实现业务逻辑的封装。
基础设施层的依赖倒置
- 依赖倒置原则:基础设施层不依赖于上层的业务逻辑,而是业务逻辑依赖于基础设施层提供的抽象。
- 存储抽象:领域层不直接与存储系统(如ES或Redis)交互,而是通过基础设施层提供的接口。
重构前后的数据查询能力对比
- 重构前:缺乏实时查询能力,团队需要将数据拉取到本地进行缓存。
- 重构后:利用异步调用机制,实现数据的持久化,并对外提供高效的查询服务。
领域模型与代码模型映射
- 模型映射:领域模型与代码模型之间需要有明确的映射关系,以保证业务逻辑的正确实现和代码的可维护性。
通过上述的架构重构,系统不仅提高了模块化和解耦,还增强了可扩展性和可维护性。
图片
上图是领域模型与代码模型的映射。分层对应上一张图展现的架构,在Domain层,按照领域划分进行聚合分包。上图标蓝的Hoteltree就是前文提到的酒店聚合,在这一领域内进行功能划分。
领域驱动设计中的Domain Primitive(DP)概述
一、Domain Primitive(DP)简介
Domain Primitive(DP)是领域驱动设计(DDD)中的一个概念,它在Value Object(VO)的基础上进一步发展而来。DP不仅具备VO的不可变性(Immutable),还增加了有效性(Validity)和行为(Behavior)。
DP的核心特征
- 概念完整性:每个DP都代表一个完整的业务概念,具有明确的定义。
- 使用领域语言:DP使用业务领域内的原生语言,以提高概念的精确度。
- 最小业务单元:DP作为业务域的最小组成部分,可以组合构建更复杂的业务对象。
- 属性显式化:DP能够将隐式属性转化为显式,提高业务逻辑的透明度。
举例说明
以联系信息为例,传统的VO可能只包含电话号码,而DP则会将区号、国际来源等隐式属性显式化,以更全面地表达业务概念。
二、项目落地效果分析
1. 组织效率
- 资源集中:组织资源是否集中在核心业务领域。
- 沟通效率:是否能用统一的语言描述业务,提高会议效率。
- 领域知识沉淀:是否有人能成为领域专家,沉淀领域知识。
- 职责明确:减少团队间职责模糊,降低内部冲突。
2. 开发效率
- 模块粒度:模块大小是否合适,模块间依赖是否健康。
- 接口稳定性:接口数量是否稳定,避免膨胀。
- bug减少:减少因功能理解不足导致的bug。
- 自测性:模块和接口的自测性高,提高开发效率。
- 代码可读性:代码易于理解,便于人员交接和新人上手。
3. 效率之本与产品分担
- 领域清晰:明确核心子域,重点投入。
- 统一语言:减少沟通成本,培养研发业务专家。
- 需求承接:承接大部分产品需求,助力产品管理。
- 微服务优化:通过DDD领域划分,减少微服务数量。
- 响应效率提升:开发工时短的产品响应效率显著提升。
- 架构优化:通过架构和功能分类,加快新人上手速度。
三、思维模型的改变
通过DP的应用,团队的思维模式也会发生改变,更加注重业务概念的完整性和精确性,从而提高整体的业务理解和开发效率。
四、总结
DP作为领域驱动设计中的一个高级概念,通过其概念完整性、使用领域语言、最小业务单元的特性,以及将隐式属性显式化的能力,为软件开发带来了更高的效率和更好的业务理解。
技术人员的业务转型与数字化实践
技术人员在业务转型中扮演着重要角色,从被动了解业务到主动参与业务策略的解读和数字化方案的提议。产品经历的核心价值在于成为技术与业务的桥梁,实现产研融合。
一、问题域分析与领域建模
- 分治思维:将复杂问题分解为更小的、更易于管理的部分。
- 模型思维:构建模型来模拟和理解业务流程和逻辑。
- 抽象思维:提取关键概念,忽略非关键细节。
- 结构化思维:以系统化的方式组织和分析问题。
二、模型实现
- 简单思维:追求简洁,避免不必要的复杂性。
- 契约思维:明确各部分之间的责任和接口。
- 解耦思维:减少模块间的依赖,提高系统的灵活性和可维护性。
三、DDD的优势与劣势
优势
- 隐性知识显性化:统一团队语言,提高沟通效率。
- 业务变化隔离:围绕业务变化,隔离“变化”,保持系统的稳定性。
- 积木式组合:业务演进像搭积木一样灵活组合。
- 关注点分离:隔离技术细节,专注于业务逻辑。
- 面向测试、运维:提高系统的可测试性和可维护性。
- 业务思维:技术人员主动思考业务,提出创新想法。
劣势
- 上手门槛:团队成员需要时间理解和掌握DDD的概念。
使用建议
- 业务场景复杂:适用于业务逻辑复杂、需要高度模块化的场景。
- 业务变化频繁:能够快速适应业务变化,保持系统的灵活性。
- 核心业务领域:重点领域需要更精细的管理和优化。
- 部分取用:可以只采用DDD的部分思想,如分层、聚合等。
- 团队共识:确保团队对DDD有共同的理解和认识。
四、业务架构与技术架构
业务架构是领域的核心,技术架构是支撑业务的容器。没有业务灵魂的技术架构是缺乏意义的。
五、Q&A
Q1:DDD重构时,如何协调产品上线需求的矛盾?
A1:在DDD重构过程中,我们依托公司技术中心的战略支持。面对产品上线需求的矛盾,可以选择“绞杀者”模式,即在不影响现有业务的基础上,另起炉灶进行优化重构。
Q2:选择COLA架构作为DDD重构业务模型的原因是什么?
A2:选择COLA架构的原因包括:
- 阿里开源,有大厂背书,信任度高。
- COLA具备优秀的分层架构和规范,提供了丰富的最佳实践。
- 对于初期不熟悉DDD的团队,可以直接参考官方demo,将其应用到自己的业务中,后期再进行个性化优化。
作者介绍
- 李全党:2021年加入去哪儿网,担任酒店供应链代理商和基础信息业务负责人,拥有超过10年的系统研发和软件架构设计经验,主导多个DDD项目。
- 朱浩曼:2021年9月加入去哪儿网,担任标准代理商业务负责人,专注于业务架构的优化和实践。
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/geek001/post/20240730/%E5%8E%BB%E5%93%AA%E5%84%BF%E7%BD%91%E6%9E%B6%E6%9E%84%E6%BC%94%E8%BF%9B%E4%B9%8B%E8%B7%AF%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%B0%BD%E5%A4%B4%E5%8E%9F%E6%9D%A5%E6%98%AFDDD--%E7%9F%A5%E8%AF%86%E9%93%BA/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com