gpt4 book ai didi

java - 如何为许多具体类型创建抽象工厂

转载 作者:行者123 更新时间:2023-12-02 09:56:36 25 4
gpt4 key购买 nike

假设我们有名为 IAction 的接口(interface),以及许多实现此接口(interface)的类(超过 20 个):ConreteAction1 , ConreteAction2等等。所有这些类都有带参数的构造函数。此外,所有这些类及其依赖项都在 Dagger 模块中注册(作为 transient 对象或单例)。我们的任务是实现(或自动生成)抽象工厂实现类似于以下的接口(interface):

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 的另一个实现时都必须修改上面的工厂。接口(interface)(违反开闭原则)。

Dagger 中是否有其他方法可以以更优雅和可扩展的方式创建这样的工厂实现?

最佳答案

您可以使用Multibindings为此。

@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();
}
}

此时主要的困难是您将每个 Action 绑定(bind)两次,每个 map 一次。如果这是一个问题,您可以使用 Set 绑定(bind)来聚合一组配置,然后使用映射绑定(bind)来检索正确的 Provider。

关于java - 如何为许多具体类型创建抽象工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55959445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com