DDD领域模型企业级系统(一)

网友投稿 248 2022-09-05

DDD领域模型企业级系统(一)

领域模型的基本构造块:

1.实体(Entity):有业务生命周期,使用标识进行跟踪。

2.值对象(Value Object):无业务生命周期,用来描述实体。

3.服务(Service):无状态的行为类型,表示某种能力。

4.聚合(Aggregate):

1).聚合是一簇相关联的对象,出于封装的目的,将这些对象作为一个单元(业务、持久化和并发)。

2).每个聚合都有一个边界和一个根。

3).边界定义了聚合中应该包含什么。

5.聚合根(Aggregate Root)

1).根是聚合中唯一允许被外部引用的元素,在聚合边界内,对象之间可以相互引用。

2).聚合根使用全局标识,由仓储负责其持久化相关的生命周期,实体使用局部标识,由聚合根负责其持久化生命周期。

6.仓储(Repository)

7.工厂(Factory)

聚合的一致性:

1).聚合内的一致性由聚合自身负责维护

2).跨聚合的一致性由服务负责维护

3).最终一致性

如何保证聚合的一致性:

1).对聚合内的任何修改都要经过聚合跟,聚合跟负责一致性检查。

2).聚合内除了聚合根之外的实体只能被临时使用。

3).值对象因为拥有了值语义,天生安全。

4).服务封装跨聚合的一致性职责。

聚合设计的两大准则:

1).聚合不要设计的过大,过大聚合很难保证强一致性

2).聚合与聚合之间不要通过引用的方式来关联,而应该通过ID关联,ID关联具有很好的性能和可伸缩性

3).聚合用来封装真正的不变性,而不是简单将对象组合到一起。

4).聚合之内实体的交互应该通过聚合根完成。

5).应该为一个聚合配备一个仓储。

6).不属于聚合的职责或聚合不具有完成职责所具有的所有信息时,应该交予服务完成或传递另一个聚合根作为参数。

7).聚合内不要依赖领域服务或仓储。

8).永远不要删除聚合根

定义一个接口:IAggreate

public interface IAggreate { }

Order类:

public class Order : IAggreate { public Guid id { get; set; } public DateTime datetime { get; set; } public decimal Total { get; set; } public OrderItem ordertime { get; set; } public void SetOrderTotal() { Total = this.ordertime.LineTotal * 5; } }

OrderItem订单聚合根:

public class OrderItem { public int Amount { get; set; } public decimal LineTotal { get; set; } public decimal getproductcurrentprice(Product product) { return product.UnitPrice; } public decimal PUnitPrice { get; set; } public void SetLineTotal() { LineTotal = PUnitPrice * Amount; } }

Product 产品表:

public class Product:IAggreate { public Guid id { get; set; } public string Name { get; set; } public decimal UnitPrice { get; set; } public decimal GetProductPrice() { return this.UnitPrice; } }

通过服务实现:

public class OPService { Product p = new Product(); Order order = new Order(); public void CreateOrder() { var punitprice = p.GetProductPrice(); //通过聚合跟赋值 order.ordertime.PUnitPrice = punitprice; } }

创建领域对象的方式:

1.直接实例化

2.采用工厂方法进行对象创建

什么时候采用工厂创建领域对象

1.创建领域对象过程复杂,减轻调用方的负担

2.保护领域层领域对象创建逻辑

对象生命周期:

仓储的作用和好处和好处:

1.维护领域对象集合以及状态

2.实现对领域对象的持久化

3.解耦领域对象和数据库,领域层保留仓储的接口,实现领域模型的纯净话

4.可以随时替换仓储的实现,便于单元测试

5.工厂和仓储是都是针对聚合根的

6.一般在应用服务中使用仓储,不建议在领域服务和领域对象中使用仓储,如果必要,则在构造函数中传入仓储接口

代码:

Order类:

///

/// 不允许外部访问 /// public Guid ID { get; private set; } public DateTime DateTime { get; private set; } public string OrderSO { get; private set; } //产品信息 public ProductInfo Product { get; private set; } public Order(string orderso, ProductInfo product) { ID = Guid.NewGuid(); DateTime = DateTime.Now; Product = product; } /// /// 创建工厂 /// public static Order CreateFactory(Guid productid) { string orderso = OrderSOService.ProcessOrderNO(); ProductInfo product = (new ProductInfo()).GetProductInfoByKey(productid); return new Order(orderso, product); }

产品类:

public class ProductInfo { public Guid ID { get; set; } public string ProductName { get; set; } public decimal UnitPrice { get; set; } public ProductInfo GetProductInfoByKey(Guid key) { return this; } }

基础服务层:

public class OrderSOService { ///

/// 产生订单号 /// /// public static string ProcessOrderNO() { return "Orderso"; } }

服务层:

///

/// 服务层 /// public class Main { Order order = Order.CreateFactory(Guid.NewGuid()); }

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:ViewBag、ViewData和TempData的使用和区别
下一篇:ModelFirst的CRUD
相关文章

 发表评论

暂时没有评论,来抢沙发吧~