[英]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 設計您的應用程序:
編寫一個高級存儲庫接口,為您的域實體公開“查找”、“保存”等。 存儲庫接口和返回的實體應該是“純域邏輯”。 也就是說:沒有持久性或休眠問題。 在您的情況下,它將是在那里實現的所有業務方法的Garage
對象。 在存儲庫實現(可能駐留在另一個層/包中)中,您將處理休眠行表示(休眠實體)和實體管理器以完成接口的合同。 在您的情況下,這是Garage
對象映射到(啞) GarageEntity
並通過EntityManager
或Session
持久化的地方。
您可能會接受一些持久性/休眠泄漏到您的域中。 這將導致具有單個Garage
域對象,該對象包含同一源文件(xml 可以是單獨的)上的所有業務邏輯和 hibernate/jpa 注釋(或 xml)。 在這種情況下,存儲庫可能是直接的 jpa 存儲庫實現。
在任何情況下,DDD 中的邏輯總是相同的:
在應用程序服務(一些GarageService
- 用例的入口點)中,查詢存儲庫以獲取對其執行業務操作的域對象。 然后應用服務再次將修改后的實體存儲在存儲庫中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.