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

領域設計之倉儲和工廠模式!

開發 前端
本文要講的倉儲模式就是用來解耦領域層和基礎層的,降低他們之間的耦合和相互影響。

?倉儲就類似于倉庫管理員,它是聚合的管理。

倉儲介于領域模型和數據模型之間:

  • 主要用于聚合的持久化和檢索。

它隔離了領域模型和數據模型,以便我們關注于領域模型而不需要考慮如何進行持久化。

為什么要用倉儲

解耦領域層和基礎層

DDD嚴格的分層架構告訴我們:

?

每一層只能與其下方的一層發生耦合。

因此用戶接口層只與應用層發生交互,應用層往下只與領域層發生交互,領域層往下只與基礎層發生交互。

在傳統的代碼分層結構Controller—Service—Dao結構中:

?

經常能看到在Service業務實現層的代碼中嵌入SQL,或者在其中頻繁出現修改數據對象并調用DAO的情況。

  • 這樣的話,基礎層的數據處理邏輯就滲透到了業務邏輯代碼中。

在DDD的分層結構中:

?

如果出現上述情況,則基礎層的數據處理邏輯就滲透到了領域層。

  • 領域層中的領域模型就難以聚焦在業務邏輯上,對外層的基礎層產生了依賴。

而一旦涉及到數據邏輯的修改,就要到領域層中去修改代碼。

本文要講的倉儲模式就是用來解耦領域層和基礎層的,降低他們之間的耦合和相互影響。

倉儲模式

倉儲模式包含倉儲接口和倉儲實現:

?

倉儲接口

  • 面向領域層提供基礎層數據處理相關的接口。

倉儲實現

  • 完成倉儲接口對應的數據持久化相關的邏輯處理。

一個聚合配備一個倉儲,由倉儲完成聚合數據的持久化。

  • 領域層邏輯面向倉儲接口編程,聚合內的數據持久化過程為DO(領域對象)轉PO(持久化對象)。

當需要更換數據庫類型,或者更改數據處理邏輯時:

?

我們就可以保持業務邏輯接口不動,只修改倉儲實現,保證了領域層業務邏輯和基礎層邏輯隔離。

倉儲的架構

倉儲要依賴數據庫、內存等具體的實現工具去做真正的持久化。

如下圖所示(圖中連線代表依賴關系):

我們可以把倉儲的行為抽象為基本的接口,然后利用控制反轉。

  • 把實現該節點的倉儲注入領域模型的運行態中。

實現了倒置依賴的依賴圖如下:

實現舉例

如下示例為一個訂單聚合中對訂單實體的倉儲模式實現。

訂單DO定義:

/**
 * 訂單聚合
 */
public class OrderDO {

    //訂單ID
    private long id;

    //訂單時間
    private long orderTime;
    
}

訂單PO定義:

/**
 * 訂單聚合的持久化PO
 */
public class OrderPO {

    //訂單ID
    private long id;

    //訂單時間
    private long orderTime;
}

倉儲接口定義:

/**
 * 訂單聚合倉儲接口
 */
public interface OrderRepository {

    /**
     * 添加訂單
     */
    void addOrder(OrderPO order);

    /**
     * 更新訂單
     */
    void updateOrder(OrderPO order);

    /**
     * 根據ID查找訂單PO對象
     */
    OrderPO findById(long id);
}

倉儲接口實現:

/**
 * 訂單倉儲實現
 */
public class OrderRepositoryImpl implements OrderRepository {

    @Resource
    private OrderDao orderDao;

    @Override
    public void addOrder(OrderPO order) {
        orderDao.addOrder(order);
    }

    @Override
    public void updateOrder(OrderPO order) {
        orderDao.updateOrder(order);
    }

    @Override
    public OrderPO findById(long id) {
        return orderDao.findById(id);
    }
}

訂單領域服務實現:

?

后面基礎層發生了變化,則領域層無需動任何代碼。

  • 只要倉儲接口不變,領域層的邏輯就可以一直保持不變,維護了領域層的穩定性。
/**
 * 定領域服務聚合類
 */
public class OrderDomainService {

    @Resource
    private OrderRepository orderRepository;

    public void addOrder(OrderPO order) {
        orderRepository.addOrder(order);
    }
}

Respository(倉儲)與DAO(數據訪問層)的區別

在理解了聚合之后,我們可以知道:

?

DAO 是技術手段,Respository是抽象方式。

DAO只是針對對象的操作,而Respository是針對 聚合 的操作。

DAO的操作方式如下:

?

訂單和和訂單明細都有一個對應的DAO。

訂單和訂單明細的關系并沒有在對象之間得到體現。

@Service
@Transactional
public class OrderService {
    public void createOrder(Order order, List<OrderDetail> orderDetailList) throws Exception {
        Long orderId = orderDao.save(order);
        for(OrderDetail detail : orderDetailList) {
            detail.setOrderId(orderId);
            orderDetailDao.save(detail);
        }
    }
}

Respository的操作方式如下:

// 訂單和訂單明細構成聚合
public class Order {
 List<OrderDetail> orderDetail;
 ...
}
@Service
@Transactional
public class OrderService {
    public void createOrder(Order order) throws Exception {
        orderRespository.save(order);
    }
}

StackOverFlow中有一個回答,講的很好:

?

https://stackoverflow.com/a/11384997

工廠模式

DO對象創建時,需要確保聚合根和它依賴的對象同時被創建。

?

如果這項工作交給聚合根來實現,則聚合根的構造函數將變得異常龐大。

所以把通用的初始化DO的邏輯,放到工廠中去實現。

?

通過工廠模式封裝聚合內復雜對象的創建過程,完成聚合根,實體和值對象的創建。

  • DO對象創建時,通過倉儲從數據庫中獲取PO對象,通過工廠完成PO到DO的轉換。

工廠中還可以包含DO到PO對象的轉換過程,方便完成數據的持久化。

/**
 * Order聚合的工廠
 * DO和PO的轉換
 */
public class OrderFactory {

    /**
     * OrderPO到領域對象的數據初始化
     */
    protected Order createOrder(OrderPO orderPO){
        Order order = new Order();
        order.setId(orderPO.getId());
        order.setOrderTime(orderPO.getOrderTime());
        return order;
    }

    /**
     * 領域對象到持久化對象PO的轉換
     */
    protected OrderPO createOrderPO(Order order){
        OrderPO orderPO = new OrderPO();
        orderPO.setId(order.getId());
        orderPO.setOrderTime(order.getOrderTime());
        return orderPO;
    }
    
}

參考資料:

  • 《基于DDD和微服務的中臺架構與實現》
  • 《架構真經》
  • 《領域驅動設計:軟件核心復雜性應對之道》
  • 《實現領域驅動設計》
責任編輯:姜華 來源: 月伴飛魚
相關推薦

2020-08-21 07:23:50

工廠模式設計

2011-11-17 16:03:05

Java工廠模式Clojure

2021-03-06 22:50:58

設計模式抽象

2010-04-19 09:30:00

工廠模式PHP設計模式

2009-01-15 10:55:29

JavaScript設計模式抽象工廠

2022-05-09 08:04:50

工廠模式設計模式

2020-08-11 11:20:30

Typescript設計模式

2011-07-28 09:50:58

設計模式

2019-08-16 10:46:46

JavaScript工廠模式抽象工廠模式

2022-01-12 13:33:25

工廠模式設計

2011-07-21 14:33:02

設計模式

2021-09-29 13:53:17

抽象工廠模式

2020-10-19 09:28:00

抽象工廠模式

2024-07-31 08:12:33

2013-11-26 16:29:22

Android設計模式

2010-10-09 09:25:35

Python工廠模式

2015-11-03 09:43:43

avascript設計模式工廠模式

2024-09-14 08:24:44

設計模式抽象工廠模式JDK

2023-03-27 00:20:48

2020-12-17 09:38:16

設計模式參數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美成人精品 | 91xxx在线观看| 久久免费精品 | 久久av.com| 日韩一区二区在线免费观看 | 亚洲视频中文字幕 | 狠狠色综合久久婷婷 | 国产精品福利在线 | 日日爱av| www精品 | 日本一区二区三区免费观看 | 日本一区二区三区免费观看 | 在线观看亚洲 | 欧美一级片在线看 | 午夜激情免费视频 | 台湾佬伊人 | 91中文字幕在线观看 | 欧美日韩专区 | 狠狠艹 | 欧美一级黄 | 国产高清精品一区二区三区 | 一区二区三区在线 | 国产毛片毛片 | 97精品超碰一区二区三区 | 色婷婷国产精品 | 中文字幕影院 | 曰韩三级| 日本天天操| 亚洲一区二区三区在线视频 | 男人天堂视频在线观看 | 亚洲精品无 | 日韩欧美中文 | 国产免费a| 亚洲精品一区二区三区在线观看 | 在线观看亚洲专区 | 国产精品久久久久9999鸭 | 欧洲视频一区二区 | av一区二区三区四区 | 欧美一级欧美三级在线观看 | 中文字幕免费视频 | 欧美一级大片 |