1. 程式人生 > >DDD實戰進階第一波(五):開發一般業務的大健康行業直銷系統(實現產品上下文領域層)

DDD實戰進階第一波(五):開發一般業務的大健康行業直銷系統(實現產品上下文領域層)

討論 clas 基本 ted ctc decimal nco protect pan

從這篇文章開始,我們根據前面的DDD理論與DDD框架的約束,正式進入直銷系統案例的開發。

本篇文章主要講產品上下文中的領域層的主要實現,先簡單講下業務方面的需求:產品SPU與產品SKU,產品SPU主要是產品的名字和相關描述,

產品SKU包括產品SPU的多個規格,每個規格有不同的價格與PV值。從我們對DDD概念的理解,產品SPU與產品SKU屬於同一個聚合,產品SPU是聚合根。

技術分享圖片

產品上下文主要實現產品的上架功能,為了實現上架功能,我們首先要實現產品上下文的領域POCO模型與領域邏輯,

我們將產品的POCO模型與領域邏輯建立到一個叫Product.Domain的項目中。

產品SPU領域對象POCO代碼:

 public partial class ProductSPU : IAggregationRoot
    {
        [Key]
        public Guid Id { get; set; }
         public string Code { get; set; }
        public string ProductSPUName { get; set; }
        public string ProductSPUDes { get; set; }
        public List<ProductSKU> ProductSKUS { get
; set; } }

產品SKU領域對象POCO代碼:

public partial class ProductSKU : IEntity
    {
        public ProductSKU() { }
        [Key]
        public Guid Id { get; set; }
        public string Code { get; set; }
        public string Spec { get; set; }
        public Unit Unit { get; set; }
        
public decimal PV { get; set; } public decimal DealerPrice { get; set; } public byte[] Image { get; set; } public Guid ProductSPUId { get; set; } public string ProductSPUName { get; set; } }

從上面代碼可以看到,ProductSPU從聚合根接口繼承,ProductSKU從實體接口繼承,ProductSPU包含了一個ProductSKU的集合(也就是引用),這就代表它們同屬一個聚合,在具體使用EF Core做

持久化時,會作為一個事務統一持久化。

領域對象除了包含自身的屬性,也應該包括自身的業務邏輯,產品上架的功能比較簡單,業務邏輯也比較簡單,主要就是如何生成整個領域對象,以及聚合根與實體業務標識符Code的生成規則。

產品SPU領域對象業務邏輯代碼:

 public partial class ProductSPU
    {
        public ProductSPU CreateProductSPU(Guid id,string spuname,string spudesc,List<ProductSKU> productskus)
        {
            this.Id = id;
            this.Code = "Code " + spuname;
            this.ProductSPUName = spuname;
            this.ProductSKUS = productskus;
            this.ProductSPUDes = spudesc;
            return this;
        }
    }

產品SKU領域對象業務邏輯代碼:

 public partial class ProductSKU
    {
        public ProductSKU CreateProductSKU(string productspuname,Guid productspuid,
            byte[] image,decimal dealerprice,decimal pv,string unit,string spec)
        {
            this.Id = Guid.NewGuid();
            this.ProductSPUId = productspuid;
            this.Code = "Code " + productspuname + spec;
            this.ProductSPUName = productspuname;
            this.Image = image;
            this.DealerPrice = dealerprice;
            this.PV = pv;
            switch (unit)
            {
                case "":
                    this.Unit = Unit.盒;
                    break;
                case "":
                    this.Unit = Unit.包;
                    break;
                case "":
                    this.Unit = Unit.瓶;
                    break;
            }
            this.Spec = spec;
            return this;
        }
    }

我將領域對象的屬性與領域對象的邏輯分到不同的cs文件中,便於不同職責人開發與管理,而且采用相同的名稱空間和Partial關鍵字。

Product.Domain除了要實現領域邏輯之外,還要定義ProductSPU的倉儲接口、通過EF Core定義產品上下文與數據庫上下文之間的映射關系。

倉儲接口定義:

 public interface IProductRepository
    {
        void CreateProduct<T>(T productspu) where T : class, IAggregationRoot;

    }

從上面可以看到,這個接口其實就是定義了將ProductSPU這個聚合根持久化到數據庫與的接口。

產品上下文與數據庫上下文映射關系:

1.因為映射關系使用EF Core實現,未來可能被替換掉,所以先定義一個產品上下文接口:

public interface IProductContext
    {
    }

2.EF Core映射實現

 public class ProductEFCoreContext:DbContext,IProductContext
    {
        public DbSet<ProductSPU> ProductSPU { get; set; }
        public DbSet<ProductSKU> ProductSKU { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
        {
            optionBuilder.UseSqlServer("數據庫連接字符串");
        }

    }

3.使用EF Core工具生成數據庫腳本並更新數據庫,在生成腳本時,需要編輯項目文件,並采用EF Core Tools命令生成,這裏就不細講EF Core技術方面的內容。

到這裏,我們就基本實現了產品上下文的領域層,可以看到領域層主要是領域邏輯,定義了一個倉儲接口,將數據庫技術解耦,當然要定義領域對象與數據庫之間的映射關系,否則用例無法完成真正

對領域對象的持久化。

QQ討論群:309287205

DDD實戰進階視頻請關註微信公眾號: 技術分享圖片

DDD實戰進階第一波(五):開發一般業務的大健康行業直銷系統(實現產品上下文領域層)