避免使用Factory模式和Spring的原始类型

pjngdqdw  于 2022-11-21  发布在  Spring
关注(0)|答案(1)|浏览(139)

我尝试实现一个工厂模式,通过该模式,给定一个具有类型字段的对象,我可以动态地让类处理该对象
这是一个简单的例子,基本上,有一系列实现Builder接口的Spring服务组件。它们定义了它们可以处理的TYPE。Factory类将有Spring注入的builders,即所有实现Builder接口的类。
Test类说明了如何使用它,即,要测试的参数将具有一个类型字段,该字段用作查找以获取正确的构建器类。
这工作正常,但我得到了很多原始类型的警告,我不确定最好的方法来摆脱。
有没有更好的方法来搭配这个?谢谢!

@Service
public class Factory {
    // Raw type warning here
    Map<Builder.TYPE, Builder> builderMap;

    // Raw type warning here
    public Factory(List<Builder> builders){
       builderMap = builders.stream().collect(Collectors.toMap( Builder::getType, Function.identity() ));
    }
    // Raw type warning here
    public Builder getBuilder(Builder.TYPE TYPE){
        return builderMap.get(TYPE);
}

public interface Builder<T> {
   TYPE getType();
   ProcessedObject process(T object);
   enum TYPE {
      ONE
   }
}

@Service
public class TestBuilder implements Builder<DtoOne> {
  @Override
  public TYPE getType() {
     return TYPE.ONE;
  }

  @Override
  public ProcessedObject process(DtoOne object) {
     // ... process
  }
}

@Service
public class Test {
  private final Factory factory; // omitting constructor code

  public void test(Dto testObject) {
     // Raw type warning here
     Builder builder = factory.getBuilder(testObject.getType());
     // Raw type warning here
     builder.process(testObject);
  }
}
sq1bmfud

sq1bmfud1#

根据以下意见更新答案:
如果我理解正确的话,基本上你要用T来限制process()方法参数中的对象类型。
我可以想到两种方法:
1.如果您有BaseDto,所有其他Dto对象(DtoOne、DtoTwo等)都将扩展到该BaseDto,我们可以编写如下代码。
制造商:

public interface Builder<T extends BaseDto> {
    TYPE getType();

    Object process(T object);

    enum TYPE {
        ONE
    }
}

工厂名称:

public class Factory<T extends BaseDto> {
   
    Map<Builder.TYPE, Builder<T>> builderMap;

    
    public Factory(List<Builder<T>> builders){
       builderMap = builders.stream().collect(Collectors.toMap( Builder::getType, Function.identity() ));
    }
    
    public Builder<T> getBuilder(Builder.TYPE TYPE){
        return builderMap.get(TYPE);
    }
}

这样我们就可以避免原始类型警告。
1.如果没有公共的基类,那么我们几乎可以向构建器中添加任何类型,而这些类型本质上是未知类型(可以是任何类型)。在这种情况下,我们可以用通配符替换原始类型警告,如下所示。
生成器类将保持不变。工厂类将如下所示:

public class Factory {

    Map<Builder.TYPE, Builder<?>> builderMap;

 
    public Factory(List<Builder<?>> builders){
       builderMap = builders.stream().collect(Collectors.toMap( Builder::getType, Function.identity() ));
    }

    public Builder<?> getBuilder(Builder.TYPE TYPE){
        return builderMap.get(TYPE);
    }
}

相关问题