[英]What is the best practice to construct a Domain Object depending on external calls?
我正在嘗試構建一個從外部 API 獲取其數據的對象。 我將嘗試用一個例子來解釋它:
首先,我在我的 API 中獲得一個 POST 正文來創建一個對象:
class CarRequestBody {
private String colorId;
private String engineId;
//Constructors, etc.
}
然后有了這些信息,我需要構建 Car 的詳細實例。 從外部服務提供數據:
ColorDetails color = colorApiClient.getColor(colorId);
EngineSpecifications engine = engineApiClient.getEngine(engineId);
最后,我用所有這些信息構建了我的域對象。
所以我想知道構建實例的最佳實踐是什么。 我以3
種不同的方式思考過:
1 - CarService 中的方法如下:
public Car createCar(CartRequestBody body) {
ColorDetails color = colorApiClient.getColor(body.getColorId);
EngineSpecifications engine = engineApiClient.getEngine(body.getEngineId);
Car car = new Car(color, engine);
}
2 - 在構造函數中輸入數據:
public Car(CarRequestBody body) {
this.color = colorApiClient.getColor(body.getColorId);
this.engine = engineApiClient.getEngine(body.getEngineId);
}
3 - 在域類的吸氣劑中:
class Car {
private ColorData color;
private EngineSpecifications engine;
//Constructor
public ColorData getColor() {
if (color == null){
return colorApiClient.getColor(colorId);
}
return this.color;
}
....
}
這種情況有一些設計模式嗎?
我建議使用Builder設計模式。
在這里你可以看到代碼 -
public class Car{
private ColorDetails colorDetails;
private EngineSpecifications specifications;
private Car(CarBuilder builder){
this.colorDetails = builder.colorDetails;
this.specifications = builder.specifications;
}
public static class CarBuilder {
private ColorDetails colorDetails;
private EngineSpecifications specifications;
public CarBuilder withColor(ColorDetails colorDetails) {
this.colorDetails = colorDetails;
return this;
}
public CarBuilder withSpecifications(EngineSpecifications
specifications) {
this.specifications = specifications;
return this;
}
public Car build() {
Car car = new Car(this);
return car;
}
}
}
// 客戶端代碼
public class Client{
ColorDetails color = colorApiClient.getColor(colorId);
EngineSpecifications engine = engineApiClient.getEngine(engineId);
Car car = new Car.CarBuilder()
.withColor(color)
.withSpecifications(engine)
.build();
}
如果你的目標是保持你的設計干凈,你的域類Car
應該只知道它需要正常運行的對象,如ColorData
和EngineSpecificationsonly
。
將apiClient
注入Car
類不是一個好主意,因為它與它的功能無關,並且會增加耦合。
此外,如果 API 調用失敗怎么辦,您真的想將處理這種情況的管道代碼添加到構造函數中嗎?
同樣,我看不出定義一個期望CarRequestBody
的構造函數有什么好處。
最簡潔的方法是讓域類的構造函數保持簡單,並且不受不需要它們執行的對象的影響。 如果你想概括這些領域類的實例化過程,你可以引入實用方法來處理它。
一個簡單的構造函數會有什么問題? 我不知道 Java,但在 C# 中是這樣的:
class Car {
...
public Car(Color color, Engine engine) {
... // set properties with the parameters
}
}
哦,如果你想做一些解耦,請不要在你的域中使用與 API 中相同的對象。 所以你需要某種 Mapper 對象。
// 編輯
由於您使用的是請求,因此您可以創建一個 requesthandler 類。 如果您使用控制反轉或調解器,您可以通過這種方式將請求連接到處理程序。 所以你可以研究那些設計模式。 您還可以查看 Clean Architecture 以將您的域代碼與外部系統(在這種情況下為 API)分離
public CarRequestHandler : IRequestHandler<CarRequest> {
public CarRequestHandler(IColorRepository colorRepository, IEngineRepository engineRepository) {
this.colorRepo = colorRepository; //etc.}
public Handle(CarRequest request) {
// call repositories with the ids and create the domain object and stuff
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.