在我的Spring Boot应用程序中,我有一个Stage
和StageProcessor
的概念来处理Stage
。 Stage
有一个StageType
enum财产。我有不同的StageProcessor
接口实现,这些实现是Spring bean。现在,我有另一个Spring bean,WorkflowProcessor
,需要根据StageProcessor
的StageType
调用合适的Stage
。到目前为止,我已经提出以下建议:
@Service
public class StageConfig {
@Autowired
private StageProcessorA stageProcessorA;
@Autowired
private StageProcessorB stageProcessorB;
public StageProcessor getProcessor(Stage stage) {
switch(stage.getType()) {
case A:
return stageProcessorA;
break;
case B:
return stageProcessorB;
break;
}
}
}
我想知道我是否缺少任何设计模式或Spring机制。有更好设计的想法吗?
这完全基于@chrylis的想法,因为处理器不需要为此更改它们的API,您只需使用注释即可。此外,如果您有一种类型的多个处理器,则会出现这种情况。
interface StageProcessor {
OutputType process(Stage stage);
}
@Component
@Processes(StageType.A)
class StageProcessorA implements StageProcessor{
OutputType process(Stage stage){
//validate stage is StageType.A
}
}
@interface Processes{
StageType type;
StageType getType(){
return type;
}
}
@Component
@Processes(StageType.B)
class StageProcessorB implements StageProcessor{
}
@Service
class StageProcessors {
Map<StageType, List<StageProcessor>> stageProcessors;
StageProcessors(Collection<StageProcessor> processors) {
Map<StageType, List<StageProcessor>> map = new HashMap<>();
for (StageProcessor processor : processors) {
StageType stageType = processor.getClass().getAnnotation(Processes.class).getType();
map.computeIfAbsent(stageType, k -> new ArrayList<>()).add(processor);
}
stageProcessors = map;
assert stageProcessors.size() == expectedNumberOfProcessors;
}
List<StageProcessor> getProcessors(StageType stage) {
return stageProcessors.get(stage);
}
}
这取决于您案例的具体情况。在许多情况下,阶段实际上并不像枚举中那样硬编码,而是可以针对各种系统进行配置。此外,您拥有的潜在阶段越多,设置稍微更详细但避免重复的成本就越高。
一般来说,我会在这里推荐Spring的解析器模式。代码看起来像这样,其中KeyType
通常是枚举或字符串。一般的想法是每个实现告诉你它可以处理什么类型的事物(阶段,类型,参数等),然后你查找匹配。 (没有直接映射查找的变体是有boolean canHandle(something)
并迭代直到找到一个。)
interface StageProcessor {
OutputType process(Stage stage);
KeyType stageKey();
}
@Service
class StageProcessors {
Map<KeyType, StageProcessor> stageProcessors;
StageProcessors(Collection<StageProcessor> processors) {
stageProcessors = processors.stream().collect(groupingBy(StageProcessor::stageKey));
assert stageProcessors.size() == expectedNumberOfProcessors;
}
StageProcessor getProcessor(KeyType stage) {
// although usually your service would take care of dispatching directly
return stageProcessors.get(stage);
}
}
(并作为注释:Avoid field injection.)