在没有类型转换返回类型的情况下调用工厂

时间:2014-03-11 20:42:37

标签: java generics casting factory builder

这是我第一次尝试制作工厂..如果我没有正确使用图案,请原谅!

所以这是我的工厂:

public class BuilderFactory { 

    public BuilderFactory(){        
    }

    public <T extends Builder> T getBuilderOf(Object clazz){
        if(clazz instanceof House){             
            return (T) new HouseBuilder();
        }
        return null;
    }
}

它将返回一个构建器(在本例中为HouseBuilder),它具有一个Builder接口。

构建器:

public interface Builder<T> {

    T build();

}

HouseBuilder:

public class HouseBuilder implements Builder<House> {

    private String street;

    public HouseBuilder() {

    }
    @Override
    public House build() {
        return new House(street);
    }

    @Override
    public HouseBuilder<House> withStreet(String street) {
        this.street = street;
        return this;
    }

}

这是我称之为的地方:

BuilderFactory builderFactory = new BuilderFactory();

现在可以这样做:

builderFactory.getBuilderOf(House.class).build();

由于build()位于Builder界面中。但如果我想这样做:  builderFactory.getBuilderOf(House.class).withStreet("street");

我隐含地需要像这样构建构建器:

 (HouseBuilder)builderFactory.getBuilderOf(House.class).withStreet("street")

否则编译器会抱怨。

我不想强制转换它,也不想从工厂实例化我的返回值。是否有任何选项我无需转换结果,仍然可以使用.withStreet()方法? :)

提前致谢。 戴维

2 个答案:

答案 0 :(得分:4)

为什么要烦扰泛型?

您的工厂明确需要了解具体构建器(return (T) new HouseBuilder())。

您的客户端明确需要传递正确的类型(House.class),显然您希望它知道该类型,因为客户端使用特定于具体构建器的方法(withStreet

所以只需使工厂方法具体:

public HouseBuilder getHouseBuilder() {
    return new HouseBuilder();
}

答案 1 :(得分:2)

如果你想要添加细节,你对你的实现非常通用,那么你也需要对它们进行通用。

public interface Instruction {

    public String getDescription();
}

public StreetInstruction implements Instruction {
    String street;

    public StreetInstruction (String street) {
       this.street = street;
    }

}

public interface Builder<T> {

    T build(Instruction ... instructions);

}


builderFactory.getBuilderOf(House.class).build(new StreetInstruction("Sesame"));

现在有很多方法可以解决这个问题,但这可能就是其中之一。我认为你遇到的问题是不同类型的对象将有非常不同的实现。所以你的工厂也可以创造家具。如果它确实如何指导那个建造者你想要一张沙发而不是一张椅子?你的目标没有任何问题,你可能想要考虑你的范围。