Java - 使用泛型创建流畅的界面

时间:2014-06-11 21:15:04

标签: java generics fluent

在我目前的任务中,我必须构建一个新的SchemaArtifact对象,该对象填充了测试用例的递归Field对象(两个自定义类)。我还需要使用流畅的界面来做到这一点。问题是我的build()函数(在树中弹出一个级别)应该返回根SchemaArtifact(如果调用字段位于顶层)或返回其父级(如果它是子字段)。我知道这可能听起来令人困惑,所以希望一些示例代码可以清除它:

public class SchemaHelper{
    public SchemaArtifact makeSchema(){
        return new SchemaArtifact()
            .addField(new Field("FirstName"))
                .addField(new Field("Nickname")).build()
                .build()
            .addField(new Field("LastName")).build();
    }
}

public class SchemaArtifact{
    private Map<String, Field> fields = new Map();

    public addField(Field f){
        this.fields.put(field.id, f);
        return f;
    }
}

public class Field{
    public String id;
    private Map<String, Field> fields = new Map(); //children
    private Field parent; //null if parent is just the main schema
    private SchemaArtifact schema; //schema that this Field belongs to

    public Field(String id){
        this.id = id;
    }

    public Field addField(Field f){
        this.fields.put(field.id, f);
        return f;
    }

    public <T> T build(){
        if(this.parent != null){
            return (T)this.parent;
        }else{
            return (T)this.schema;
        }
    }
}

正如您所看到的,我尝试使用泛型返回多个类型,但我得到了#34;方法addField(Field)未定义类型Object&#34;当我尝试一次添加多个Field时我也试过使用一个包装器接口,后来需要不必要的铸造;并且单独的buildToSchema()/ buildToField()方法可以使用,但是使得创建多个模式更加困惑。

总而言之,有没有办法让我获得单一的build()方法来返回SchemaArtifact和Field?

谢谢你,
泰勒

1 个答案:

答案 0 :(得分:1)

必须在编译时知道build()的返回类型。在这种情况下,返回对象的类取决于运行时条件,因此在编译时无法知道。

两种可能性:

  • 您知道何时需要FieldSchemaArtifact。在这种情况下,您应该使用两种分离方法并在适当的地方使用它们。
  • 您不知道期望什么类型。在这种情况下,您应该使用接口。

你也可以这样:

Field field = new SchemaArtifact()
        .addField(new Field("FirstName"))
            .addField(new Field("Nickname")).build();
SchemaArtifactschema = field.build();

这将强制编译器推断出正确的类型,但它与使用两种不同的方法相同,只是更少类型安全(如果使用错误的类型,将会有ClassCastException。)