[英]How to create abstract factory for many concrete types
假设我们有一个名为IAction
接口,以及许多实现此接口的类(超过20个): ConreteAction1
, ConreteAction2
等。所有这些类都有带有参数的构造函数。 同样,所有这些类及其依赖项都在Dagger模块中注册(作为瞬时对象或单例)。 我们的任务是实现(或自动生成)抽象工厂实现接口,类似于:
public interface IActionFactory{
IAction createByClass(Class clazz); // create action by type
// or
IAction createByName(String name); // create action by custom name
}
我知道如何使用Dagger对Provider<T>
批注的支持来实现此工厂:
public class ActionFactory implements IActionFactory{
@Inject Provider<ConcreteAction1> concreteAction1Provider;
@Inject Provider<ConcreteAction2> concreteAction2Provider;
(...)
@Override
public IAction createByClass(Class clazz){
if(ConcreteAction1.class.equals(clazz)){
return concreteAction1Provider.get()
}
if(ConcreteAction2.class.equals(clazz)){
return concreteAction2Provider.get()
}
(...)
}
@Override
public IAction createByName(String name){
if(name.equals("name_1")){
return concreteAction1Provider.get()
}
if(name.equals("name_2")){
return concreteAction2Provider.get()
}
(...)
}
}
不幸的是,这种方法涉及很多样板代码(我有20多个具体的类),并且每次我创建IAction
接口的另一个实现(违反开闭原理)时,都必须修改上面的工厂。
Dagger中还有其他方法可以更优雅,更可扩展地创建这种工厂实现吗?
您可以为此使用多重绑定 。
@Module public interface ActionModule {
@Binds @IntoMap @ClassKey(ConcreteAction1.class)
IAction bindActionClass1(ConcreteAction1 action1);
@Binds @IntoMap @ClassKey(ConcreteAction2.class)
IAction bindActionClass2(ConcreteAction2 action2);
// ...
@Binds @IntoMap @StringKey("name_1")
IAction bindActionName1(ConcreteAction1 action1);
@Binds @IntoMap @StringKey("name_2")
IAction bindActionName2(ConcreteAction2 action2);
// ...
}
public class ActionFactory implements IActionFactory{
@Inject Map<Class<?>, Provider<IAction>> classActionFactory;
@Inject Map<String, Provider<IAction>> stringActionFactory;
@Override
public IAction createByClass(Class<?> clazz) {
// TODO: handle missing entries gracefully
return classActionFactory.get(clazz).get();
}
@Override
public IAction createByName(String name) {
return stringActionFactory.get(name).get();
}
}
这时的主要困难是,每个动作绑定两次,每个地图绑定一次。 如果这是一个问题,则可以使用Set绑定来聚合一组配置,然后使用map绑定来检索正确的Provider。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.