gpt4 book ai didi

java - 如果我们在实体类的getter和setter中添加逻辑是不是不好的设计

转载 作者:行者123 更新时间:2023-11-30 06:06:16 25 4
gpt4 key购买 nike

Java 8

我有一个 POJO 类:

class User {
private String name;
private String password;

//... Getters / Setters ...
}

我将把它用作实体类。

password的getter/setter中,我想添加解密/加密逻辑。

public String getPassword() {
return EncryptionFactory.decryption(password);
}

public void setPassword(String password) {
this.password = EncryptionFactory.encryption(password);
}

EncryptionFactory 是一个实用程序类,用于加密/解密 String

我的问题是

根据通用 Java 编码指南,如果我添加更改密码的逻辑,它会破坏设计还是糟糕的设计?

在使用它时,我从我的教授那里得到了糟糕的设计反馈。

最佳答案

来自wiki article on mutators :

Often a setter is accompanied by a getter (also known as an accessor), which returns the value of the private member variable

由于 getter 旨在提供对私有(private)字段值的访问权限,因此它会违反 principle of least astonishment : 可能会抛出异常,EncrpytionFactory 的实现可能在某些时候变得无效,等等......当开发人员期望简单地访问一个值时。

您是否认为这种糟糕的设计取决于您的设计标准有多严格。确定的最佳方法是查看缺点:

  • 无法获取加密密码
  • 强制使用String作为纯文本密码来存储密码(因为setPassword会自动加密)
  • 在包含get/setPassword的类型中引入EncrpytionFactory的依赖性

因此在您的特定情况下,这是糟糕的设计。

尽管在某些情况下,某些开发人员可能更喜欢它。例如,如果您有一个 Person#getAge() : int 但使用 Date 属性来管理此人的年龄:

class Person {
private Date dateOfBirth;

public int getAge() {
Date now = ...; //grab date/time right now
int age = ...; //calculate age using dateOfBirth and now

return age;
}

有些人认为计算应该解耦,或者 getAge 应该命名为 calculateAge

来自维基文章:

Accessors conversely allow for synthesis of useful data representations from internal variables while keeping their structure encapsulated and hidden from outside modules. A monetary getAmount accessor may build a string from a numeric variable with the number of decimal places defined by a hidden currency parameter.


对于你的情况,还有更多需要担心的。

你真的想解密密码吗,有什么理由吗?假设您想要维护安全,有更安全的方法来维护密码。

任何时候您想将输入的密码与存储的密码进行比较,只需对输入的密码进行加密并将结果与​​存储的密码进行比较即可。

如果有人想“恢复”他们的密码,以纯文本形式向用户发送密码会存在安全风险。这就是大型企业要求您在忘记密码时重设密码的原因。


假设您想保留解密。

您真的需要每次有人调用getPassword() 时解密吗?如果有人想要加密的值怎么办?

您应该将解密与访问分开。看看你是如何拥有一个 EncryptionFactory 的:

User user = ...;
String encryptedPassword = user.getPassword();
String decryptedPassword = EncryptionFactory.decryption(encryptedPassword);

您的密码实际存在解密的次数应该很少(有些人可能会争辩说它永远不应该在内存中解密)。重点是,它应该是完全可选的。

密码应该设置为已经加密:

String encryptedPassword = EncryptionFactory.encrpytion(...);

User user = ...;
user.setPassword(encryptedPassword);

它应该以加密形式访问。你永远不应该强加这样的安全风险(解密密码),让它成为可选的。

最后,如果您必须公开解密的getPassword 替代方案,您应该将其重命名为decryptPassword():

public String decryptPassword() {
return EncrpytionFactory.decryption(getPassword());
}

尽管这在 User(或您使用的任何类型)和 EncryptionFactory 之间引入了不必要的耦合。

您真的应该更深入地了解安全方面。你should not be maintaining decrypted passwords as String , 和 it's safest if no one but the user knows the password .

关于java - 如果我们在实体类的getter和setter中添加逻辑是不是不好的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44600536/

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