何时使用JavaFX属性setter和getter,而不是直接使用该属性

时间:2015-11-20 19:04:31

标签: java javafx properties setter getter

我熟悉Java,但刚刚开始学习JavaFX,并专门了解JavaFX属性。我理解Oracle的以下示例中显示的基本设计模式:

package propertydemo;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

class Bill {

    // Define a variable to store the property
    private DoubleProperty amountDue = new SimpleDoubleProperty();

    // Define a getter for the property's value
    public final double getAmountDue(){return amountDue.get();}

    // Define a setter for the property's value
    public final void setAmountDue(double value){amountDue.set(value);}

     // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {return amountDue;}

}

我不明白何时/为什么我会使用getter和setter方法,而不是直接使用属性?

我在想的是你可能想要在getter和/或setter中有一些自定义代码可能会对数据进行一些操作前/操作/验证,但如果你创建了一个自定义的getter和/或setter,你会得到不同的结果,取决于你是否直接使用getter / setter或属性,这对我来说似乎很危险。

如果getter / setter只是调用Property的get和set方法,那么为什么要使用它们?

对此有任何见解将不胜感激。

1 个答案:

答案 0 :(得分:13)

JavaFX属性模式旨在扩展旧的标准JavaBean模式。因此,在您的示例中,根据JavaBean约定,您具有名为double的{​​{1}}类型的(读写)属性。这由两种方法决定

amount

JavaBean模式通过“绑定属性”允许一些有限的“可观察性”,其中bean支持注册PropertyChangeListener。 UI工具包通常需要观察属性并响应更改。例如,public double getAmount() ; public void setAmount(double amount); 具有Label属性是有意义的。如果text属性发生更改,则需要通知text,以便它知道重新绘制自己。乍一看,使用具有绑定属性的JavaBeans将是一种方法。但是,在UI工具箱中使用此机制会产生性能问题,因为如果不立即计算值,则无法通知值不再有效。这意味着,例如,对属性的每次更改都会重新计算布局。

JavaFX团队显然希望做的是定义一个模式

  1. 符合标准JavaBean模式和
  2. 支持的可观察属性,其中可以跟踪失效,而无需在每次更改值时重新计算相关值(“延迟可观察值”)
  3. 因此,JavaFX解决方案是创建支持Label的属性,这些属性在值更改时得到通知,而ChangeListener s则在值不再有效时通知。这意味着,例如,布局机制可以跟踪它当前是否有效,而不会在它变为无效时强制重新计算。布局只会重新计算实际的屏幕脉冲(即渲染场景时),并且只有在无效时才会重新计算。

    (作为一个快速概念验证,请考虑以下内容:

    InvalidationListener

    请注意,DoubleProperty width = new SimpleDoubleProperty(3); DoubleProperty height = new SimpleDoubleProperty(4); ObservableDoubleValue area = Bindings.createDoubleBinding(() -> { double a = width.get() * height.get(); System.out.println("Computed area: "+a); return a ; }, width, height); System.out.println("Area is "+area.getValue()); width.set(2); height.set(3); System.out.println("Area is "+area.getValue()); 为2且width仍为4时,中间值永远不会计算。)

    因此,JavaFX中的值由这些可观察的Properties表示,它支持无效监听器和更改侦听器,这意味着它们基本上是“懒惰地可观察”。通过属性访问器方法(在您的示例中为height)公开属性本身就足以支持此功能。

    然而,在语义上,公开amountProperty()意味着bean的值为DoubleProperty。为了保持与旧JavaBean约定的兼容性,此bean应通过公开相应的doubleget方法来宣传此事实。因此,JavaFX Property模式既需要“属性访问器”(set),也需要标准的JavaBean方法(amountProperty()getAmount())。这意味着遵循JavaFX模式的bean可以在使用标准JavaBean模式的任何地方使用,例如在JPA中。

    请注意,要使模式正常工作,setAmount(...)amountProperty().get() == getAmount()amountProperty().set(x)具有相同效果的情况应始终如此。通过制作setAmount(x)get方法set,可以保证(即使bean类是子类),如示例所示。

    如果您自己调用方法来检索或更改属性的值,则调用哪个并不重要,因为它们可以保证具有相同的效果。由于JavaFX Property模式是JavaBean模式的扩展,因此调用finalget方法可能会有一点点偏好:在某种意义上,访问该值只需要JavaBean功能,而不是完整的JavaFX属性功能,因此它可能只是依赖于该功能而具有某种语义意义。然而,在实践中,你使用它没有任何区别。

相关问题