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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

逻辑建模与物理建模_架构层和建模域逻辑

發布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 逻辑建模与物理建模_架构层和建模域逻辑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

邏輯建模與物理建模

在討論用于建模域邏輯(例如事務腳本,表模塊,域模型)的PoEAA模式時,我注意到人們對域模型模式是最好的印象(盡管印象不對)。 因此,他們開始將其應用于所有內容。

不配領域模型模式

讓我們成為現實。 大多數子系統都是基于CRUD的。 系統的僅特定部分需要域模型實現模式。 或者,換句話說,應用程序的某些部分僅需要數據上的表格和一些驗證邏輯(例如,必填/必填字段,數字的最小/最大值,文本的最小/最大長度)。 對于這些,領域模型是不值得的。

對于這些,也許貧血領域模型會很好地適合。

貧血領域模型并不像聽起來那樣糟糕

貧血領域模型并不像聽起來那樣糟糕。 在那兒,我說了(至少在我的博客文章中如此)。

但是看起來怎么樣?

package com.acme.bc.domain.model; ... @Entity class Person {@Id ... private Long id;private String firstName;private String lastName;// ...// getters and setters } ... interface PersonRepository /* extends CrudRepository<Person, Long> */ {// CRUD methods (e.g. find, find/pagination, update, delete) }package com.acme.bc.infrastructure.persistence; ... class PersonRepositoryJpa implements PersonRepository {... }

在表示層中,控制器可以訪問存儲庫。 該存儲庫負責提取持久性詳細信息。

package com.acme.bc.interfaces.web;@Controller class PersonsController {private PersonRepository personRepository;public PersonsController(PersonRepository personRepository) {...}// ... }

在這種情況下,將Person類暴露給表示層是完全可以的。 表示層可以直接使用它,因為它具有一個公共的零參數構造函數,獲取器和設置器,而視圖很可能需要這些構造器。

那里有。 一個簡單的基于CRUD的應用程序。

您還需要服務層嗎? 否。您還需要DTO (數據傳輸對象)嗎? 不需要。在這種簡單的CRUD情況下,您不需要其他服務或DTO 。

是的,此Person看起來像域實體。 不過,這并不包含邏輯,并且只是用來傳輸數據。 因此,它實際上只是一個DTO。 但這沒關系,因為它可以完成保存持久性存儲和檢索的數據的工作。

現在, 如果業務邏輯開始變得更加復雜,則最初貧乏的領域模型中的某些實體可能會變得更加富有行為。 如果是這樣的話,這些實體可以值得一個領域模型模式。

貧血領域模型的替代品

作為貧血領域模型(如上所述)的替代方法,可以將這些類移出領域邏輯層并移入表示層。 而不是命名
PersonRepository ,現在命名為
PersonDao 。

package com.acme.bc.interfaces.web;@Entity class Person {...}@Controller class PersonsController {private PersonDao personDao;public PersonsController(PersonDao personDao) {...}// ... }interface PersonDao /* extends CrudRepository<Person, Long> */ {// CRUD methods (e.g. find, find/pagination, update, delete) }package com.acme.bc.infrastructure.persistence;class PersonDaoJpa implements PersonDao {... }

太多分層

我認為,如果您必須通過不增加價值的強制性應用程序服務,那將是一個過大的殺傷力。

package com.acme.bc.interfaces.web; ... @Controller class PersonsController {private PersonService personService;public PersonsController(PersonService personService) {...}// ... }package com.acme.bc.application; ... @Service class PersonService {private PersonRepository personRepository;public PersonService(PersonRepository personRepository) {...}// expose repository CRUD methods and pass to repository// no value add }

將存儲庫保留在domain.model包中。 將存儲庫實現放置在另一個包中(例如, infrastructure.persistence )。 但為什么?

domain.model包是定義存儲庫的位置。 域模型中的元素指示存儲庫接口定義中需要哪些方法。 因此,存儲庫定義放置在domain.model包中。 存儲庫實現需要遵循添加的新方法(或刪除未使用的方法)。 此包裝遵循依賴關系反轉原理。 infrastructure.persistence程序包取決于domain.model程序包,而不是相反。

交易申請服務

那么,什么時候應用服務合適? 應用程序服務負責驅動工作流程和協調事務管理(例如,通過使用Spring中的聲明性事務管理支持)。

如果您發現簡單的CRUD應用程序需要在表示層控制器中啟動事務,那么將它們移至應用程序服務中可能是一個好兆頭。 當控制器需要更新多個不具有單個根的實體時,通常會發生這種情況。 這里通常的示例是在銀行帳戶之間轉移金額。 需要進行交易以確保借方和貸??方都成功或都失敗。

package sample.domain.model; ... @Entity class Account {...} ... interface AccountRepository {...}package sample.interfaces.web; ... @Controller class AccountsController {private AccountRepository accountRepository;...@Transactionalpublic ... transfer(...) {...} }

如果看到了這一點,那么最好將其(從表示層)移至應用程序層服務。

package sample.interfaces.web; ... @Controller class AccountsController {private AccountRepository accountRepository;private TransferService transferService;...public ... transfer(...) {...} }package sample.application; ... @Service @Transactional class TransferService {private AccountRepository accountRepository;...public ... transfer(...) {...} }package sample.domain.model; ... @Entity class Account {...} ... interface AccountRepository {...}

復雜邏輯的域模型模式(僅)

我將以重復輸入記帳為例。 但我敢肯定,還有更適合的復雜邏輯。

假設我們將日記帳分錄和科目建模為域實體。 該帳戶包含余額(金額)。 但這并不是一個簡單的設定。 需要創建日記帳分錄。 過帳日記帳分錄時,它將影響指定的帳戶。 然后,該帳戶將更新其余額。

package ….accounting.domain.model; ... /** Immutable */ @Entity class JournalEntry {// zero-sum items@ElementCollectionprivate Collection<JournalEntryItem> items;... } ... /** A value object */ @Embeddable class JournalEntryItem {...} ... interface JournalEntryRepository {...} ... @Entity class Account {...} ... interface AccountRepository {...} ... @Entity class AccountTransaction {...} ... interface AccountTransactionRepository {...}

現在,在這種情況下,一個簡單的實現將有一個表示層控制器創建一個日記帳分錄對象,并使用一個存儲庫來保存它。 并且在某個時間點(或如果使用自動過賬),將創建相應的帳戶交易,并更新帳戶余額。 所有這些都需要匯總成一個事務(即全有或全無)。

同樣,此事務理想地移至應用程序服務。

package ….accounting.application;@Service @Transactional class PostingService {...}

如果需要允許用戶瀏覽日記帳分錄和帳戶交易,則表示層控制器可以直接使用相應的存儲庫。 如果域實體不適合于視圖技術(例如,它不遵循JavaBean命名約定),則表示層可以定義適合于視圖的DTO。 小心! 不要僅僅為了滿足表示層的需求而更改域實體。

package ….interfaces.web;@Controller class AccountsController {private AccountRepository accountRepository;private AccountTransactionRepository accountTransactionRepository;private PostingService postingService;... }

即將結束...

所以你有它。 希望這篇文章可以闡明何時(以及何時不)使用域模型模式。

現在我想我要感冒了。

翻譯自: https://www.javacodegeeks.com/2016/10/architectural-layers-modeling-domain-logic.html

邏輯建模與物理建模

總結

以上是生活随笔為你收集整理的逻辑建模与物理建模_架构层和建模域逻辑的全部內容,希望文章能夠幫你解決所遇到的問題。

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