成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

實現資源庫還沒找到稱手的家伙

開發 前端
UOW模式是在業務用例的操作中跟蹤對象的所有更改(增加、刪除和更新),并將所有更改的對象保存在一個列表中。在業務用例的終點,通過事務,一次性提交所有更改,以確保數據的完整性和有效性。總而言之,UOW協調這些對象的持久化及并發問題。

 ?[[357638]]?

本文轉載自微信公眾號「codeasy」,作者閻華。轉載本文請聯系codeasy公眾號。 

用UOW模式實現Repository

看了《無法實施富領域模型的罪魁禍首找到了》這一篇文章后,很多人都會問這種Repository是這么實現的。這種Repository的實現背后用了一個叫做 “Unit of Work (UOW)”的模式:

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.Unit of Work --Martin Fowler

UOW模式是在業務用例的操作中跟蹤對象的所有更改(增加、刪除和更新),并將所有更改的對象保存在一個列表中。在業務用例的終點,通過事務,一次性提交所有更改,以確保數據的完整性和有效性。總而言之,UOW協調這些對象的持久化及并發問題。

??

很多實現了UOW模式的框架都采用了保存快照的方式來跟蹤對象狀態的變化,如上圖所示,通過對比開始時對象的狀態和編輯后的對象的狀態,從而決定如何更新數據庫。這樣做的好處是可以增量按需更新。

重點是最后一次性保存變更,跟蹤對象狀態的變更不是必須的,我們看看IDDD_Sample是怎么實現的。

IDDD_Sample使用了LevelDB來存儲數據,以 agilepm.port.adapter.persistence.LevelDBSprintRepository 為例:

void save(Sprint aSprint, LevelDBUnitOfWork aUoW) {
LevelDBKey primaryKey = new LevelDBKey(PRIMARY, aSprint.tenantId().id(), aSprint.sprintId().id());
aUoW.write(primaryKey, aSprint);
}

其中 LevelDBUnitOfWork 的write方法是這么實現的:

public void write(LevelDBKey aKey, Object aValue) {
String serializedValue = this.serializer.serialize(aValue);
this.batch.put(aKey.keyAsBytes(), serializedValue.getBytes());
}

它把整個聚合序列化后存儲了。由于沒有跟蹤對象變更,所以也無法實現增量的更新,只能粗暴地用最新的聚合序列化后完全覆蓋之前的聚合存儲了。 但這種方式對我們大部分場景參考性不大,一個原因是我們最常用的還是關系型數據庫, 另一個原因是這種非增量的更新開銷還是比較大的。

合適的就是最好的,我有個朋友曾用MongoDB作存儲,使用了這樣的模式,效果很好,他所做的那個應用數據量不大,并發不高,用這種方式大大節約了開發和維護的成本。

那我們看看當使用關系型數據庫的時候有什么框架可以選擇。

使用JPA實現Repository

JPA (Java Persistence API) 是一個Java 持久化規范,最流行的一個實現是Hibernate,它可以大大簡化對數據庫的操作,然而,JPA在國內不受待見:


然而要實現UOW模式的Repository,使用JPA依然是最佳選擇,你幾乎不用自己做任何的工作,只要把聚合中的對象和表映射好就可以了。

JPA/Hibernate還提供了易用的樂觀鎖功能,在聚合根上維護一個樂觀鎖非常簡單

JPA/Hibernate在國內不受待見的一個重要原因,不是它不好用,而是太好用了——隱藏了很多實現細節有時候顯得不太靈活,提供了太多的高級功能用不好容易踩坑。

所以,使用JPA,請遵循以下幾點建議:

  • 只用它的功能的一個子集,比如要禁用Many-to-Many映射、禁用延遲加載的功能等;
  • 還記得之前關于CQRS這篇文章吧,很多查詢場景不需要聚合內的全部數據,所以,有些Query的實現,你完全可以不使用JPA,而是用原始的SQL去查,比如用JDBC或MyBatis;理解了CQRS,這些技術是可以很好地結合在一起使用的;
  • 確定你的聚合中的數據不需要分庫分表。即使你使用了Proxy模式的分庫分表中間件,使用JPA還是有問題的,這個以后專門寫一篇文章說說為什么有問題,以及如何解決這個問題;

嫌棄JPA不夠精簡的人很多,以至于Spring的官方推出了 Spring-Data-JDBC,一個專門為DDD的聚合存儲設計的ORM框架,它比JPA輕量很多,簡單很多,然而,為了輕量簡單,它也沒有對對象狀態修改進行跟蹤,所以在保存聚合的時候無法像JPA一樣按需更新數據庫,而是如IDDD_Sample一樣,粗暴地覆蓋更新,甚至會先刪除聚合下所有子實體后再重新插入(無論子實體數據有沒有變更),這可能會帶來不可控的性能問題。

如果我們又想用關系數據庫,又不能使用JPA,那還有別的辦法嗎?

自己寫代碼實現資源庫

前段時間我嘗試過一種方法:自己手寫Repository的實現,在聚合保存前,先從庫里load出來一個聚合,把這兩個聚合里的對象進行比較(diff),找出差異,生成操作數據庫的SQL語句,去增量更新數據庫。

這樣做的問題是需要寫很多的Repository代碼,而且很容易出錯也不容易維護,我試圖做一些抽象來簡化代碼,最后發現抽象越多越像JPA了。

這樣做還有一個問題是需要在保存前額外加載一次,如果想避免這個問題,可以看看《DDD之聚合持久化應該怎么做?| https://zhuanlan.zhihu.com/p/334344752》,但這種方法還是沒有避免需要寫很多代碼的問題。

自己編碼實現的好處是可控,比如容易處理分庫分表的問題。但實現起來太復雜,編寫和維護成本高,也容易出問題,這大大打擊了使用富領域模型的熱情。

總之,實現Repository,還沒有一件稱手的家伙。

再次審視端口適配器模型

前面我們提到過DDD提倡的六邊形模型,即端口適配器模型,Repository就是一個例子。比如接口 agilepm.domain.model.product.sprint.SprintRepository 這是一個接口,即所謂的端口,它和領域對象在同一個包里;而 agilepm.port.adapter.persistence.LevelDBSprintRepository這個實現是在另外的叫 adapter 的包下,這背后體現的是依賴倒置原則,這樣可以讓領域層和應用層不依賴于具體的技術實現。

Repository的實現只是一種adapter,下一篇我們講一講如何訪問另一個上下文中的服務,那本質上也是一種port/adapter,但有更多的不一樣的細節需要注意。

 

責任編輯:武曉燕 來源: codeasy
相關推薦

2011-03-17 09:38:16

OpenSUSE 11資源庫

2013-11-05 11:40:12

OS X MaveriOS X 10.9

2020-12-02 18:43:08

iOS 14資源庫蘋果

2021-06-02 08:25:44

性能優化Repository

2016-03-17 17:18:11

專家資源庫專家智造+

2015-08-12 09:33:57

開發人員PHP資源庫

2012-01-12 09:11:17

移動Web

2018-01-17 21:34:43

AI框架資源庫優點

2019-05-16 12:17:21

AndroidiOS蘋果

2023-11-09 22:22:12

2017-03-10 06:48:00

FacebookFaiss開源資源庫

2018-01-18 16:55:29

潤乾python

2018-03-15 14:53:24

潤乾python

2013-07-26 10:33:17

數據交易大數據云計算

2009-11-27 08:56:14

Windows 7附件

2022-05-19 23:45:34

Python開發

2011-06-13 10:10:58

2013-11-26 09:47:47

ORM

2021-11-15 18:19:24

工業互聯網安全

2023-05-08 15:55:16

MySQL數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜天堂精品久久久久 | 国产aaaaav久久久一区二区 | 国产xxx在线观看 | 九九久久国产 | 欧美精品在线免费观看 | 羞羞视频在线观免费观看 | 欧美在线观看网站 | 黄色毛片黄色毛片 | 中文字幕av一区 | 国产综合av | 色精品视频| 国产一区二区三区 | 91电影在线播放 | 久久激情视频 | 国产亚洲一区二区精品 | www.狠狠干 | 免费黄色a视频 | 国产成人亚洲精品 | 91成人免费 | 日韩一区二区三区在线看 | 日韩色图视频 | 91精品国产综合久久精品 | 久久久久免费精品国产 | 91电影| 精品免费 | 国产精品不卡视频 | 亚洲精品天堂 | 日本三级网站在线 | 欧美xxxx网站 | 欧美激情亚洲天堂 | 国产在线观看网站 | 成人精品免费视频 | 中文字幕日本一区二区 | 99精品视频一区二区三区 | 毛片免费看的 | 午夜一区二区三区视频 | 亚洲午夜在线 | 91精品久久久久久久久久入口 | 中文字幕一区二区三区精彩视频 | 免费成人在线网站 | 久草免费在线视频 |