2016-08-23 3 views
0

ルールのセットに従ってパスワードを検証するクラスがあるとします。このパスワードがどのくらい正確に確認されるかは、サーバーを呼び出す人によって異なります。それぞれの異なる種類の人は、いくつかのルールに対して異なる実装をしています。 LengthRuleは、通常の検証では厳密な検証8で、長時間の検証では5回の長さを必要とします。
渡されたパラメータ(たとえば、グループ配線)に従ってすべてのルールのバインディングを変更し、それらを動的に切り替える最も良い方法は何ですか?パラメータのGuice設定を変更する

public void verifyPassword(String password, Person person) { 
    if (isBusinessClient(person)) { 
      // Apply strict wiring 
      PasswordChecker checker = new PasswordChecker(); 
      passwordChecker.check(password) 
    } else if (wasBusinessClient(person)) { 
      // Apply normal wiring 
      PasswordChecker checker = new PasswordChecker(); 
      passwordChecker.check(password) 
    } else { 
      // Apply lax wiring 
      PasswordChecker checker = new PasswordChecker(); 
      passwordChecker.check(password) 
    } 
} 
+0

あなたが渡したjsonオブジェクトはあなたのPersonオブジェクトですか? – pandaadb

+0

簡単にするために、人がif elseを評価できる列挙型であると仮定することはできません。問題は、guiceバインディングを動的に変更する方法です。 – PKuhn

+0

マルチバインディングを使用し、PasswordCheckerのX量をバインドし、isXXXClientメソッドの代わりに、正しいパスワードチェッカーを返すgetPasswordChecker(Person)メソッドがあります。 – pandaadb

答えて

2

これはguiceのマルチバインディングに基づいた回答です。一般:複数の実装を特定のインタフェースにバインドし、一連の実装を注入できます。

私がしようとしているのは、すべてのパスワードチェッカーをバインドして注入し、そのセットを使用して何をすべきかを判断することです。

これは完全に実行されている例です。

public class TestMultiBinding { 

    public static void main(String[] args) { 

     Injector injector = Guice.createInjector(new AbstractModule() { 

      @Override 
      protected void configure() { 
       Multibinder<PasswordChecker> multiBinder = Multibinder.newSetBinder(binder(), PasswordChecker.class); 
       multiBinder.addBinding().to(BusinessChecker.class); 
       multiBinder.addBinding().to(ClientChecker.class); 

       bind(Test.class).in(Singleton.class); 
      } 
     }); 


     Test test = injector.getInstance(Test.class); 
     test.verifyPassword("hello", Person.P1); 
     test.verifyPassword("hello", Person.P2); 
    } 

    public static class Test { 

     private Set<PasswordChecker> checkers; 

     @Inject 
     public Test(final Set<PasswordChecker> checker) { 
      this.checkers = checker; 
     } 

     public void verifyPassword(final String pass, final Person p) { 
      getPasswordChecker(p).check(pass); 
     } 

     public PasswordChecker getPasswordChecker(final Person p) { 
      Optional<PasswordChecker> checker = checkers.stream().filter(c -> c.isApplicable(p)).findFirst(); 
      if(checker.isPresent()) { 
       return checker.get(); 
      } 
      return null; // or default 
     } 
    } 


    public static interface PasswordChecker { 
     public void check(String s); 
     boolean isApplicable(Person P); 
    } 

    public static class BusinessChecker implements PasswordChecker { 

     @Override 
     public void check(String s) { 
      System.out.println("User Business Checker"); 
     } 

     @Override 
     public boolean isApplicable(Person P) { 
      return P.equals(Person.P1); 
     } 
    } 

    public static class ClientChecker implements PasswordChecker { 

     @Override 
     public void check(String s) { 
      System.out.println("User Client Checker"); 
     } 

     @Override 
     public boolean isApplicable(Person P) { 
      return P.equals(Person.P2); 
     } 
    } 

    public enum Person { 
     P1, P2; 
    } 
} 

テストクラスはあなたの例です。それはパスワードとPerson列挙をとる。

各PasswordCheckerは、「isApplicable」というメソッドを実装して、指定されたPersonがこのチェッカーを使用できるかどうかを判断します。代わりに、噴射時に、PasswordCheckerを正しい人にマッピングすることもできます(stream.collect(Collectors.toMap(...))メソッドを使用)。そうすれば、正しい実装を得るためにハッシュマップルックアップを行うだけで済みます。

私のモジュールでは、パスワードチェッカーのマルチバインディングを定義します。私はそれに私のバインディングを追加します。

残りは表示されます。私のコードを呼び出す

が印刷されます:

User Business Checker 
User Client Checker 

私は、これはあなたが私に知らせて:)を探していたものですね!

Artur

関連する問題