2016-08-23 2 views
0

Допустим, у меня есть класс, который проверяет пароли в соответствии с набором правил. Как именно этот пароль проверяется, зависит от человека, который вызывает сервер. У каждого отдельного человека есть другая реализация для некоторых правил. Допустим, что LengthRule будет требовать длину 12 в строгой проверке 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

Ваш объект Person - объект json, в который вы проходите? – pandaadb

+0

Это не означает, что для простоты можно предположить, что человек является перечислением, на котором можно оценить if. Проблема заключается в том, как динамически изменять привязки guice. – PKuhn

+0

Вы можете использовать multibindings, связывать X количество PasswordChecker и вместо метода isXXXClient, у вас есть метод getPasswordChecker (Person), который возвращает правильную проверку пароля – pandaadb

ответ

2

это ответ на основе MultiBindings в виде. Общее: вы можете привязать несколько реализаций к данному интерфейсу, а затем ввести набор реализаций.

То, что я собираюсь сделать, - это привязать все мои проверки пароля, ввести их, а затем использовать этот набор, чтобы определить, что делать.

Это полный работает пример:

класс
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», чтобы определить, может ли данное лицо использовать эту проверку. Альтернативно, во время инъекции вы можете сопоставить PasswordChecker с правильным человеком (используя методы stream.collect (Collectors.toMap (...))). Таким образом, вам нужно будет только просмотреть хэш-карту, чтобы получить правильную реализацию.

В моем модуле я определяю многосвязывание для паролей. Я добавляю привязки к нему.

Остальное вы можете видеть.

Вызов мой код выведет:

User Business Checker 
User Client Checker 

Я надеюсь, что это то, что вы искали :) дайте мне знать!

Artur

Смежные вопросы