处理运行时依赖项

时间:2009-09-09 08:04:38

标签: java dependency-injection

依赖注入是一种有用的技术,但在面对运行时依赖性时,建议采用什么方法?

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();
        }
    }
}

现在复杂性已封装在工厂中,但如果没有太多的样板代码,我怎样才能获得相同的结果呢?

3 个答案:

答案 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();
  }
}