我有以下非常简单的界面:
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
(或更多!),这将变得非常混乱。
我一直在忽视一些更简单的解决方案吗?
由于
答案 0 :(得分:0)
如果你必须有工厂,那么没有 - as in this question手工工厂可能是你能得到的最好的。
但是,如果使用不同的绑定注释将所有IDataSource实现绑定到IDataSource,那么您可以跳过工厂并简单地注入@Source("foo") IDataSource
并获取所需的实例。 String和实现之间的配置仍然必须存在于某个地方,但如果您愿意,可以将其置于Guice模块中。并且,通过注入Injector并提供兼容的注释实现,您甚至可以编写像DataSourceFactory这样的工厂,它遵循Guice。
作为旁注,请注意您的DataSourceFactory; get
没有安全的方法为其类型参数T提供值。