繁体   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