2009-09-09 9 views
0

依存性注入は便利な手法ですが、ランタイム依存性に直面した場合はどのような方法が推奨されますか?ランタイム依存性の処理

イベントのタイプとリクエストを開始したユーザーに応じて、イベントプロセッサにイベントをグルーグルしたいとします。

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

は今複雑さは、工場内にカプセル化されているが、どのように他の私は、同じ結果を得ることができ、あまりにも多くの定型コードなし?

+1

インスタンスの重い使用は、Javaの「臭い」の1つで、デザインに問題があることを伝えていますが、私たちにお尋ねしてから考えていると思います! – SteveD

答えて

2

あなたがそうでなければ、あなたがそれらに頼ることができます、あなたのプロセッサは、自然順序付けのいくつかの並べ替えを持っている場合、あなたは彼らが正しい順序でテストされることを保証するためにComparableを実装することができます

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 
} 

のようなものを使用することができますが注入されています必要な順番で工場に送り、設定可能にします。

+0

ありがとうございます。チェックする候補プロセッサーの数が少ないと仮定すると、素晴らしい解決策です。 – parkr

0

それぞれEventEventProcessorの作成を担当させることができます。そうすれば、あなたが行う必要があるチェックの数を減らし、より良いカプセル化を達成することができます。より多くの「OO」にもかかわらず、論理はもはや1つの場所にない(つまり、あなたの例によれば、「手続き的アプローチ」に固執するほうがよい)というトレードオフがあります。

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

書かれているように、「定型化されたコード」と呼ばれるものは、私にはちょうど「コード」であるように見えます。どこかに記述する必要があるいくつかの処理ロジックがあります(ローカルイベントはローカルイベントプロセッサなどに行きます)。その論理が間違いであると明示的に述べないようにしようとする。あなたまで、それらの上のすべてのイベントプロセッサとループを設定

boolean isInterestedInEvent(Event e) 

:それはあなたがやりたいんどのような場合には

は、それを行うための最も簡単な方法は、メソッドを追加するためのインタフェースを変更することです正しいものを見つけてください。

+0

+1 - 興味のあるイベントを公開する*イベントプロセッサ*のように見えます。 –

関連する問題