Java中的通用构建器
我为查找表创建了一个构建器并使用它,如下所示。
public class RaceCodeDataBuilder { private RaceCode raceCode; public RaceCodeDataBuilder() { raceCode = new RaceCode(); } public RaceCodeDataBuilder code(String code) { raceCode.setCode(code); return this; } public RaceCodeDataBuilder displayName(String displayName) { raceCode.setDisplayName(displayName); return this; } public RaceCode build() { return raceCode; } }
在测试中使用此构建器:
RaceCode mockRaceCode = new RaceCodeDataBuilder() .code("2054-5") .displayName("Black or African American") .build();
我期待更多类似的构建器用于其他查找表,例如StateCodeBuilder,GenderCodeBuilder,并且它们都只有“code”和“displayName”,类似于上面的构建器。
我想创建一个通用构建器,并避免创建几个使用不同名称执行相同作业的构建器类。
我尝试了一些仿制药,但我离开了…
public class CodeDataBuilder{ private T t; public CodeDataBuilder(T t) { this.t = t; } public CodeDataBuilder code(String code) { raceCode.setCode(code); // Cant write T.setCode here for obvious resons return this; } public CodeDataBuilder displayName(String displayName) { raceCode.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons return this; } public T build() { return t; } }
有人可以帮助我吗?
谢谢。
使用您需要的方法创建一个接口BuildableCodeData
,并使用类似RaceData
类来实现它。
您的代码将如下所示:
public interface BuildableCodeData { public void setCode(String code); public void setDisplayName(String name); } public class Builder { private T codeData; public Builder(T codeData) { this.codeData = codeData; } public Builder setCode(String code) { codeData.setCode(code); return this; } public Builder setDisplayName(String displayName) { codeData.setDisplayName(displayName); return this; } public T build() { return codeData; } }
它看起来更像你应该使用一个接口,只是让你的构建方法返回该接口。 例如:
public interface Buildable{ void setDisplayName(String name); void setCode(String code); } public class CodeDataBuilder { private Buildable mObj; public CodeDataBuilder(Buildable mObj) { this.mObj = mObj; } public CodeDataBuilder code(String code) { mObj.setCode(code); // Cant write T.setCode here for obvious resons return this; } public CodeDataBuilder displayName(String displayName) { mObj.setDisplayName(displayName); // Cant write T.setDisplayNamehere for obvious resons return this; } public Buildable build() { return mObj; } } }
然后只需使您想要构建的任何对象实现Buildable接口。
如果使用所需方法创建接口:
interface CodeModel { public void setCode(String s); public void setDisplayName(String s); }
然后,您可以要求您的generics类仅接受T extends CodeModel
,如下所示:
class CodeDataBuilder { // T has setCode method now! }
希望这可以帮助!
如果您具有某些标准函数的接口,则可以为其创建通用构建器。 基础构建器是抽象的,对于每个具体实现,都会有一个具体的构建器。
接口:
public interface CodeNameable { String getCode(); String getName(); }
具体实施:
public class CodeNamedCar implements CodeNameable { private String code; private String name; public CodeNamedCar(String code, String name) { this.code = code; this.name = name; } }
抽象生成器:
public abstract class CodeNameBuilder { public String code; public String name; public CodeNameBuilder() { } }
混凝土建造者
public abstract class CarBuilder extends CodeNameBuilder { public CarBuilder() { } public CarBuilder code(String co_de) { this.code = code; return this; } public CarBuilder name(String name) { this.name = name; return this; } public CodeNameCar build() { return (new CodeNameCar(code, name)); } }
然后你可以按照你的意愿使用它:
CodeNamedCar car = new CarBuilder().code("thecode").name("Mazda").build();
使用此设计,您需要在CodeNameCar
构造函数中检查每个字段的正确性(例如,非空和非空)。 还有其他方法可以设计它。
构建器模式即将创建一个新的类实例,并根据需要对其进行初始化。
在您前进的方式中,您倾向于使用部分属性的部分setter完成并创建可能的伪关系,因为两个对象具有相同的属性。
为了支持这一点,示例中的所有内容都有一个name属性,但是您没有创建一个名为Nameable
的超级接口,并在每个可能的位置实现它。
如果这些属性在您的类中共享,您应该考虑为它们创建一个类。
class Code { int number; String name; } class Race { Code code; //other attributes; }
然后你有一个代码生成器和另一个用于种族的构建器。
另请注意,良好的设计是权衡的平衡。 如果5个类共有两个字段,那么目的就是使代码变得复杂并创建一个专用的机制,它只能打包初始化,不会做任何有效的工作。