簡體   English   中英

構造函數中邏輯的最佳實踐是什么? (爪哇)

[英]What is the best practice for logic inside a constructor? (Java)

我正在學習 Java,我使用的資源之一是 Coursera。 對於其中一項任務,我正在為 CaesarCipher class 編寫一個構造函數,其中我正在初始化字母表和“移位”字母表。

public CaesarCipher(int key) {
    this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    this.shifted = alphabet.substring(key) + alphabet.substring(0, key);
}

這個想法是,當您在構造函數中給出“鍵”時,它會相應地移動字母表。 我注意到的一個可能的問題是,如果鍵比字母字符串長,那么您將收到索引越界錯誤。 為了防止這種情況,我假設我們可以在構造函數中編寫邏輯,如下所示:

public CaesarCipher(int key) {
    while(key > 26) {
        key = key - 26;
    }
    this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    this.shifted = alphabet.substring(key) + alphabet.substring(0, key);
}

在參加本課程之前對 Java 有一些了解,盡管我知道您通常不會在構造函數中包含邏輯。 對於這樣的情況,最佳做法是什么?

我會說,除了驗證之外,構造函數中不應該有任何邏輯。 所以對於你的例子:

public CaesarCipher(int key) {
    if(key < 0){
       throw new IllegalArgumentException("key < 0");
    }
    key%=26;//Replaces the while loop
    this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    this.shifted = alphabet.substring(key) + alphabet.substring(0, key);
}

這種方法的優點是,它會快速失敗,並且以后不會在某個地方顯示錯誤。 看這個例子:

public class Foo{
   private String bar;
   public Foo(String s){
      this.bar = s;
   }

   public int getLengthOfBar(){
       return this.bar.length();
   }
   
   public static void main(String[] args){
      String s=getStringFromSomewhere();//May return null
      Foo f=new Foo(s);
      ...Some code....
      int len = f.getLengthOfBar(); //BOOM, if s is null, it will fail with a NullPointer Exception.
      ...Do something with len....
   }
}

如果你在構造函數中添加一個檢查,你會很快看到你不應該通過null 是的,您也可以向getLengthOfBar添加一個檢查,但我真的認為,您應該在構造函數中進行驗證。 (至少對於像 Nullchecks、ranges、...這樣的小型檢查)

只需接受構造函數中的key (通過將其設為private final int使其不可變是一種很好的做法),然后使用https://en.wikipedia.org/wiki/Single-responsibility_principle方法使用該key執行某些操作。

alphabet也可以是public static final String

shifted看起來對我來說應該是一種方法。

這是我將如何實現它。

public class CaesarCipher {
    private int key;
    private String alphabet;

    public CaesarCipher(int key) {
        this.key = key;
        this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    }

    public String shift(){
        int key = getKey();
        return alphabet.substring(key) + alphabet.substring(0, key);
    }

    public int getKey(){
        return  key % 26;
    }

    public static void main(String[] args) {
        CaesarCipher cc = new CaesarCipher(31);
        System.out.println(cc.shift());
    }
}

編輯:根據上述評論/答案,可以對密鑰進行驗證,例如

    public int getKey(){
        if(key<0) {
            throw new IllegalArgumentException("Key < 0");
        }
        return  key % 26;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM