gpt4 book ai didi

用于强制执行类先决条件的 java 设计模式

转载 作者:太空宇宙 更新时间:2023-11-04 10:08:08 27 4
gpt4 key购买 nike

我想知道在构建时执行全类先决条件的最佳设计是什么。

让我举一个简化的例子。

我有一个代表安全字符串的类,例如密码。密码仅以其哈希表示形式存储。无法检查密码,只能根据尝试的值进行检查。

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),

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

客户端代码必须选择一个实现并设置哈希器。在那之前,没有人可以实例化密码。一旦设置,哈希器就无法更改。

这是设计决策。

目前,我声明了一个静态私有(private)变量,因此所有密码实例的哈希器都是相同的;以及一个强制 setter 一旦设置就不能更改。

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

到目前为止,一切都很好。但是,在我看来,它看起来不太好。我想知道是否有一些通用的模式可以解决这个问题。所以我的问题是这样的模式是否存在以及如何在我的案例中实现它。

最佳答案

我建议更改您的设计并尝试以不同的方式进行处理。首先,进行一些重构。构造函数不应包含任何代码。其次,你制作哈希器的接口(interface)很棒。尽管如此,我会将其重构为:

public interface Hash {
String hashed(String value);
boolean isValid(String hashed);
}

接下来,更改您的密码类别:

public class Password {

private String password;
private Hash hash;

public Password(String password, Hash hash) {
this.password = password;
this.hash = hash;
}

public boolean isValid(String password) {
return hash.hashed(this.password).equals(hash.hashed(password);
}
}

这将是一个优雅的设计。您只需要确保通过构造函数传递正确的哈希实现即可。一旦设定好,每个密码都将被验证为相同的实现。

关于用于强制执行类先决条件的 java 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52683452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com