2017-06-17 75 views
1

JAVA 8它是不好的設計,如果我們在實體類

的getter和setter添加邏輯我有一個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編碼規則,如果我添加邏輯改變密碼,它打破設計或者設計不好?

使用它時,我收到了來自我的教授的糟糕設計反饋。

+1

您正在使用get/setter,然後只是用變量獲取和設置值,不要做其他任何事情。因爲它的設計需要這樣,所以如果你需要處理一些事情,那麼就單獨做。只是想象你爲其他人公開你的pojo類,他們不知道你已經加密了密碼,然後他們再次這樣做。這很糟糕 –

+3

看看https://stackoverflow.com/questions/1568091/why-use-getters-and-setters。最上面的答案提到了你的用例 - 使用不同於你的界面公開的表示。 –

+0

@CameronSkinner,這意味着我們應該這樣做。對 ? –

回答

3

wiki article on mutators

通常,一個設置器伴隨的吸氣劑(也被稱爲訪問器),它返回私有成員變量的值

由於吸氣劑是旨在提供私人字段值的訪問權限,這將違反principle of least astonishment:可能會拋出異常,EncrpytionFactory的impl在某些時候可能會失效,等等......當開發人員期望只訪問av ALUE。

您是否認爲這個糟糕的設計取決於您的設計標準有多嚴格。以確定最好的辦法是看缺點:

  • 無法獲得加密口令
  • 被迫使用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

從wiki文章:

訪問器反過來允許從內部變量有用數據表示的合成,同時保持它們的結構封裝並且從外部模塊隱藏。 貨幣getAmount訪問器可以從數值變量中構建一個字符串,其中隱藏貨幣參數定義小數位數。


在你的情況下,有更多的擔心。

你真的想要解密密碼,因爲在有什麼理由嗎?假設您想維護安全性,有更安全的方法來維護密碼。

無論何時您想將輸入的密碼與存儲的密碼進行比較,只需輸入輸入的密碼並將結果與​​存儲的密碼進行比較即可。

如果有人想要「恢復」他們的密碼,以純文本形式發送用戶的密碼會帶來安全風險。這就是爲什麼大企業要求您在忘記密碼時重置密碼的原因。


假設你想保留解密。

你真的需要每次解密有人打電話getPassword()?如果有人想要加密的值怎麼辦?

你應該保持解密與訪問分開。眼看你怎麼已經有一個EncryptionFactory

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

應該只有幾次在您的密碼確實存在解密(有些人可能會認爲這應該不會存在解密在內存中)。要點是,它應該是完全可選的。

密碼應該已經被加密設置:

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

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

應該在encrpyted形式訪問。你永遠不應該強制這樣的安全風險(解密密碼),使其成爲可選項。雖然這個介紹unneccesary耦合betweeing User(或站立着使用任何類型)和EncryptionFactory

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

最後,如果你必須暴露解密getPassword替代,你應該把它重命名爲decryptPassword()

您應該更深入地瞭解安全問題。您should not be maintaining decrypted passwords as Stringit's safest if no one but the user knows the password

相關問題