我有火箭课。我想通过生成器实例化一个火箭物体。我需要通过反应性存储库从数据库获取一些状态,但是反应性存储库返回Mono或Flux。如何使用Mono和Flux正确地向构建器注入状态。这是我尝试过的。
public class Rocket {
private String engine;
private String fuel;
public Rocket(Builder builder) {
engine = builder.getEngine();
fuel = builder.getFuel();
}
public static class Builder {
private String engine;
protected Mono<String> engineCollector;
private String fuel;
protected Mono<String> fuelCollector;
public Builder() {
}
protected Builder setEngine(Mono<String> engineCollector) {
this.engineCollector = engineCollector.doOnNext((collect) -> {
this.engine = collect;
});
return this;
}
private Builder setFuel(Mono<String> fuelCollector) {
this.fuelCollector = fuelCollector.doOnNext((collect) -> {
this.engine = collect;
});
return this;
}
public String getEngine() {
return this.engine;
}
public String getFuel() {
return this.fuel;
}
public Rocket build() {
return engineCollector
.flatMap(s -> fuelCollector)
.then(Mono.just(new Rocket(this)))
.block();
}
}
}这种方法是好的还是坏的,正确的方法是什么?
发布于 2022-03-18 05:43:03
将构建器与反应性API相结合的一种方法是:
Mono.just(Rocket.builder())
.flatMap(builder ->
engineCollector()
.map(builder::engine)
.thenReturn(builder)
)
.flatMap(builder ->
fuelCollector()
.map(builder::fuel)
.thenReturn(builder)
)
.map(builder -> builder.build());哪里
@Builder
class Rocket {
private String engine;
private String fuel;
}
Mono<String> engineCollector() {
...
}
Mono<String> fuelCollector() {
...
}发布于 2022-03-18 11:28:16
正如我在评论中所说的那样,试图将Mono转换成一种不属于反应型的东西,这与使用反应式编程是背道而驰的。
根据反应性范例,当您拥有Rocket和Mono<FuelTank>时,不应该尝试创建Mono<FuelTank>。相反,您应该创建一个Mono<Rocket>。
现在是代码(请注意,为了便于阅读,我将使用实际的标称类型,而不仅仅是字符串)。我个人更喜欢您描述的大多数情况下的Mono::zip操作。对于只有两个值的情况,甚至不需要构建器:
public class Rocket {
....
public Rocket(Engine engine, FuelTank fuel) {
....
}
....
}
Mono<Engine> engine = repo.getRocketEngine();
Mono<FuelTank> tank = repo.getRocketFuelTank();
Mono<Rocket> rocket = Mono.zip(engine, tank, Rocket::new);当你有两个以上的属性时,这会变得更复杂一些,但是仍然是非常有张力的。例如,考虑到火箭有三个部分:NoseCone、Engine和FuelTank,而不是两个部分。嗯,具有重写功能的Mono::zip 我们被覆盖了吗生成元组,具有最多八的特性。
Mono<NoseCone> cone = repo.getRocketNoseCone();
Mono<Engine> engine = repo.getRocketEngine();
Mono<FuelTank> tank = repo.getRocketFuelTank();
Mono<Tuple3<NoseCone, Engine, FuelTank>> builderStage1 = Mono.zip(cone, engine, tank);
Mono<Rocket> rocket = builderStage1.map(tuple -> {
NoseCone coneValue = tuple.getT1();
Engine engineValue = tuple.getT2();
FuelTank tankValue = tuple.getT3();
return Rocket.builder()
.engine(engineValue)
.fuel(tankValue)
.noseCone(coneValue)
.build();
});或者,为了缩短最后几行代码并去掉丑陋的长类型签名:
Mono<Rocket> rocket = Mono.zip(cone, engine, tank).map(tuple -> Rocket.builder()
.noseCone(tuple.getT1())
.engine(tuple.getT2())
.fuel(tuple.getT3))
.build()
);https://stackoverflow.com/questions/71512825
复制相似问题