gpt4 book ai didi

java - Builder Factory 返回不同的子接口(interface)

转载 作者:行者123 更新时间:2023-11-30 08:46:29 25 4
gpt4 key购买 nike

我知道在 stack overflow 上有很多与此相关的变体和相关主题,但我没有找到任何令人信服的答案,所以我会自己试一试。

我正在尝试设计一个返回通用构建器接口(interface)的不同子类的构建器工厂。我想让所有的实现共享一个通用的抽象类以供代码重用。

请注意,我对 build() 方法的返回类型不感兴趣,我只对构建器的类型感兴趣。

这是我目前所拥有的:

具有子接口(interface)通用性的构建器接口(interface):

interface FruitBuilder<T extends FruitBuilder<T>> {
T taste(String taste);
T shape(String shape);
T weight(String weight);

Fruit build();
}

一些构建器有额外的方法:

interface GrapesBuilder extends FruitBuilder<GrapeBuilder> {
GrapesBuilder clusterSize(int clusterSize);
}

接下来是指定返回特定构建器的工厂:

interface FruitBuilderFactory {
GrapesBuilder grapes();
AppleBuilder apple();
LemonBuilder lemon();
}

这些接口(interface)的用户应该能够像这样使用它:

 Fruit grapes = fruitBuilderFactory
.grapes()
.weight(4)
.color("Purple")
.clusterSize(4) // Note that the GrapesBuilder type must be accessible here!
.build();

大部分逻辑将进入抽象类,包括高级构建逻辑:

abstract class BaseFruitBuilder<T extends FruitBuilder<T>> implements FruitBuilder<T> {

String taste;

T taste(String taste) {
this.taste = taste;
return (T)this; // Ugly cast!!!!!
}

...

Fruit build() {
Fruit fruit = createSpecificInstance();

// Do a lot of stuff on the fruit instance.

return fruit;
}

protected abstract Fruit createSpecificInstance();
}

有了基类,实现新的构建器真的很简单:

class GrapseBuilderImpl extends BaseFruitBuilder<GrapesBuilder> {
int clusterSize;
GrapesBuilder clusterSize(int clusterSize) {
this.clusterSize = clusterSize;
}

protected Fruit createSpecificInstance() {
return new Grape(clusterSize);
}
}

这一切都是编译好的(至少是我的真实代码)。问题是我是否可以在抽象类中删除对 T 的丑陋转换。

最佳答案

避免转换的一个选项是定义一个返回 T 的单一抽象方法:

abstract class BaseFruitBuilder<T extends FruitBuilder<T>> implements FruitBuilder<T> {

String taste;

T taste(String taste) {
this.taste = taste;
return returnThis();
}

protected abstract T returnThis();

//...
}

class GrapseBuilderImpl extends BaseFruitBuilder<GrapesBuilder> {
//...
@Override
protected T returnThis() {
return this;
}
}

缺点是您必须信任每个子类才能正确实现该方法。再一次,用你的方法,没有什么能阻止任何人声明一个子类 GrapesBuilder extends BaseFruitBuilder<AppleBuilder> ,因此您需要在某种程度上信任子类。

编辑 刚刚意识到这个解决方案被@user158037 的comment 引用了.我自己用过这个,但从来没有意识到这是一个众所周知的习语。 :-)

关于java - Builder Factory 返回不同的子接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32849499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com