依赖注入是一种有用的技术,但在面对运行时依赖性时,建议采用什么方法?
e.g。假设您要根据事件类型和发起请求的用户将事件粘贴到事件处理器。
public interface Event {}
public interface EventProcessor {
public void handleEvent(Event e);
}
class EventProcessorFactory {
private final User u;
private final Event e;
public EventProcessorFactory(User u, Event e) {
this.u = u;
this.e = e;
}
public EventProcessor get() {
EventProcessor ep;
if(e instanceof LocalEvent) {
ep = new LocalEventProcessor();
}
else if(e instanceof RemoteTriggeredEvent && u instanceof AdminUser) {
//has static dependencies
ep = new RemoteEventProcessor(u);
}
else {
ep = new DefaultEventProcessor();
}
}
}
现在复杂性已封装在工厂中,但如果没有太多的样板代码,我怎样才能获得相同的结果呢?
答案 0 :(得分:3)
正如所写,你所谓的'样板代码'在我看来只是'代码'。您有一些需要在某处声明的处理逻辑(本地事件转到本地事件处理器等)。试图避免明确说明逻辑可能是一个错误。
如果这是您想要做的,最简单的方法是更改界面以添加方法:
boolean isInterestedInEvent(Event e)
然后设置所有事件处理器并循环遍历它们,直到找到正确的处理器。
答案 1 :(得分:2)
您可以使用类似
的内容public interface EventProcessor {
public boolean supports(Event event, User user);
public void handleEvent(Event event);
}
class EventProcessorFactory {
public void setEventProcessors(List<EventProcessor> processors) {
this.processors = processors;
}
public EventProcessor get(Event event, User user) {
for (EventProcessor processor : processors) {
if (processor.supports(event, user)
return processor;
}
}
}
class LocalEventProcessor implements EventProcessor {
public boolean supports(Event event, User user) {
return (event instanceof LocalEvent);
}
// etc
}
class RemoteEventProcessor implements EventProcessor {
public boolean supports(Event event, User user) {
return (event instanceof RemoteTriggeredEvent) &&
(user instanceof AdminUser);
}
// etc
}
如果你的处理器有某种自然顺序,你可以实现Comparable
以确保它们按正确的顺序进行测试,否则你可以依赖它们以所需的顺序注入工厂,因此使其可配置。
答案 2 :(得分:0)
您可以让每个Event
负责创建EventProcessor
。这样,您可以减少需要进行instanceof
检查的次数,并实现更好的封装。尽管更多的是“OO”,但是权衡的是逻辑不再存在于一个地方(即,有时候根据你的例子坚持使用“程序方法”更好。)
public interface Event {
EventProcessor createProcessor(User u);
}
public class RemoteTriggeredEvent implements Event {
public EventProcessor createProcessor(User u) {
return (u instanceof AdminUser) ? new RemoteEventProcessor(u) :
new DefaultEventProcessor();
}
}