子类化构建器模式与Java中的扭曲
我想为抽象类创建一个抽象的构建器(虽然它不需要是抽象的),抽象类的每个子类都可以有自己的子类Builder。 我还希望每个字段/属性都填写AKA强制。 所以我使用带有扭曲的Builder Patter( https://blog.jayway.com/2012/02/07/builder-pattern-with-a-twist/ )。
我遇到了一个问题,这个问题在我之前提到的这个问题中得到了解决: 通用父对象不能作为没有强制转换的子项返回但是现在我无法创建多个具体/子类构建器。
最后我想实例化像这样的对象:
ConcreteBuilderA.getBuilder().setValue(Object value).setConcreteValue(int num).build()
其中setValue()属于AbstractBuilder,其他属于concreteBuilder。
我最好的镜头是(大大简化和抽象):
/** * @param the type of builded object it should return. * @param the type of the builder subclass. * @param the type of the linking interface. */ public abstract class AbstractBuilder implements ValueSetter { 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 implements ConcreteValueSetter { @Override public ConcreteBuilder setConcreteValue(int num) { //set value return this; } @Override public ConcreteProduct build(); { return buildable; } }
|
public interface ValueSetter { public L setValue(Object value); }
|
public interface ConcreteValueSetter { public ConcreteBuilder setConcreteValue(int num); }
如标记所示,这会在“切换”到子类构建方法时停止链。 我已经做了一些变种,我无法让它工作。
所以我真的很想知道这是否可行。 如果是的话,我想看看如何。 如果不是,我想知道一些符合我要求的技术。
提前致谢!
我在Federico Peralta Schaffner的帮助下找到了答案。 我很可能在我的真实项目中使构建器变得复杂。 所以这里是Builder-with-a-twist +inheritance的代码:
/** * * @param the type of the product. * @param the linking interface. */ public class AbstractBuilder implements ValueSetterOne, ValueSetterTwo { protected P toBeBuild; @Override public L setValueTwo(int value) { //set value return (L) this; } @Override public ValueSetterTwo setValueOne(int value){ //set value return this; }
|
public class ConcreteBuilder extends AbstractBuilder implements NameSetter, Optional{ public static ValueSetter getBuilder() { AbstractBuilder 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 { public ValueSetterTwo setValueOne(int value); }
|
public interface ValueSetterTwo { 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();
你的问题是懒惰编程技术的症状。 试试这个; 假装你是一名专业软件开发人员:
ConcreteBuilderA builder = ConcreteBuilderA.getBuilder(); ThingBeingBuilt thing; builder.setValue(value); builder.setConcreteValue(num); thing = builder.build()
- Hibernate Validator,自定义ResourceBundleLocator和Spring
- 从现有项目生成Maven POM?
- 使用TaskExecutor时数据插入问题
- Mysql驱动问题
- Map 的任何实现,即两个键?
- java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver在java中不再起作用。 如何解决这个问题?
- Java Graphics.drawImage()如何工作以及ImageObserver的作用是什么
- 使用用户界面(Swing)在Java上启动ServerSocket冻结
- 如何在spring-data-mongodb框架中将BigDecimal转换为Double