博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DDD领域模型企业级系统(一)
阅读量:4885 次
发布时间:2019-06-11

本文共 3740 字,大约阅读时间需要 12 分钟。

领域模型的基本构造块:

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());     }

 

转载于:https://www.cnblogs.com/sunliyuan/p/6389224.html

你可能感兴趣的文章
大象的崛起!Hadoop七年发展风雨录
查看>>
图片二值化
查看>>
数据库常用函数
查看>>
集合之TreeSet(含JDK1.8源码分析)
查看>>
C语言学习的记忆
查看>>
Lucene学习总结之三:Lucene的索引文件格式(1) 2014-06-25 14:15 1124人阅读 ...
查看>>
node-sass 报错的解决方法
查看>>
Python:GeoJson格式的多边形裁剪Tiff影像并计算栅格数值
查看>>
免费下载知网文献的方法 | sci-hub免费下载SCI论文方法
查看>>
测试用例,变量之间,相互调用的方法,和修改原来初始化变量的方法
查看>>
ASP.NET MVC中将控制器分离到类库的实现(转)
查看>>
Poj 2304 Combination Lock(模拟顺、逆时钟开组合锁)
查看>>
Palindrome Number
查看>>
H5上传功能
查看>>
PHP命名空间(Namespace)的使用详解
查看>>
java项目@override报错问题
查看>>
DataTable 和Json 字符串互转
查看>>
Django中Template does not exit
查看>>
Redis安装 java中的连接 序列化 反序列化
查看>>
hdu 1896 优先队列的应用
查看>>