From ad8f9f55ea79a4d587aecc69698808da82de3d62 Mon Sep 17 00:00:00 2001 From: somhairle Date: Tue, 21 Apr 2026 20:40:27 +0800 Subject: 二〇二六年四月二十一日 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...201\232\345\220\210\346\240\271\342\200\235.md" | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 "source/_posts/\351\242\206\345\237\237\351\251\261\345\212\250\350\256\276\350\256\241\344\270\255\347\232\204\342\200\234\350\201\232\345\220\210\346\240\271\342\200\235.md" (limited to 'source/_posts/领域驱动设计中的“聚合根”.md') diff --git "a/source/_posts/\351\242\206\345\237\237\351\251\261\345\212\250\350\256\276\350\256\241\344\270\255\347\232\204\342\200\234\350\201\232\345\220\210\346\240\271\342\200\235.md" "b/source/_posts/\351\242\206\345\237\237\351\251\261\345\212\250\350\256\276\350\256\241\344\270\255\347\232\204\342\200\234\350\201\232\345\220\210\346\240\271\342\200\235.md" new file mode 100644 index 00000000..19b5fc32 --- /dev/null +++ "b/source/_posts/\351\242\206\345\237\237\351\251\261\345\212\250\350\256\276\350\256\241\344\270\255\347\232\204\342\200\234\350\201\232\345\220\210\346\240\271\342\200\235.md" @@ -0,0 +1,65 @@ +--- +title: 领域驱动设计中的“聚合根” +date: 2025-03-13 16:00:12 +tags: [Technique] +--- + +在领域驱动设计(Domain-Driven Design,简称DDD)中,聚合根(Aggregate Root)是聚合(Aggregate)中的核心实体,是一个聚合的入口点和控制者,负责维护聚合内部的一致性和不变性条件。聚合是一组紧密相关的领域对象的集合,这些对象通过一定的业务规则绑定在一起,并被视为一个单元。 + +主要的作用如下: + +- 维护不变性:聚合根确保聚合内所有对象的一致性和不变性条件不被破坏。它负责封装与聚合相关的业务逻辑,保证聚合内的对象符合业务规则。 +- 管理生命周期:聚合根负责管理其内部对象的创建、修改和删除。它控制着聚合内部成员的生命周期,包括它们的创建、更新和删除。 +- 处理业务逻辑:聚合根负责处理与聚合相关的业务逻辑和操作,外部系统通过调用聚合根的方法来执行这些操作。它不仅是数据的容器,还负责封装与聚合相关的业务逻辑。 + +其具有以下特性: + +- 唯一入口:聚合根是聚合内部对象的唯一入口,外部系统只能与聚合根交互,而无法直接访问聚合内部的其他对象。这样可以避免外部系统直接修改聚合内的实体,确保聚合的一致性和业务逻辑的完整性。 +- 标识唯一性:每个聚合根都有一个全局唯一的标识符(ID),用以区分不同的聚合实例。 +- 事务边界:聚合根常常作为事务的边界,确保事务内的所有操作要么全部成功,要么全部失败,以此来维护数据的完整性。 + +用 F# 来描述,以订单管理为例,大概写一下: + +```fsharp +type OrderStatus = + | New + | Shipped + | Delivered + | Cancelled + +type OrderItem (productName: string, price: float, quantity: int) = + do + if quantity <= 0 then + failwith "Quantity must be positive" + + member public this.ProductName = productName + member public this.Price = price + member public this.Quantity = quantity + member public this.TotalPrice () = price * quantity + +type Order (id: int, customerName: string) = + let mutable status = OrderStatus.New + let mutable orderItems = [] + + member public this.Id = id + member public this.CustomerName = customerName + member public this.Status = status + member public this.OrderItems = orderItems + + member public this.AddItem (item: OrderItem, price: float, quantity: int) = + if quantity <= 0 then + failwith "Quantity must be positive" + + orderItems <- orderItems @ [OrderItem(item.ProductName, price, quantity)] + + member public this.ChangeStatus (status: OrderStatus) = + this.Status <- status + + member public this.TotalPrice () = + orderItems |> List.sumBy (fun item -> item.TotalPrice()) + + member public this.GetTotalPrice () = + orderItems |> List.sumBy (fun item -> item.TotalPrice()) +``` + +在这个例子中,`Order` 是聚合根,它通过 `AddItem` 方法来添加订单项,保证每个订单项符合业务规则。同时,聚合根 `Order` 还负责订单状态的管理,例如通过 `ChangeStatus` 方法来更新订单状态。`OrderItem` 是聚合内的一个实体,表示订单项,它通过 `GetTotalPrice` 方法来计算每个订单项的总价。外部系统只能通过 `Order` 聚合根来访问和操作订单项,而不能直接访问或修改 `OrderItem` -- cgit v1.2.3