以 spring-boot 代码中的多态性为条件进行重构

Pra*_*kar 2 polymorphism refactoring spring code-cleanup conditional-statements

我在这里看到了 Martin Fowler 的《重构》中给出的示例

不知道如何以 spring-boot 方式(IoC)实现它。

我正在开发 Spring Web 应用程序。我有一个 REST 控制器,它以给定的格式接受studentIdfileType导出学生fileType的数据。控制器调用ExportService exportFile()如下所示的方法

@Service
public class ExportServiceImpl implements ExportService {
    public void exportFile(Integer studentId, String fileType) {
        if (XML.equals(fileType)) { exportXML(studentId);}
        else if()... // and so on for CSV, JSON etc
    }
}
Run Code Online (Sandbox Code Playgroud)

为了以多态性为条件进行重构,

首先我创建了抽象类,

abstract class ExportFile {
    abstract public void doExport(Integer studentId);
}
Run Code Online (Sandbox Code Playgroud)

然后我为每个文件类型导出创建服务。例如,以下 XML 导出是一项服务,

@Service
public class ExportXMLFileService extends ExportFile {
    public void doExport(Integer studentId) {
        // exportLogic will create xml
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我的 ExportService 应该是这样的,

@Service
public class ExportServiceImpl implements ExportService {
    @Autowired
    private ExportFile exportFile;

    public void exportFile(Integer studentId, String fileType) {
        exportFile.doExport(studentId);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我被困在这里:(

无法获取,如何@Autowired ExportFile知道根据哪个具体服务来参考fileType

如果我错了,请纠正我。我们将非常感谢您的回复:)

rap*_*oft 5

您将需要实现工厂模式。我做了类似的事情。您将得到一个ExportServiceFactory它将根据特定的输入参数返回 的具体实现ExportService,如下所示:

@Component
class ExportServiceFactory {

    @Autowired @Qualifier("exportXmlService")
    private ExportService exportXmlService;

    @Autowired @Qualifier("exportCsvService")
    private ExportService exportCsvService;

    public ExportService getByType(String fileType) {
         // Implement method logic here, for example with switch that will return the correct ExportService
    }

}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我使用了 Springs @Qualifier,它将确定将注入什么实现。

然后在您的代码中,每当您需要使用时,ExportService您将注入工厂并获取正确的实现,例如

  ...
  @Autowired
  private ExportServiceFactory exportServiceFactory;

  ...
  // in method, do something like this
  exportServiceFactory.getByType(fileType).doExport();
Run Code Online (Sandbox Code Playgroud)

我希望这能帮助您走上正确的道路。至于工厂方法中的切换 - 没关系,因为您现在已经解耦逻辑以从与之无关的代码中检索特定的实现。