更优雅的编码方式 Setter

More Elegant Way of Coding a Setter

我想知道他们是否是编写 setter 的更聪明、更优雅的方式,或者就此而言,任何必须检查用户输入是否正确的代码

这看起来很奇怪。我是新手,所以也许这只是解决这个问题的标准方法,但如果不是,我很想知道 'smart' 方法是什么

public void setMonth(){
    boolean run = true;
    while(run){
        int input = scan.nextInt();
        if(input > 0 && input < 13){
            this.month = input;
            run = false;
        }
    }
}

首先你可以像这样简化你的代码:

 public void setMonth() {
    int input = 0;
    do {
       input = scan.nextInt();
    } while(input <= 0 || input >= 13)

    this.month = input;
 }

除此之外,我将其分为两个函数。 setter 应该只设置一个值。

 public void setMonth(int month) {
    if(month > 0 && month <= 12) {
       this.month = month;
   } else {
        throw new IllegalArgumentException("Month has to be a value between 1 and 12 inclusively. Actual value was :" + month);
    }
 }

 public void readMonth() {
    int input = 0;
    do {
       input = scan.nextInt();
     } while(input <= 0 || input >= 13)

   setMonth(input);
 }

根据 ChiefTwoPencils 的建议,您还可以将 setter 提取到另一个 class 中。从而进一步分离用户输入和数据。

 class MonthDataHolder {
     private int month;

      public MonthDataHolder(int month) {
           setMonth(month);
     }

     public void setMonth(int month) {
        if(isValidMonthValue(month)) {
            this.month = month;
        } else {
             throw new IllegalArgumentException("Month has to be a value between 1 and 12 inclusively. Actual value was :" + month);
         }
     }

      private boolean isValidMonthValue(month) {
           return month >= 1 || month <= 12;
      }
 }

 class InputReader {

       public MonthDataHolder readMonth() {
         int input = 0;
         do {
           input = scan.nextInt();
          } while(input <= 0 || input >= 13)

          return new MonthDataHolder(input);
      }
 }

setters 和 getter 也被称为修改器和访问器。

我的理解是,这些方法仅用于检索或修改对象的 'state'。它不应该有业务逻辑,或者应该尽可能少地包含业务逻辑。

基本都有Computations/Business逻辑,便宜。

使您的 setter 仅 'set' 值。

public void setMonth(int month){
    this.month = month
}

虽然基于输入检索值的方法可以在其他任何地方重复使用,但我建议您可以创建一个实用程序 class 并将其作为静态方法。

class DateUtil {
    public static int retrieveMonthBasedOnInput(){
    }
}

此 class 应该具有从用户输入中检索详细信息的业务逻辑,因此应该在尝试设置该 bean 实例的值时使用。

功能要简单,只做一个工作。也许你可以这样编码:

public void setMonth(int month) throws IllegalArgumentException {
    if(month<0 || month>11) throw new IllegalArgumentException("Month can only be set 0~11");
    this.month = month;
}

如您所见,该函数只做一件设置月份的事情。如果参数不正确,则抛出异常。

写作规则"good"更严格:

1) 不要在 setter 中进行任何输入输出操作,例如访问数据库、文件、网络、发送电子邮件、从命令行读取等...如果必须,请在之前或之后进行你调用 setXXX,最好为此编写一些服务方法。

2) setter中的逻辑越少越好。可以进行范围检查等参数验证...

3) Setter 应该只做它设计的一件事(设置一个值),它不应该有任何副作用。