2017-07-24 52 views
-1

我問這個問題上Code Review,但有人把它擱置說,這是比較合適的在這裏提出它,所以現在的問題是構建的類和方法的Java

假設我有一個應用程序並且該應用程序有一個類爲我從一個方法生成一個隨機字符串,然後我從該字符串創建一個祕密。

的代碼是類似於以下,

public class MyRandomStringGeneratorClass 
{ 
    private String generatedRandomString; 
    public String generateRandomString() 
    { 
     //some logic 
     this.generatedRandomString = someRandomStringGenerator(); 
    } 
    public String generateSecretFromGeneratedRandomString() 
    { 
     //some encryption of the String 'generatedRandomString' 
    } 

} 



public class MainClass 
{ 
    public static void main(String args[]) 
    { 
     MyRandomStringGeneratorClass obj = new MyRandomStringGeneratorClass(); 
     String randomString = obj.generateRandomString(); 
     String secretFromRandomString = obj.generateSecretFromGeneratedRandomString(); 
    } 
} 

與上面的代碼的問題是,如果API的用戶並沒有產生什麼隨機字符串,並呼籲該保密信息生成方法的前期。這將會給他/她一個空指針錯誤,即

public class MainClass 
{ 
    public static void main(String args[]) 
    { 
     MyRandomStringGeneratorClass obj = new MyRandomStringGeneratorClass(); 
     // String randomString = obj.generateRandomString(); 
     String secretFromRandomString = obj.generateSecretFromGeneratedRandomString(); 
    } 
} 

我想在這種情況下,我能做到的最好的事情是把在祕密生成方法的空檢查該字段,如果它爲空,登錄一個消息在控制檯給用戶,你必須首先生成一個字符串來獲取該字符串的祕密,但它似乎有點老生常談。

public class MyRandomStringGeneratorClass 
{ 
    private String generatedRandomString; 
    public String generateRandomString() 
    { 
     //some logic 
     this.generatedRandomString = someRandomStringGenerator(); 
    } 
    public String generateSecretFromGeneratedRandomString() 
    { 
     if(generatedRandomString==null)logSomeErrorAndReturn(); 
     //some encryption of the String 'generatedRandomString' 
    } 

} 

我能想到的另一件事是從方法generateSecretFromGeneratedRandomString()內調用方法generateRandomString()。這將確保String確實生成並且ecryption也在相同的位置執行。

public class MyRandomStringGeneratorClass 
{ 
    private String generatedRandomString; 
    private String generateRandomString() 
    { 
     //some logic 
     this.generatedRandomString = someRandomStringGenerator(); 
    } 
    public String generateSecretFromGeneratedRandomString() 
    { 
     generatedRandomString=generateRandomString(); 
    // encrypt the String now 
    } 

} 

但是我可能無法返回純生成的隨機字符串(不聲明字段作爲公共或除非我提供相同的吸氣劑的方法)。 請建議適當的方法。詢問是否需要進一步澄清。

+0

您已經知道如何檢測情況。當你找到它時,你該怎麼做。拋出異常? – John3136

回答

0

爲什麼您需要將generateRandomString暴露給用戶?我只是讓它的實現細節,並將其封裝內generateSecretFromGeneratedRandomString

public String generateSecretFromGeneratedRandomString() { 
    if (generatedRandomString == null) { 
     generatedRandomString = generateRandomString(); 
    } 
    //some encryption of the String 'generatedRandomString' 
    return encryptedString; 
} 
+0

不錯的地方:),但我需要公開它,因爲我在我的數據庫中保存加密以及普通數據(認爲它不是密碼,而只是一個加密的字符串)。我認爲你要提出的下一個建議不是存儲無論是密碼還是其他內容的明文數據。但是,我正在保存自己的重複加密解密過程。但你的建議是最受歡迎的。 – nobalG

0

您可以嘗試可選容器對象 - https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

public class MyRandomStringGeneratorClass 
{ 
    private Optional<String> generatedRandomString; 
    public String generateRandomString() 
    { 
     //some logic 
     this.generatedRandomString = Optional.of(someRandomStringGenerator()); 
     return generatedRandomString.get() 
    } 
    public String generateSecretFromGeneratedRandomString() 
    { 
     if(generatedRandomString.isPresent()) 
     { 
      //some encryption of the String 'generatedRandomString' 
     } 
     else 
     { 
      // generatedRandomString is null and you can create new one and encrypt it 
     } 

    } 
} 
+0

這與'generatedRandomString == null'相同嗎?如果你只使用一個庫的一個功能性,而不是像這裏那樣容易複製,那麼是否值得包含這個庫? – Shirkam

+0

可選僅用於此用例。Java 8告訴您避免使用空檢查和NPE ..它並不昂貴地使用它。 – Pavan

0

兩者(generateRandomString和generateSecretFromGeneratedRandomString)方法可以聲明public返回普通的String和加密的String。如果隨機字符串不是先前生成的,則從generateSecretFromGeneratedRandomString方法獲取新的隨機字符串。

+0

是的,可以做... – nobalG

0

檢查generateSecretFromGeneratedRandomString()方法中的Null值,如果值爲null,則拋出一個自定義異常,然後處理該異常並要求用戶在生成密鑰之前生成一個隨機字符串。安全和簡單。

+0

嗯...尼斯點.. – nobalG

0

怎麼樣的不變RandomString類:

public class RandomString { 

    private final String randomString; 
    private final String secret; 

    public RandomString() { 
     this.randomString = someRandomStringGenerator(); 
     this.secret = computeSecret(this.randomString); 
    } 

    public String getString() { 
     return randomString; 
    } 

    public String getSecret() { 
     return secret; 
    } 

} 

public class MainClass { 
    public static void main(String args[]) { 
     final RandomString randomString = new RandomString(); 
     System.out.println(randomString.getString()); 
     System.out.println(randomString.getSecret()); 
    } 
} 
+0

是的,似乎有效.. – nobalG

0

如果你想執行的順序,仍然保持壓倒一切都在微方法打開覆蓋,模板方法設計模式可以是選項用過的。

public class RndStringGenerator { 
    private String randomString; 
    public final String getSecretString() { 
     generateRndString(); 
     return generateSecret(); 
    } 
    public String getGeneratedRndString() { 
     if (randomString == null) { 
      generateRndString(); 
     } 
     return randomString; 
    } 
    protected void generateRndString() { 
     // some logic 
     this.randomString = "Assume its Random String"; 
    } 
    protected String generateSecret() { 
     // some encryption 
     return randomString; 
    } 
} 

這是模板方法,它將允許覆蓋受保護的方法,但會鎖定最終的方法覆蓋以維護序列。

+0

你可以指點一些代碼示例嗎? – nobalG