簡體   English   中英

域實體使用 Hibernate 實體?

[英]Domain entities using Hibernate entities?

在我目前在 Spring Boot 應用程序中與 DDD 的斗爭中,我陷入了僵局。 我知道我的域實體不應該與基礎設施層(Hibernate 實體所在的地方)有任何聯系。 當然,我的領域層依賴於 Hibernate 實體的數據來完成它的操作。

因此,在我的應用程序層,我的服務加載 Hibernate 實體並將其傳遞到域實體中。

這是我的域實體的示例:

package com.transportifygame.core.domain.objects;

import com.transportifygame.core.domain.OperationResult;
import com.transportifygame.core.domain.constants.Garages;
import com.transportifygame.core.domain.exceptions.garages.NotAvailableSpotException;
import com.transportifygame.core.infrastructure.entities.CompanyEntity;
import com.transportifygame.core.infrastructure.entities.GarageEntity;
import com.transportifygame.core.infrastructure.entities.LocationEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@RequiredArgsConstructor
@AllArgsConstructor

public class Garage {

    private GarageEntity garage;

    public static Integer getAvailableSlots(Garages.Size size) {
        switch (size) {
            case SMALL:
                return Garages.Slots.SMALL;
            case MEDIUM:
                return Garages.Slots.MEDIUM;
            case LARGE:
                return Garages.Slots.LARGE;
            case HUGE:
                return Garages.Slots.HUGE;
        }

        return 0;
    }

    public static Double getGaragePriceToBuy(Garages.Size size) {
        switch (size) {
            case SMALL:
                return Garages.Prices.BUY_SMALL;
            case MEDIUM:
                return Garages.Prices.BUY_MEDIUM;
            case LARGE:
                return Garages.Prices.BUY_LARGE;
            case HUGE:
                return Garages.Prices.BUY_HUGE;
        }

        return 0.0;
    }

    public static OperationResult<GarageEntity, Object> buy(
        Garages.Size size,
        CompanyEntity company,
        LocationEntity location
    ) {
        // As we had changed the company object, we have to refresh
        var newGarage = new GarageEntity();
        newGarage.setCompany(company);
        newGarage.setLocation(location);
        newGarage.setSize(size.ordinal());
        newGarage.setSlotsAvailable(Garage.getAvailableSlots(size));

        return new OperationResult<>(newGarage, null);
    }

    public static void hasAvailableSpot(GarageEntity garage) throws NotAvailableSpotException {
        if (garage.getSlotsAvailable() == 0) {
            throw new NotAvailableSpotException();
        }
    }

    public static OperationResult<GarageEntity, Object> addFreeSlot(GarageEntity garage) {
        garage.setSlotsAvailable(garage.getSlotsAvailable() - 1);

        return new OperationResult<>(garage, null);
    }

    public static OperationResult<GarageEntity, Object> removeFreeSlot(GarageEntity garage) {
        garage.setSlotsAvailable(garage.getSlotsAvailable() + 1);

        return new OperationResult<>(garage, null);
    }

}

現在的問題是,這是為域實體提供所需數據的正確方法嗎? 如果沒有,正確的方法是什么?

它是否使用工廠來構建基於休眠實體的域實體? 域實體應該反映休眠實體屬性嗎?

我也讀過一些人使用這種方法在 Hibernate 實體中添加域實體的邏輯,但我認為這不是正確的方法。

我建議您熟悉 DDD 存儲庫模式。 簡而言之,存儲庫應該模仿內存中的集合來檢索和存儲域對象。

因此,您最終可以通過兩種方式使用 hibernate 設計您的應用程序:

  1. 編寫一個高級存儲庫接口,為您的域實體公開“查找”、“保存”等。 存儲庫接口和返回的實體應該是“純域邏輯”。 也就是說:沒有持久性或休眠問題。 在您的情況下,它將是在那里實現的所有業務方法的Garage對象。 在存儲庫實現(可能駐留在另一個層/包中)中,您將處理休眠行表示(休眠實體)和實體管理器以完成接口的合同。 在您的情況下,這是Garage對象映射到(啞) GarageEntity並通過EntityManagerSession持久化的地方。

  2. 您可能會接受一些持久性/休眠泄漏到您的域中。 這將導致具有單個Garage域對象,該對象包含同一源文件(xml 可以是單獨的)上的所有業務邏輯和 hibernate/jpa 注釋(或 xml)。 在這種情況下,存儲庫可能是直接的 jpa 存儲庫實現。

在任何情況下,DDD 中的邏輯總是相同的:

在應用程序服務(一些GarageService - 用例的入口點)中,查詢存儲庫以獲取對其執行業務操作的域對象。 然后應用服務再次將修改后的實體存儲在存儲庫中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM