【发布时间】:2017-04-24 04:06:20
【问题描述】:
问题
我想创建一个具有流利构建器的类,两者都可以继承和扩展。基类应该有所有公共和必填字段,子类应该有不同的可选字段
下面的简单示例(我能想到的最好、最简单的用例;p)
base: Animal
name
age
static Builder
impl: Snake extends Animal
length
static Builder extends Animal.Builder
impl: Spider extends Animal
numberOfLegs
static Builder extends Animal.Builder
我想以其中一种方式使用它(最喜欢的是第一种):
Spider elvis = Spider.name("elvis").age(1).numberOfLegs(8).build();
Spider elvis = Spider.builder().name("elvis").age(1).numberOfLegs(8).build();
Spider elvis = new Spider.Builder().name("elvis").age(1).numberOfLegs(8).build();
我想要实现的是
- 此构建器的用户必须提供一些最少的信息(这样系统才能正常工作),否则他将无法构建该对象
- 所有可选字段都可以声明,没有特定顺序,在必填字段之后
- 我可能需要为孩子添加一些必填字段,但只需更改构建器中调用的第一个方法即可轻松处理
- 我不想在这些类之外(这里:在 Main 中)进行任何强制转换,但我不介意在这段代码中(这里:在 Animal 或 Spider 中)
到目前为止,我失败了,如果您能帮我找到解决方法,我将不胜感激 :) 或者也许我应该考虑一种不同的方法?
我使用的最有价值的资源
http://blog.crisp.se/2013/10/09/perlundholm/another-builder-pattern-for-java
http://egalluzzo.blogspot.com/2010/06/using-inheritance-with-fluent.html
Generic fluent Builder in Java
到目前为止完成的工作
到目前为止的代码可以在下面找到。有一些我尝试过但失败的东西的痕迹,有一些未使用或只是奇怪的东西(最好的例子是 IBuildImpl)。这些是为了让您了解我的尝试,但如果您认为这需要适度 - 请告诉我,我会清理它们
基础
package fafafa;
public abstract class Animal<T> {
String name; //mandatory field, one of many
Integer age; //mandatory field, one of many
public String getName() {
return name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
interface IName {
IAge name(String name);
}
interface IAge {
IBuild age(Integer age);
}
interface IBuild<T extends Animal<T>> {
T build();
}
public abstract static class Builder<T extends Animal<T>, B extends Builder<T, B>>
implements IName, IAge, IBuild<T> {
protected T objectBeingBuilt;
protected abstract B that();
protected abstract T createEmptyObject();
Builder(){
this.objectBeingBuilt = createEmptyObject();
System.out.println();
}
@Override
public IAge name(String name) {
objectBeingBuilt.name = name;
return that();
}
@Override
public IBuild age(Integer age) {
objectBeingBuilt.age = age;
return that();
}
// @Override
// public T build() {
// return objectBeingBuilt;
// }
}
}
实施
package fafafa;
public class Spider extends Animal<Spider> {
Integer numberOfLegs; //optional field, one of many
private Spider() {
}
public Integer getNumberOfLegs() {
return numberOfLegs;
}
@Override
public String toString() {
return "Spider{" +
"numberOfLegs='" + numberOfLegs + '\'' +
"} " + super.toString();
}
// public static Builder<Spider, Builder> name(String name) {
// return (Builder) new Builder().name(name);
// }
interface INumberOfLegs {
IBuild numberOfLegs(Integer numberOfLegs);
}
interface IBuildImpl extends IBuild<Spider>, INumberOfLegs {
@Override
Spider build();
}
public static class Builder extends Animal.Builder<Spider, Builder> implements IBuildImpl {
@Override
protected Builder that() {
return this;
}
@Override
protected Spider createEmptyObject() {
return new Spider();
}
public IBuild numberOfLegs(Integer numberOfLegs) {
objectBeingBuilt.numberOfLegs = numberOfLegs;
return that();
}
public Spider build() {
return objectBeingBuilt;
}
}
}
主要
package fafafa;
public class Main {
public static void main(String[] args) {
Spider build = new Spider.Builder().name("elvis")
.age(1)
.numberOfLegs(8) //cannot resolve method numberOfLegs
.build();
System.out.println(build);
}
}
【问题讨论】:
标签: java inheritance builder fluent fluent-interface