我想为抽象类创建一个抽象的构建器(虽然它不需要是抽象的),抽象类的每个子类都可以有自己的子类Builder。我还希望每个字段/属性都填写AKA强制。所以我使用Builder Pattern with Twist(https://blog.jayway.com/2012/02/07/builder-pattern-with-a-twist/)。
我遇到了一个问题,这个问题在我之前问过的这个问题中得到了解决:Generic parent object cannot be returned as child without cast 但是现在我无法创建多个具体/子类构建器。
最后,我想实例化像这样的对象:
ConcreteBuilderA.getBuilder().setValue(Object value).setConcreteValue(int num).build()
其中setValue()属于AbstractBuilder,其他属于concreteBuilder。
我最好的镜头是(大大简化和抽象化):
/**
* @param<B> the type of builded object it should return.
* @param<S> the type of the builder subclass.
* @param<L> the type of the linking interface.
*/
public abstract class AbstractBuilder<B extends AbstractClass, S extends AbstractBuilder, L> implements ValueSetter<L>
{
protected B buildable;
@Override
public L setValue(Object value)
{
//set the value
return this;//<-- returns Object, blocking the use of the ConcreteBuilder methods
}
public abstract B build();
}
|
public class ConcreteBuilder extends AbstractBuilder<ConcreteProduct, ConcreteBuilder, ConcreteValueSetter> implements ConcreteValueSetter
{
@Override
public ConcreteBuilder setConcreteValue(int num)
{
//set value
return this;
}
@Override
public ConcreteProduct build();
{
return buildable;
}
}
|
public interface ValueSetter<L>
{
public L setValue(Object value);
}
|
public interface ConcreteValueSetter
{
public ConcreteBuilder setConcreteValue(int num);
}
如标记所示,当切换&#39;到子类构建方法。 我已经为此做了一些变种,我无法让它发挥作用。
所以我真的很想知道这是否可行。如果是,我想看看如何。如果不是我想知道一些符合我要求的技术。
提前致谢!
答案 0 :(得分:1)
我在Federico Peralta Schaffner的帮助下找到了答案。 我很可能在我的真实项目中使构建器变得复杂。 所以这里是Builder-with-a-twist + inheritance的代码:
/**
*
* @param <P> the type of the product.
* @param <L> the linking interface.
*/
public class AbstractBuilder<P extends AbstractClass, L> implements ValueSetterOne<L>, ValueSetterTwo<L>{
protected P toBeBuild;
@Override
public L setValueTwo(int value) {
//set value
return (L) this;
}
@Override
public ValueSetterTwo<L> setValueOne(int value){
//set value
return this;
}
|
public class ConcreteBuilder extends AbstractBuilder<ConcreteClass, NameSetter> implements NameSetter, Optional{
public static ValueSetter<NameSetter> getBuilder()
{
AbstractBuilder<ConcreteClass, NameSetter> builder = new ConcreteBuilder();
builder.toBeBuild = new ConcreteClass();
return builder;
}
@Override
public Optional buildName(String name) {
this.toBeBuild.setCharacterName(name);
return this;
}
@Override
public ConcreteClass build() {
return this.toBeBuild;
}
@Override
public Optional addExtraObject(Object extra) {
System.out.println("test");
return this;
}
}
|
public interface ValueSetterOne<L> {
public ValueSetterTwo<L> setValueOne(int value);
}
|
public interface ValueSetterTwo<L> {
public L setValue(int value);
}
|
public interface NameSetter {
public Optional buildName(String name);
}
|
public interface Optional {
public ConcreteClass build();
public Optional addExtraObject(Object extra);
}
然后测试它:
ConcreteBuilder.getBuilder().setValueOne(0).setValueTwo(1).buildName("tricky").addExtraObject(args).build();
答案 1 :(得分:1)
您的问题是懒惰编程技术的症状。 试试这个;假装你是一名专业软件开发人员:
class MyComponent extends Component {
state = {
toggle: false
}
_fn1 = () => {
this.setState(previousState => ({
toggle: !previousState.toggle
});
}
render() {
const { toggle } = this.state;
return (
<button onClick={this.clickHandler}>
Turn me {toggle ? 'on' : 'off'}
</button>
);
}
}