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

領(lǐng)域設(shè)計(jì)之倉(cāng)儲(chǔ)和工廠模式!

開發(fā) 前端
本文要講的倉(cāng)儲(chǔ)模式就是用來(lái)解耦領(lǐng)域?qū)雍突A(chǔ)層的,降低他們之間的耦合和相互影響。

?倉(cāng)儲(chǔ)就類似于倉(cāng)庫(kù)管理員,它是聚合的管理。

倉(cāng)儲(chǔ)介于領(lǐng)域模型和數(shù)據(jù)模型之間:

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

它隔離了領(lǐng)域模型和數(shù)據(jù)模型,以便我們關(guān)注于領(lǐng)域模型而不需要考慮如何進(jìn)行持久化。

為什么要用倉(cāng)儲(chǔ)

解耦領(lǐng)域?qū)雍突A(chǔ)層

DDD嚴(yán)格的分層架構(gòu)告訴我們:

?

每一層只能與其下方的一層發(fā)生耦合。

因此用戶接口層只與應(yīng)用層發(fā)生交互,應(yīng)用層往下只與領(lǐng)域?qū)影l(fā)生交互,領(lǐng)域?qū)油轮慌c基礎(chǔ)層發(fā)生交互。

在傳統(tǒng)的代碼分層結(jié)構(gòu)Controller—Service—Dao結(jié)構(gòu)中:

?

經(jīng)常能看到在Service業(yè)務(wù)實(shí)現(xiàn)層的代碼中嵌入SQL,或者在其中頻繁出現(xiàn)修改數(shù)據(jù)對(duì)象并調(diào)用DAO的情況。

  • 這樣的話,基礎(chǔ)層的數(shù)據(jù)處理邏輯就滲透到了業(yè)務(wù)邏輯代碼中。

在DDD的分層結(jié)構(gòu)中:

?

如果出現(xiàn)上述情況,則基礎(chǔ)層的數(shù)據(jù)處理邏輯就滲透到了領(lǐng)域?qū)印?/p>

  • 領(lǐng)域?qū)又械念I(lǐng)域模型就難以聚焦在業(yè)務(wù)邏輯上,對(duì)外層的基礎(chǔ)層產(chǎn)生了依賴。

而一旦涉及到數(shù)據(jù)邏輯的修改,就要到領(lǐng)域?qū)又腥バ薷拇a。

本文要講的倉(cāng)儲(chǔ)模式就是用來(lái)解耦領(lǐng)域?qū)雍突A(chǔ)層的,降低他們之間的耦合和相互影響。

倉(cāng)儲(chǔ)模式

倉(cāng)儲(chǔ)模式包含倉(cāng)儲(chǔ)接口和倉(cāng)儲(chǔ)實(shí)現(xiàn):

?

倉(cāng)儲(chǔ)接口

  • 面向領(lǐng)域?qū)犹峁┗A(chǔ)層數(shù)據(jù)處理相關(guān)的接口。

倉(cāng)儲(chǔ)實(shí)現(xiàn)

  • 完成倉(cāng)儲(chǔ)接口對(duì)應(yīng)的數(shù)據(jù)持久化相關(guān)的邏輯處理。

一個(gè)聚合配備一個(gè)倉(cāng)儲(chǔ),由倉(cāng)儲(chǔ)完成聚合數(shù)據(jù)的持久化。

  • 領(lǐng)域?qū)舆壿嬅嫦騻}(cāng)儲(chǔ)接口編程,聚合內(nèi)的數(shù)據(jù)持久化過(guò)程為DO(領(lǐng)域?qū)ο螅┺D(zhuǎn)PO(持久化對(duì)象)。

當(dāng)需要更換數(shù)據(jù)庫(kù)類型,或者更改數(shù)據(jù)處理邏輯時(shí):

?

我們就可以保持業(yè)務(wù)邏輯接口不動(dòng),只修改倉(cāng)儲(chǔ)實(shí)現(xiàn),保證了領(lǐng)域?qū)訕I(yè)務(wù)邏輯和基礎(chǔ)層邏輯隔離。

倉(cāng)儲(chǔ)的架構(gòu)

倉(cāng)儲(chǔ)要依賴數(shù)據(jù)庫(kù)、內(nèi)存等具體的實(shí)現(xiàn)工具去做真正的持久化。

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

我們可以把倉(cāng)儲(chǔ)的行為抽象為基本的接口,然后利用控制反轉(zhuǎn)。

  • 把實(shí)現(xiàn)該節(jié)點(diǎn)的倉(cāng)儲(chǔ)注入領(lǐng)域模型的運(yùn)行態(tài)中。

實(shí)現(xiàn)了倒置依賴的依賴圖如下:

實(shí)現(xiàn)舉例

如下示例為一個(gè)訂單聚合中對(duì)訂單實(shí)體的倉(cāng)儲(chǔ)模式實(shí)現(xiàn)。

訂單DO定義:

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

    //訂單ID
    private long id;

    //訂單時(shí)間
    private long orderTime;
    
}

訂單PO定義:

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

    //訂單ID
    private long id;

    //訂單時(shí)間
    private long orderTime;
}

倉(cāng)儲(chǔ)接口定義:

/**
 * 訂單聚合倉(cāng)儲(chǔ)接口
 */
public interface OrderRepository {

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

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

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

倉(cāng)儲(chǔ)接口實(shí)現(xiàn):

/**
 * 訂單倉(cāng)儲(chǔ)實(shí)現(xiàn)
 */
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);
    }
}

訂單領(lǐng)域服務(wù)實(shí)現(xiàn):

?

后面基礎(chǔ)層發(fā)生了變化,則領(lǐng)域?qū)訜o(wú)需動(dòng)任何代碼。

  • 只要倉(cāng)儲(chǔ)接口不變,領(lǐng)域?qū)拥倪壿嬀涂梢砸恢北3植蛔儯S護(hù)了領(lǐng)域?qū)拥姆€(wěn)定性。
/**
 * 定領(lǐng)域服務(wù)聚合類
 */
public class OrderDomainService {

    @Resource
    private OrderRepository orderRepository;

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

Respository(倉(cāng)儲(chǔ))與DAO(數(shù)據(jù)訪問(wèn)層)的區(qū)別

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

?

DAO 是技術(shù)手段,Respository是抽象方式。

DAO只是針對(duì)對(duì)象的操作,而Respository是針對(duì) 聚合 的操作。

DAO的操作方式如下:

?

訂單和和訂單明細(xì)都有一個(gè)對(duì)應(yīng)的DAO。

訂單和訂單明細(xì)的關(guān)系并沒(méi)有在對(duì)象之間得到體現(xiàn)。

@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的操作方式如下:

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

StackOverFlow中有一個(gè)回答,講的很好:

?

https://stackoverflow.com/a/11384997

工廠模式

DO對(duì)象創(chuàng)建時(shí),需要確保聚合根和它依賴的對(duì)象同時(shí)被創(chuàng)建。

?

如果這項(xiàng)工作交給聚合根來(lái)實(shí)現(xiàn),則聚合根的構(gòu)造函數(shù)將變得異常龐大。

所以把通用的初始化DO的邏輯,放到工廠中去實(shí)現(xiàn)。

?

通過(guò)工廠模式封裝聚合內(nèi)復(fù)雜對(duì)象的創(chuàng)建過(guò)程,完成聚合根,實(shí)體和值對(duì)象的創(chuàng)建。

  • DO對(duì)象創(chuàng)建時(shí),通過(guò)倉(cāng)儲(chǔ)從數(shù)據(jù)庫(kù)中獲取PO對(duì)象,通過(guò)工廠完成PO到DO的轉(zhuǎn)換。

工廠中還可以包含DO到PO對(duì)象的轉(zhuǎn)換過(guò)程,方便完成數(shù)據(jù)的持久化。

/**
 * Order聚合的工廠
 * DO和PO的轉(zhuǎn)換
 */
public class OrderFactory {

    /**
     * OrderPO到領(lǐng)域?qū)ο蟮臄?shù)據(jù)初始化
     */
    protected Order createOrder(OrderPO orderPO){
        Order order = new Order();
        order.setId(orderPO.getId());
        order.setOrderTime(orderPO.getOrderTime());
        return order;
    }

    /**
     * 領(lǐng)域?qū)ο蟮匠志没瘜?duì)象PO的轉(zhuǎn)換
     */
    protected OrderPO createOrderPO(Order order){
        OrderPO orderPO = new OrderPO();
        orderPO.setId(order.getId());
        orderPO.setOrderTime(order.getOrderTime());
        return orderPO;
    }
    
}

參考資料:

  • 《基于DDD和微服務(wù)的中臺(tái)架構(gòu)與實(shí)現(xiàn)》
  • 《架構(gòu)真經(jīng)》
  • 《領(lǐng)域驅(qū)動(dòng)設(shè)計(jì):軟件核心復(fù)雜性應(yīng)對(duì)之道》
  • 《實(shí)現(xiàn)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)》
責(zé)任編輯:姜華 來(lái)源: 月伴飛魚
相關(guān)推薦

2020-08-21 07:23:50

工廠模式設(shè)計(jì)

2011-11-17 16:03:05

Java工廠模式Clojure

2021-03-06 22:50:58

設(shè)計(jì)模式抽象

2010-04-19 09:30:00

工廠模式PHP設(shè)計(jì)模式

2009-01-15 10:55:29

JavaScript設(shè)計(jì)模式抽象工廠

2020-08-11 11:20:30

Typescript設(shè)計(jì)模式

2022-05-09 08:04:50

工廠模式設(shè)計(jì)模式

2011-07-28 09:50:58

設(shè)計(jì)模式

2019-08-16 10:46:46

JavaScript工廠模式抽象工廠模式

2022-01-12 13:33:25

工廠模式設(shè)計(jì)

2011-07-21 14:33:02

設(shè)計(jì)模式

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設(shè)計(jì)模式

2010-10-09 09:25:35

Python工廠模式

2015-11-03 09:43:43

avascript設(shè)計(jì)模式工廠模式

2024-09-14 08:24:44

設(shè)計(jì)模式抽象工廠模式JDK

2023-03-27 00:20:48

2020-12-17 09:38:16

設(shè)計(jì)模式參數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: av中文字幕在线 | 艹逼网 | 国产精品久久久久久久久久三级 | 91精品国产91久久久久久密臀 | 97视频精品 | 国产一区91在线 | 在线播放国产一区二区三区 | 免费在线看黄视频 | 人碰人操 | 韩日一区二区三区 | 精品在线99| 国产在线中文字幕 | 亚洲乱码一区二区三区在线观看 | 亚洲欧美日韩电影 | 狠狠综合久久av一区二区老牛 | 一级做a爰片性色毛片16美国 | 中文字幕在线观看 | 欧美成人一区二区三区 | 国产一区免费 | av在线视| 国产精品99久久久久久动医院 | 精品毛片 | 99精品视频一区二区三区 | 国产东北一级毛片 | 久久99视频这里只有精品 | 亚洲狠狠| 精产国产伦理一二三区 | 日本不卡一区二区三区 | 国产精品日韩欧美一区二区三区 | 亚洲影音先锋 | 男人的天堂中文字幕 | 激情91 | 中文字幕av在线播放 | 狠狠躁18三区二区一区 | av一区二区三区四区 | 国产在线中文 | a在线免费观看视频 | 91精品久久久 | 国产黄色大片 | 一级欧美 | 人人爱干 |