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