日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

领域Model?

發布時間:2024/9/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 领域Model? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

領域驅動設計里有很多東西,我們可以應用在各種各樣的開發模式里,所以接下來說的一些東西,我們可以部分使用。

說道領域驅動的領域,大家肯定就要開始說Bounded Context,聚合,聚合根,容易讓大家搞糊涂。 我覺得先拋開這些概念,后面再來說如何設計聚合,先簡單來說。

模型

過去,我們在多層設計里定義了很多Model, 數據庫的Model(DB Entity), 然后為了不依賴數據庫,我們有設計了業務的Domain Model, 同時我們又設計了ViewModel, 這樣一般也沒什么問題,職責也很清晰。但是有幾個問題

  • 我們要做很多的模型轉換,轉入轉出。當然我們可以用AutoMapper來但是AutoMapper的性能實在難以恭維,大家可以在網上搜索AutoMapper performance.
  • 領域模型成了一個單純的DTO了。
  • 領域模型

    首先我們要看領域,就是我們盡量把業務聚合到一個領域里,比如我們要做一個功能,可以看到用戶每一次的登錄日志,那個這個登錄日志其實就是屬于用戶這個領域里。

    其次我們看模型,原來我們的模型都是只有屬性,也就是貧血模型,貧血的意思就是沒有行為,像木乃伊一樣,但是實際上領域是我們要完成業務的最主要的地方,我們希望領域能夠自制,也就是領域自己管理自己。

    示例

    比如有一個Employee, 他的狀態有Active, Pending, DeActive, 業務上是Pending只能改為Active.

    1 2 3 4 5 6 7 8 9 10 public class Employee : Entity { public Name Name { get; set; } public EmployeeStatus EmployeeStatus { get; set; } }

    如果是貧血的Employee模型,我們往往代碼如下

    public class EmployeeService : IEmployeeService { private readonly IUnitOfWorkFactory _unitOfWorkFactory; private readonly IEmployeeRepository _employeeRepository; public EmployeeService(IUnitOfWorkFactory unitOfWorkFactory, IEmployeeRepository employeeRepository) { _unitOfWorkFactory = unitOfWorkFactory; _employeeRepository = employeeRepository; } public void ChangeStatus(EmployeeStatus status, Guid employeeId) { using (var unitOfWork = _unitOfWorkFactory.GetCurrentUnitOfWork()) { var employee = _employeeRepository.GetById(employeeId); employee.EmployeeStatus = status; unitOfWork.Commit(); } } }

    但是上面的代碼的問題就是領域沒有自治,本來修改我的狀態是我的事,你能不能修改,外面隨意修改我的狀態是很危險的,比如Pending狀態只能改為Active狀態。 所以如果不是貧血的模型,我們代碼就會這樣,讓領域自己來管理

    public class Employee : Entity { public UserId UserId { get; private set; } public EmployeeStatus EmployeeStatus { get; private set; } public void ChangeStatus(EmployeeStatus status) { if (this.EmployeeStatus == EmployeeStatus.Pending && status != EmployeeStatus.Active) { throw new Exception("Only can Active when status is pending"); } this.EmployeeStatus = status; } } public class EmployeeService : IEmployeeService { private readonly IUnitOfWorkFactory _unitOfWorkFactory; private readonly IEmployeeRepository _employeeRepository; public EmployeeService(IUnitOfWorkFactory unitOfWorkFactory, IEmployeeRepository employeeRepository) { _unitOfWorkFactory = unitOfWorkFactory; _employeeRepository = employeeRepository; } public void ChangeStatus(EmployeeStatus status, Guid employeeId) { using (var unitOfWork = _unitOfWorkFactory.GetCurrentUnitOfWork()) { var employee = _employeeRepository.GetById(employeeId); employee.ChangeStatus(status); unitOfWork.Commit(); } } }

    因此可以看出,我們把業務代碼盡量寫在領域里讓領域自治。

    后記

    其實領域驅動設計最難的就是設計領域(Domain), 也就是后面會說到的AggregateRoot 聚合,但是我想我們先讓領域不再貧血,這樣在傳統的多層設計,數據驅動等架構都可以使用這種模式。

    • 作者: 王德水
    • 出處:http://deshui.wang

    總結

    以上是生活随笔為你收集整理的领域Model?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。