cover_image

深入解析18种软件架构设计模式 (3)

TechLead TechLeadCloud
2024年11月28日 03:55

图片

第一篇,软件架构介绍、4C模型、客户端-服务端架构:深入解析18种软件架构设计模式 (1)

第二篇,软件分层架构、管道与过滤器架构、主从架构:深入解析18种软件架构设计模式 (2)

本篇介绍:微内核架构,领域驱动架构,基于组件的架构。

请关注博主,后续持续更新。

架构模式捕获了各类系统和软件要素的设计结构,使其可以被复用。在编写代码的过程中,开发者往往在项目内、公司内乃至职业生涯中多次遇到类似问题。通过创建设计模式,工程师们可以借助一种可复用的方法来解决问题,结构化地实现项目目标。

5. 微内核架构 Microkernel Architecture

微内核架构(Microkernel Architecture) ,又称为可插拔架构,是一种软件设计模式,旨在帮助开发者构建更模块化和灵活的系统。该架构将核心系统功能与其他功能分离开来,并通过独立的模块实现这些额外功能。系统的核心功能由微内核(Microkernel)实现,它是系统的最基本核心,仅提供运行系统所需的基础服务。这种架构理念可以看作一种 “即插即用”(Plug-and-Play) 的设计思路。

图片

示例:电子商务网站

以一个电子商务网站为例,微内核负责提供基础服务,例如用户身份验证、用户会话管理以及支付处理等。而其他功能,比如产品推荐、用户评论、社交媒体集成功能,则通过独立模块来实现。

如果网站需要添加一个新功能,比如会员积分计划,开发者可以将其作为一个独立的模块进行开发并添加进系统,而无需对系统的核心功能进行任何修改。这种模块化设计大大简化了新增或移除功能的流程,同时确保核心系统功能的稳定性。

灵活定制

此外,网站还可以根据不同用户的特定需求定制系统,仅选择适合每位用户的必要模块。例如,针对经常购买电子产品的用户,系统可以加载一个电子产品推荐模块;而对于经常购买化妆品的用户,则可以加载一个化妆品推荐模块。这种定制能力能够显著提升用户体验。

扩展性与可维护性

最后,当网站需要扩展系统以应对更多用户或底层硬件的变化时,可以根据需要轻松地添加或移除模块。这种扩展性使得系统能够快速适应用户需求的变化或硬件的升级改动。

6. 领域驱动架构 Domain-Driven Design, DDD

领域驱动设计(Domain-Driven Design, DDD) 是一种将软件开发与业务领域紧密结合的架构设计思想。其核心在于,软件架构的设计应以业务领域为中心,而非单纯追求技术实现。这种方法强调通过对业务领域的深入理解,提炼出领域的核心逻辑,以推动软件系统的高效设计和开发。

图片

领域驱动设计的关键特点

  1. 以领域为核心 DDD 的目标是确保软件系统能够真实地反映业务领域及其规则。开发者通过与领域专家密切协作,理解业务需求,提取核心概念,并将这些概念抽象为领域模型。这种专注于业务逻辑而非技术实现的方式,能够帮助团队开发出更贴合业务需求的系统。

  2. 跨领域知识共享 开发者不仅需要掌握技术知识,还需要深入了解领域知识(Domain Knowledge)。通过与领域专家沟通,开发团队能更准确地捕获业务规则和问题空间,从而避免由于对领域的误解而导致的软件设计偏差。

    领域建模与分解

DDD 强调对领域进行建模(Domain Modeling)。这是通过对领域的深入分析,将其分解为多个小型的、高度聚焦的子领域。这种分解使得复杂的问题可以被拆解为更易管理的部分,同时确保每个部分都能独立演进。

领域模型(Domain Model)是对领域内实体及其交互关系的抽象表示。领域模型不仅是开发过程中的一个技术文档,更是团队成员之间的沟通工具。通过领域模型,开发团队可以清晰地表达领域概念及其逻辑关系。

  1. 实体(Entities):在领域中具有唯一标识的对象。例如,电商系统中的“用户”或“订单”。

  2. 值对象(Value Objects):无需唯一标识的属性类对象,用于描述领域中的某些特性,例如“货币金额”或“地址”。

  3. 服务(Services):处理特定领域逻辑的无状态操作,不属于实体或值对象。例如,订单结算服务。

    限界上下文(Bounded Contexts)

限界上下文是 DDD 中的核心概念,用于定义领域模型的适用范围。一个限界上下文是一个独立的逻辑边界,内部使用统一的模型和语言。限界上下文之间通过清晰的接口进行交互,避免模型间的耦合。

  1. 统一语言(Ubiquitous Language):在每个限界上下文内,开发者和领域专家使用统一的术语描述业务逻辑和技术实现,消除团队间的语言鸿沟。

  2. 上下文映射(Context Mapping):用于描述不同限界上下文之间的关系,例如依赖关系、集成方式或数据流动。

    聚合(Aggregates)

聚合是 DDD 中管理复杂领域逻辑的一个重要工具。聚合是一组相关实体和值对象的集合,它们共同维护领域的一致性。每个聚合都有一个根实体(Aggregate Root),外部只能通过聚合根与聚合进行交互。

例如,在订单管理系统中,“订单”可以作为一个聚合,聚合内包含“订单明细”“支付信息”等子实体或值对象。通过限制外部对聚合内部的直接访问,可以保持系统的一致性和完整性。

领域驱动设计的优势

  1. 对复杂业务的精准建模 DDD 提供了一种框架,通过领域模型、限界上下文和聚合等概念,开发者能够更精确地捕捉和表达复杂的业务需求。

  2. 高内聚、低耦合 限界上下文和聚合的使用,使系统模块之间的依赖关系更清晰,从而实现高内聚和低耦合。这不仅提高了系统的可维护性,还为后续扩展提供了更大的灵活性。

  3. 跨团队的协作效率 通过统一语言,DDD 在开发团队和业务专家之间建立了桥梁。这种一致的语义模型,有助于减少误解,提高团队协作效率。

    实例:电子商务平台

图片

为了更直观地理解领域驱动设计,我们以电子商务平台为例。

问题领域(Problem Domain):

领域实体(Domain Entities):指软件应用程序所涉及的主题或问题空间。

1.    Customer(客户):表示一个注册用户,具有属性如姓名、邮箱和送货地址。
2. Order(订单):表示客户的购买请求,包含商品、数量和总价等信息。
3. Product(商品):表示可供销售的商品,具有名称、描述和价格等属性。

值对象(Value Objects):表示特性或属性,但没有唯一标识。

1.    Money(货币):表示金额,包括货币类型和金额数值。
2. Address(地址):表示一个物理位置,包括街道、城市、州和邮政编码等信息。

限界上下文(Bounded Contexts):

限界上下文定义了领域模型适用的明确边界。不同的上下文可能有各自的模型和术语,反映了整体领域的不同视角或子系统。

1.    订单管理上下文(Order Management Context):关注订单的创建、修改和履行。
2. 客户管理上下文(Customer Management Context):管理客户档案、身份验证和地址信息。

服务(Services):

服务封装领域逻辑,为领域模型提供具体功能支持。

1.    PaymentService(支付服务):管理支付处理及与外部支付网关的集成。
2. ShippingService(物流服务):处理订单的物流管理和追踪。

仓储(Repositories):

仓储负责领域模型中实体的持久化和检索。

1.    CustomerRepository(客户仓储):管理客户信息的存储与检索。
2. OrderRepository(订单仓储):负责订单数据的存储与检索。

7. 基于组件的架构 Component-Based Architecture, CBA

在软件工程中,基于组件的架构(Component-Based Architecture, CBA)是一种强调软件可重用性的设计与开发方法。其核心思想是通过将复杂系统拆分为更小、更易管理的组件,使软件开发变得更加高效和可控。

图片

什么是软件组件?

软件组件是模块化、独立的功能单元,可以在不同系统中重复使用。组件通常具备明确定义的接口,用于指定其他组件与其交互的方式。这些接口包括组件的输入、输出以及行为的描述。

基于其功能,组件可以被分类为以下类型:

  1. 用户界面组件(UI Components):处理用户界面展示与交互。

  2. 数据访问组件(Data Access Components):管理对数据库或其他存储系统的访问。

  3. 业务逻辑组件(Business Logic Components):实现具体的业务规则与操作。

每个组件都封装了特定的功能,并通过定义良好的接口与其他组件交互。这种架构在软件开发中推广了模块化设计、可重用性和灵活性。

基于组件架构的关键概念

组件(Components)

组件是独立的软件单元,封装了特定功能或服务。组件可以使用不同的编程语言和技术实现,只要遵循定义好的接口规范。组件之间通过接口进行交互,而不直接依赖于其他组件的内部实现,从而增强系统的灵活性和可维护性。

接口(Interfaces)

接口定义了组件与外部交互的契约或 API。接口规范包括方法、参数和数据结构的详细信息,明确了组件之间的通信规则。通过接口,组件能够解耦,实现独立开发与测试。

组件的组装(Composition)

组件可以通过静态组装(编译时绑定)或动态组装(运行时绑定)组合在一起,以构建更大的系统或应用程序。静态组装:组件之间的依赖关系在系统构建阶段明确。动态组装:组件在运行时被动态实例化和连接,允许系统根据需求实时调整。

重用(Reuse)

组件通过封装通用功能,实现跨应用或项目的代码重用。重用减少了开发时间和工作量,因为开发者可以直接使用现有组件,而无需从头开始构建所有功能。

实例:Java 企业版(Java EE)中的基于组件的架构

以下通过 Java EE 的 Web 应用程序,说明基于组件的架构如何应用于实际开发中:

组件(Components)

Servlets:处理 HTTP 请求并生成动态网页内容。

EJBs(Enterprise JavaBeans):提供业务逻辑和事务管理。

JSP(JavaServer Pages):用于生成 HTML 响应的模板。


接口(Interfaces)

Servlet API:定义了处理 HTTP 请求和响应的方法。

EJB 接口:指定调用业务方法的远程和本地接口。

JSP 标签库(Tag Libraries):定义标签和属性,用于在 HTML 页面中嵌入 Java 代码。

组件的组装(Composition)

Web 应用部署描述符(web.xml):指定 Servlets、过滤器及其他组件的配置和组合方式。

依赖注入(Dependency Injection,e.g., CDI):在运行时动态管理组件间的依赖关系。

重用(Reuse)

标准组件:Java EE 提供了如 Servlets、EJBs 和 JSP 的标准组件,可在不同的 Web 应用中重用。

自定义组件:开发者可以创建自定义组件(例如自定义 Servlet 或 EJB),并在多个项目中重复使用。

更多

请关注博主,后续持续更新


架构 · 目录
上一篇深入解析18种软件架构设计模式 (2)下一篇深入解析18种软件架构设计模式 (4)
继续滑动看下一个
TechLeadCloud
向上滑动看下一个