[英]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.