首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带反应堆单体的建筑商模式

带反应堆单体的建筑商模式
EN

Stack Overflow用户
提问于 2022-03-17 13:06:04
回答 2查看 347关注 0票数 1

我有火箭课。我想通过生成器实例化一个火箭物体。我需要通过反应性存储库从数据库获取一些状态,但是反应性存储库返回Mono或Flux。如何使用Mono和Flux正确地向构建器注入状态。这是我尝试过的。

代码语言:javascript
复制
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();
    }
  }
}

这种方法是好的还是坏的,正确的方法是什么?

EN

回答 2

Stack Overflow用户

发布于 2022-03-18 05:43:03

将构建器与反应性API相结合的一种方法是:

代码语言:javascript
复制
Mono.just(Rocket.builder())
        .flatMap(builder ->
                engineCollector()
                        .map(builder::engine)
                        .thenReturn(builder)
        )
        .flatMap(builder ->
                fuelCollector()
                        .map(builder::fuel)
                        .thenReturn(builder)
        )
        .map(builder -> builder.build());

哪里

代码语言:javascript
复制
@Builder
class Rocket {
    private String engine;
    private String fuel;
}

Mono<String> engineCollector() {
...
}
    
Mono<String> fuelCollector() {
...
}
票数 2
EN

Stack Overflow用户

发布于 2022-03-18 11:28:16

正如我在评论中所说的那样,试图将Mono转换成一种不属于反应型的东西,这与使用反应式编程是背道而驰的。

根据反应性范例,当您拥有RocketMono<FuelTank>时,不应该尝试创建Mono<FuelTank>。相反,您应该创建一个Mono<Rocket>

现在是代码(请注意,为了便于阅读,我将使用实际的标称类型,而不仅仅是字符串)。我个人更喜欢您描述的大多数情况下的Mono::zip操作。对于只有两个值的情况,甚至不需要构建器:

代码语言:javascript
复制
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);

当你有两个以上的属性时,这会变得更复杂一些,但是仍然是非常有张力的。例如,考虑到火箭有三个部分:NoseConeEngineFuelTank,而不是两个部分。嗯,具有重写功能的Mono::zip 我们被覆盖了吗生成元组,具有最多八的特性。

代码语言:javascript
复制
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();
});

或者,为了缩短最后几行代码并去掉丑陋的长类型签名:

代码语言:javascript
复制
Mono<Rocket> rocket = Mono.zip(cone, engine, tank).map(tuple -> Rocket.builder()
    .noseCone(tuple.getT1())
    .engine(tuple.getT2())
    .fuel(tuple.getT3))
    .build()
);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71512825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档