java 执行附加逻辑的 getter 和 setter

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7955319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 22:10:22  来源:igfitidea点击:

getters and setters performing additional logic

javapojo

提问by eliocs

I have a Java class which represents the correlation between two elements (typical POJO):

我有一个 Java 类,它表示两个元素(典型的 POJO)之间的相关性:

public class Correlation {

    private final String a;
    private final String b;

    private double correlation;

    public Correlation(String a, String b) {
        this.a = a;
        this.b = b;
    }

    public double getCorrelation() {
        return correlation;
    }

    public void setCorrelation(double correlation) {
        this.correlation = correlation;
    }

}

To follow the correct correlation logic if a equals b then the correlation value should be ALWAYS 1. I could add the logic altering the getter method (ignore the fact of the possible null value for a):

如果 a 等于 b,要遵循正确的相关逻辑,那么相关值应始终为 1。我可以添加更改 getter 方法的逻辑(忽略 a 可能为空值的事实):

public double getCorrelation() {
    if (a.equals(b)) {
        return 1D;
    } else {
        return correlation;
    }
}

What bothers me is adding this logic to a getter method, should I change the method name or documenting it should be considered enough?

困扰我的是将这个逻辑添加到 getter 方法中,我应该更改方法名称还是记录它应该足够了?

采纳答案by Nicola Musatti

Back in the early days of Java getter/setter pairs were used to identify propertiesof beansexactly for the purpose of making it possible to define conceptual attributes implemented through computation rather than a plain member variable.

早在早期,Java 的 getter/setter 对被用来准确识别bean 的属性,目的是使定义通过计算而不是普通成员变量实现的概念属性成为可能。

Unfortunately with the passing of time programmers have come to rely more and more on getter/setters being just accessors/mutators for underlying attributes, trend that was sort of made official with the introduction of the term POJOto identify objects that only had getters and possibly setters as methods.

不幸的是,随着时间的推移,程序员越来越依赖于 getter/setter 只是底层属性的访问器/修改器,随着术语POJO的引入,这种趋势有点正式化,以识别只有 getter 和可能的对象setter 作为方法。

On the other hand it is a good thing to distinguish objects that perform computations from objects that just carry data around; I guess you should decide which type of class you wish to implement. In your place I probably would make correlation an additional constructor argument and check it's validity there, rather than in your getter. Your Correlationcannot be a computational object, as it doesn't have enough information to perform any computation.

另一方面,将执行计算的对象与仅携带数据的对象区分开来是一件好事;我想您应该决定要实现哪种类型的类。在你的地方,我可能会将相关性作为一个额外的构造函数参数并在那里检查它的有效性,而不是在你的 getter 中。你Correlation不能是一个计算对象,因为它没有足够的信息来执行任何计算。

回答by cjstehno

Side effects in getters and setters is generally not a great idea as it is usually not expected and can lead to tricky bugs. I would suggest creating a "correlate()" method or something else that is not specifically a getter in this case.

getter 和 setter 中的副作用通常不是一个好主意,因为它通常不是预期的,并且可能导致棘手的错误。我建议创建一个“correlate()”方法或其他在这种情况下不是专门的吸气剂的方法。

Hope this helps.

希望这可以帮助。

回答by Dilum Ranatunga

It make more sense to enforce the value during setCorrelation(...). For example,

在 期间强制执行该值更有意义setCorrelation(...)。例如,

public void setCorrelation(double correlation) {
  if (a.equals(b)) {
    if (Math.abs(correlation - 1D) > EPSILON) {
      throw new InconsistentException(...);
    }
    this.correlation = 1D;
  } else {
    this.correlation= correlation;
  }
}

I would also consider making the correlation property a nullable, where a nullindicates that a correlation has not been set yet.

我还会考虑将相关属性null设为可为空,其中 a表示尚未设置相关性。

回答by jalopaba

Given that correlation is a somehow/sometimes "derived" value from a and b (i.e. it is 1 if a equals b, but it might be calculated in some original way depending on (a,b), a good option could be calculate the correlation in the constructor and throw an IllegalArgumentException within setCorrelation if the vaule violates the inner logic of the object:

鉴于相关性是从 a 和 b 以某种方式/有时“派生”的值(即,如果 a 等于 b,则为 1,但可能会根据 (a,b) 以某种原始方式计算,一个不错的选择是计算如果 vaule 违反了对象的内部逻辑,则在构造函数中关联并在 setCorrelation 中抛出 IllegalArgumentException:

public class Correlation {

    private final String a;
    private final String b;

    private double correlation;

    public Correlation(String a, String b) {
        this.a = a;
        this.b = b;
        calculateCorrelation();
    }

    protected calculateCorrelation() { 
        // open to more complex correlation calculations depending on the input,
        // overriding by subclasses, etc.
        if (a.equals(b)) {
            this.correlation = 1D;
        } else {
            this.correlation = 0;
        }
    }

    public double getCorrelation() {
        return correlation;
    }

    public void setCorrelation(double correlation) throws IllegalArgumentException {
        if (a.equals(b) && correlation != 1D) {
            throw new IllegalArgumentException("Correlation must be 1 if a equals b");
        }

        this.correlation = correlation;
    }
}

Following this scheme you could also "generify" your Correlation class.

按照这个方案,您还可以“生成”您的 Correlation 类。

回答by user949300

In the cases where a != b, how is correlation calculated?

在 a != b 的情况下,如何计算相关性?

If correlation is calculated primarily from a and b, setCorrelation() should be removed. Period. The correlation should be calculated in the constructor or in the getCorrelation() method. One principle of OOP is to group related data and logic, so the calculation of correlation should ideallybe done in the class you cleverly named Correlation. If the calculation is extremely complicated, it may be elsewhere, (e.g. DIP) but the call should be made from Correlation.

如果主要从 a 和 b 计算相关性,则应删除 setCorrelation()。时期。相关性应该在构造函数或 getCorrelation() 方法中计算。OOP 的一个原则是将相关的数据和逻辑分组,所以相关性的计算最好在你巧妙命名的类中完成Correlation。如果计算极其复杂,则可能在其他地方(例如 DIP),但应从 进行调用Correlation

If correlation is not calculated from a and b, I really don't understand the class, so "it depends". If a does equal b, and somebody calls setCorrelation(0.0), is the contract to quietly ignore the call and leave correlation at 1.0, or to throw an exception? And, if I'm writing the calling code, I'm in a quandary, since I don't know what will happen if I try to setCorrelation(0.0) because I have no idea what a and b are, or else everyplace I make the call I'm forced to go if (getA().equals(getB()))etc... or to catch the Exception and do, er, what??? Which violates DRY and is exactly why OOP says that the logic and data should be grouped together in a class.

如果相关性不是从 a 和 b 计算出来的,我真的不了解这个类,所以“这取决于”。如果 a 等于 b,并且有人调用 setCorrelation(0.0),那么契约是悄悄忽略调用并将相关性保留为 1.0,还是抛出异常?而且,如果我正在编写调用代码,我会陷入困境,因为我不知道如果我尝试 setCorrelation(0.0) 会发生什么,因为我不知道 a 和 b 是什么,或者我不知道任何地方打个电话,我被迫去if (getA().equals(getB()))等等......或者抓住异常然后做,呃,什么???这违反了 DRY,这正是 OOP 说逻辑和数据应该组合在一个类中的原因。

回答by AHungerArtist

I would say use something like getValue()

我会说使用类似 getValue()

回答by K2xL

If I were using your class I would expect getCorrelation() to return correlation. In fact, I would probably redesign the class to have static method correlateElements(String a, String b) that returns a double.

如果我正在使用您的课程,我希望 getCorrelation() 返回相关性。事实上,我可能会重新设计该类,使其具有返回双精度值的静态方法 correlateElements(String a, String b)。