在我的Spring Boot应用程序中,我有一个Stage
和StageProcessor
的概念,该概念处理Stage
。 Stage
具有一个StageType
枚举属性。我有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机制。有更好的设计想法吗?
答案 0 :(得分:1)
这取决于您案件的具体情况。在许多情况下,阶段实际上不是像枚举中那样硬编码的,而是可以为各种系统配置的。此外,您拥有的潜在阶段越多,设置稍微冗长但避免重复的收益就越大。
通常,我会在这里推荐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.)
答案 1 :(得分:0)
这完全基于@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);
}
}