我有不同的类类型,根据某些情况,我想委托(delegate)给可以处理这些类类型的适当服务
。
例子: 我有几个类如下。
class Student;
class Prof;
...
对于每个类都有一个服务,实现:
interface IPersonService {
void run();
}
我有一个 mode
是根据某些条件找到的:
enum PersonType {
STUDENT, PROF;
}
当我委托(delegate)时:
@Autowired
private StudentService studentService;
@Autowired
private ProfService profService;
//@param mode assume known
public void delegate(PersonType mode) {
//assume there are several of those switch statements in my business code
switch (mode) {
case STUDENT: studentService.run(); break;
case PROF: profService.run(); break;
default: break;
}
}
问题:当引入额外的类时,我必须同时修改 PersonType
并添加一个额外的枚举(这没问题),但我还必须扩展任何switch
语句并添加对其他委托(delegate)服务的调用。此外,我还必须将这些服务显式 Autowiring 到切换委托(delegate)器。
问题:我如何优化这段代码,只为任何附加类实现新服务,而不必触及任何 switch 语句?
最佳答案
将方法添加到IPersonService
这样方法的实现就可以告诉程序它处理的是什么类型的人:
interface IPersonService {
PersonType supportedPersonType();
void run();
}
在执行委托(delegate)的服务中,注入(inject)一个 List<IPersonService>
, Spring 将填充 IPersonService
的所有实现。它可以找到。然后执行 delegate
通过列表查找第一个 IPersonService
的方法可以处理特定类型。
@Autowired
private List<IPersonService> personServices;
public void delegate(PersonType mode) {
for (IPersonService personService : personServices) {
if (personService.supportedPersonType().equals(mode)) {
personService.run();
break;
}
}
}
这样,您可以添加 IPersonService
的新实现无需更改执行委托(delegate)的服务。
为了避免每次都要经历循环 delegate
被称为,你可以建立一个Map
事先让权利IPersonService
可以快速查找:
class DelegatingService {
@Autowired
private List<IPersonService> personServices;
private Map<PersonType, IPersonService> personServiceMap;
@PostConstruct
public void init() {
personServiceMap = new HashMap<>();
for (IPersonService personService : personServices) {
personServiceMap.put(personService.supportedPersonType(), personService);
}
}
public void delegate(PersonType mode) {
personServiceMap.get(mode).run();
}
}
(为简单起见省略了错误处理)。
关于java - 如何按类类型委托(delegate)给服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37941111/