如何使用Guice简单地处理多个参数 - 发散类的工厂?

时间:2016-04-19 08:38:46

标签: java guice factory

我有以下非常简单的界面:

public interface IDataSource<T> {
    Observable<T> observable();
}

现在我将有多个实现。每个实现都可能依赖于不同的参数(不同的存储对象:JDBC,Cassandra,Redis ......)。所以我要说:

public class CassandraDataSource implements IDataSource<MyCassandraObject> {
    @Inject
    public CassandraDataSource(Keyspace ks) {
        // ...
    }
}

public class OtherCassandraDataSource implements IDataSource<MyOtherCassandraObject> {
    @Inject
    public OtherCassandraDataSource(Keyspace ks) {
        // ...
    }
}

public class JDBCDataSource implements IDataSource<MyJdbcObject> {
    @Inject
    public JDBCDataSource(Database db) {
        // ...
    }
}

等等。

我想要的是用字符串引用每个字符串,这样我就可以调用一个返回相应IDataSource的工厂。表现得像这样的东西:

public class DataSourceFactory {
    public static final Map<String, Supplier<IDataSource<?>>>   map = new HashMap<>();

    @SuppressWarnings("unchecked")
    public <T> IDataSource<T> get(String ref) {
        return (IDataSource<T>) map.get(ref).get();
    }
}

我可以将N Providers作为参数(或直接场注入)给我的工厂(N是我使用的IDataSource的数量)并将字符串映射到构造函数中的那些或使用开关在get方法中,但一旦达到10到20 IDataSource(或更多!),这将变得非常混乱。

我一直在忽视一些更简单的解决方案吗?

由于

1 个答案:

答案 0 :(得分:0)

如果你必须有工厂,那么没有 - as in this question手工工厂可能是你能得到的最好的。

但是,如果使用不同的绑定注释将所有IDataSource实现绑定到IDataSource,那么您可以跳过工厂并简单地注入@Source("foo") IDataSource并获取所需的实例。 String和实现之间的配置仍然必须存在于某个地方,但如果您愿意,可以将其置于Guice模块中。并且,通过注入Injector并提供兼容的注释实现,您甚至可以编写像DataSourceFactory这样的工厂,它遵循Guice。

作为旁注,请注意您的DataSourceFactory; get没有安全的方法为其类型参数T提供值。