2015-11-20 27 views
6

Jestem zaznajomiony z Javą, ale dopiero zaczynam uczyć się JavaFX, a konkretnie poznaję właściwości JavaFX. Rozumiem podstawowy wzorzec projektowy, jak pokazano w poniższym przykładzie Oracle:Kiedy używać funkcji ustawiania i pobierania właściwości języka JavaFX, zamiast korzystać z właściwości bezpośrednio

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;} 

} 

Co ja nie rozumiem, kiedy/dlaczego miałbym użyć metod getter i setter, zamiast korzystania z personelem?

Pomyślałem, że możesz potrzebować niestandardowego kodu w geterze i/lub seterze, który może wykonać pewne operacje przed lub po manipulowaniu/sprawdzeniu danych, ale jeśli utworzysz niestandardowy program pobierający i/lub ustawiający, uzyskałoby wtedy różne wyniki, w zależności od tego, czy użyjesz gettera/setera, czy też nieruchomości bezpośrednio, co wydaje mi się niebezpieczne.

Jeśli getter/setter po prostu wywołuje metody pobierania i ustawiania właściwości, to po co je mieć?

Wszelkie uwagi na ten temat będą mile widziane.

+0

od [dowiedz się ebook javafx] (http://www.apress.com/9781484211434). 'Dodatkowe moduły pobierające i ustawiające, wykorzystujące konwencję nazewnictwa JavaBeans, są dodawane w celu zapewnienia współdziałania klasy ze starszymi narzędziami i strukturami, które używają starych konwencji nazewnictwa JavaBeans do identyfikowania właściwości klasy. ' – Kachna

+0

Moim zdaniem dodatkowe pobierające i ustawiające nie są wymagane. – Kachna

+0

@Kachna Z pewnością to zależy od twojego przypadku użycia. Np. Jeśli chcesz używać właściwości JavaFX w jednostce JPA, potrzebujesz metod get i set. Podobnie, jeśli używasz zestawiania JSON lub XML, itp. –

Odpowiedz

11

Wzorzec właściwości JavaFX ma na celu rozszerzenie starego, standardowego wzorca JavaBeans. Tak więc w twoim przykładzie, zgodnie z konwencją JavaBean, masz właściwość (do odczytu i zapisu) typu double o nazwie amount. Określone jest to za pomocą dwóch metod

public double getAmount() ; 
public void setAmount(double amount); 

Wzór JavaBeans umożliwia pewne ograniczone „obserwowanie” poprzez „właściwości związany”, w których ziarna wspierają rejestracji PropertyChangeListener. Zestaw narzędzi interfejsu użytkownika często musi obserwować właściwości i reagować na zmiany. Na przykład sensowne jest, aby Label miał właściwość text. Jeśli zmieni się właściwość text, należy powiadomić o numerze Label, aby wiedział, że jest odświeżany. Na pierwszy rzut oka zastosowanie tego może mieć JavaBeans z właściwymi właściwościami. Jednak użycie tego mechanizmu w zestawie narzędzi interfejsu użytkownika powoduje problemy z wydajnością, ponieważ nie ma możliwości powiadomienia, że ​​wartość nie jest już ważna bez natychmiastowego obliczenia. Oznacza to na przykład, że układ będzie przeliczony na każdą indywidualną zmianę właściwości.

Co zespół JavaFX najwyraźniej dążyły do ​​zrobienia było określić wzorzec, który

  1. odpowiadało standardowej JavaBeans wzór i
  2. obsługiwane właściwości obserwowalne gdzie unieważnienie może być śledzone bez ponowne obliczanie Wartości zależne za każdym razem wartość zmieniła („wartości leniwie obserwowalne”)

więc rozwiązanie JavaFX jest stworzenie właściwości, które obsługują zarówno ChangeListener S, który jest powiadamiany o zmiany wartości, a InvalidationListener s, które są powiadamiane, gdy wartość nie jest już ważna. Oznacza to, że na przykład mechanizm układu może śledzić, czy jest on aktualnie prawidłowy, bez wymuszania ponownego obliczania, gdy stanie się on nieprawidłowy. Układ zostanie przeliczony tylko na rzeczywistym impulsu ekranu (to znaczy, gdy scena jest renderowana) i tylko wtedy, gdy jest nieważny.

(Jako proof-of-concept szybki, należy rozważyć następujące kwestie:

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()); 

tu zauważyć, że wartość pośrednia, kiedy width jest 2 i height jest nadal 4, nigdy nie jest obliczana.)

Więc wartości w JavaFX są reprezentowane przez te obserwowalne Properties, które obsługują zarówno detektory unieważniania, jak i zmieniają detektory, co oznacza, że ​​są w zasadzie "leniwie obserwowalne". Odsłanianie samej właściwości za pomocą metody dostępu do właściwości (amountProperty() w twoim przykładzie) wystarcza do obsługi tej funkcji.

Jednak w wyniku semantyki oznaczenie DoubleProperty oznacza, że ​​ziarno ma wartość typu double. Aby zachować zgodność ze starą konwencją JavaBeans, komponent bean powinien zareklamować ten fakt, ujawniając odpowiednie metody. W związku z tym wzorzec właściwości JavaFX wymaga zarówno "akcesora właściwości" (amountProperty()), jak i standardowych metod JavaBeans (getAmount() i setAmount(...)). Oznacza to, że komponenty bean zgodne ze wzorcem JavaFX mogą być używane wszędzie tam, gdzie używany jest standardowy wzorzec JavaBeans, na przykład w JPA.

Należy pamiętać, że aby wzór działał poprawnie, zawsze powinno być prawdą, że amountProperty().get() == getAmount() i że amountProperty().set(x) ma taki sam efekt jak setAmount(x). Jest to gwarantowane (nawet jeśli klasa komponentu bean jest z podklasą), wykonując metody get i set, jak w twoim przykładzie.

Jeśli samodzielnie przywołujesz metody pobierania lub zmiany wartości nieruchomości, nie ma znaczenia, do kogo zadzwonisz, ponieważ gwarantują one ten sam efekt. Ponieważ wzorzec JavaFX Property jest rozszerzeniem wzorca JavaBean, może występować niewielka preferencja dla wywoływania metod get i set: w pewnym sensie uzyskiwanie dostępu do wartości wymaga tylko funkcji JavaBeans, a nie pełnej funkcjonalności właściwości JavaFX, więc może uczynić semantyczny sens, aby polegać tylko na tej funkcjonalności. W praktyce jednak nie ma różnicy, której używasz.

+1

Dziękuję za szczegółowe wyjaśnienie. Co o przypadku, gdy seter faktycznie manipuluje danych, na przykład, jeśli masz StringProperty Imię: 'firstName.set (name.trim())' W tym przypadku wywołanie metody setter jest inna niż nazywając 'set()' na właściwości, czy jest to nie-nie z właściwościami JavaFX. – vewert

+0

Przepraszamy, chciałem dodać bardziej szczegółowy przykład, ale wydaje się, że nie można dodawać bloków kodu do komentarzy. – vewert

+1

W tym przykładzie łamiesz wiele konwencji. Jak wspomniano, we wzorcu właściwości JavaFX należy zagwarantować, że 'setFirstName (x)' jest równoważne 'firstNameProperty() .set (x)'. Ale w regularnej strukturze Java Bean, powinieneś naprawdę zagwarantować, że 'setFirstName (x); getFirstName() 'ocenia na' x', zakładając, że żadne inne operacje nie występują na obiekcie między dwoma wywołaniami metod. Jeśli naprawdę chciałeś coś takiego zrobić, podklasuj 'StringPropertyBase' i nadpisaj' setString (...) 'i' setValue (String) '. –