Мне интересно, каков наилучший дизайн для общеклассового обязательного условия, которое должно соблюдаться во время строительства.
Позвольте мне привести упрощенный пример.
У меня есть класс, представляющий безопасную строку, например, пароль.Пароли хранятся только как их хэш-представление.Пароли не могут быть проверены, но проверяются только на предмет попытанного значения.
class Password {
private String passwordHash;
private Password(){};
public Password(String aPassword) {
setPassword(aPassword);
}
public void setPassword(String aPassword) {
passwordHash = hash(aPassword);
}
public boolean checkPassword(String attempt) {
return verify(attempt, passwordHash);
}
}
Вопрос в том, как спроектировать выбор алгоритма хеширования.Код клиента должен иметь возможность выбирать из различных алгоритмов хеширования.И в данном приложении все пароли должны использовать один и тот же алгоритм хеширования.
Итак, я определяю интерфейс Hasher,
interface Hasher {
String hash(String password);
boolean verify(String attempt, String hash);
}
Могут быть разные реализации Hasher.
class SimpleHasher implements Hasher {
public String hash(String password) { // native java String.hashCode()
return Integer.toString(password.hashCode(),16);
}
public boolean verify(String attempt, String hash) {
return attempt.hashCode()==Integer.valueOf(hash, 16);
}
}
class SecureHasher implements Hasher {
public String hash(String password) { // Secure SCrypt hash
return com.lambdaworks.crypto.SCryptUtil.scrypt(password,16384,8,1);
}
public boolean verify(String attempt, String hash) {
return com.lambdaworks.crypto.SCryptUtil.check(attempt,hash);
}
}
Код клиента должен выбрать реализацию и установить хеш-код.До тех пор никто не может создать пароль.И после установки хеш не может быть изменен.
Вот проектное решение.
В настоящее время я объявляю переменную static private
, поэтому хеш-код одинаков для всех экземпляров Password;и устанавливается установщик, который принудительно запрещает его однократное изменение.
class Password {
static private Hasher hasher = null;
static public void setHasher(Hasher ahasher) throws Exception {
if (hasher!=null) throw new Exception("hasher cannot be changed");
hasher = ahasher;
}
....
, а конструктор гарантирует, что пока хеш установлен
class Password {
...
public Password(String aPassword) throws Exception {
if (hasher==null) throw new Exception("no hasher set yet");
setPassword(aPassword);
}
...
, так хорошо.Но, на мой взгляд, это выглядит не очень хорошо.Интересно, есть ли какой-то общий шаблон для решения этой проблемы.Поэтому мой вопрос заключается в том, существует ли такая модель и как ее можно реализовать в моем случае.