[英]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.