2016-09-06 2 views
1

Как должны быть выставлены свойства?Воздействующие свойства для переплета

Например:

class A{ 
    private ObjectProperty<X> objx; 
} 

class B{ 
    private ObjectProperty<X> objy; 
} 

Мы хотим связать objy с objx или добавить слушателя objx из B. Это просто, чтобы просто получить геттер для objx? или есть способ сделать функцию обертки для привязки и выставить только эту функцию?

ответ

4

standard pattern является

class A { 
    private final ObjectProperty<X> objx = new SimpleObjectProperty<>(); 

    public ObjectProperty<X> objxProperty() { 
     return objx ; 
    } 

    public final X getObjx() { 
     return objxProperty().get(); 
    } 

    public final void setObjx(X objx) { 
     objxProperty().set(objx); 
    } 
} 

Идея заключается в том, что у вас есть акцесор для свойства самого (а «свойство аксессора»: objxProperty()), которые могут быть использованы для связывания и регистрации слушателей, но свойство также появляется как обычный Java Bean: т.е. существуют стандартные методы get и set. Общий контракт заключается в том, что у вас всегда должно быть x.getObjx() == x.objxProperty().get(), что обеспечивается применением методов доступа Java Bean (getObjx() и setObjx).

Если вы хотите, чтобы иметь возможность изменить свойство внутренне, но хочу только выставить только для чтения свойство (к которому другой код может связать) использовать ReadOnlyObjectWrapper:

class A { 

    private final ReadOnlyObjectWrapper<X> objx = new ReadOnlyObjectWrapper<>(); 

    public ReadOnlyObjectProperty<X> objxProperty() { 
     return objx.getReadOnlyProperty(); 
    } 

    public final X getObjx() { 
     return objxProperty().get(); 
    } 

} 

также посмотреть на this powerpoint presentation который, будучи старым, показывает много полезных идиом, таких как ленивая и супер-ленивая инициализация собственности.

3

Следующая структура широко используется в JavaFX:

class A { 

    // Private inner property 
    private ObjectProperty<X> objx; 

    // Public property accessor method 
    public final ObjectProperty<X> objxProperty() { 
     if (objx == null) 
      objx = new SimpleObjectProperty<X>(DEFAULT_VALUE); 

     return objx; 
    } 

    // Public setter method 
    public final void setObjx(X val) { 
     objxProperty().set(val); 
    } 

    // Public getter method 
    public final X getObjx() {return objx == null ? DEFAULT_VALUE : objx.get();} 

} 

То, что вы можете увидеть здесь называется lazy initialization. Фокус в том, что частное внутреннее свойство не инициализируется до тех пор, пока оно (действительно) не будет запрошено.

Приобретение общественной собственности objxProperty() будет инициализировать частную внутреннюю собственность objx. Этот метод доступа к ресурсам используется для отображения внутреннего свойства для привязки и прослушивания. Частное внутреннее свойство получает суффикс «Свойство», который можно рассматривать как соглашение в JavaFX.

Общепринятый метод настройки setObjx использует этот метод доступа к свойству, поэтому в случае запроса установить значение этого свойства, внутреннее свойство будет инициализировано.

Это немного отличается в случае публичного getter getObjx(), как если бы внутреннее свойство еще не инициализировалось (нет запроса прямого доступа к этому свойству и никакого заданного запроса до этого), значение по умолчанию возвращается непосредственно без инициализации внутреннее свойство, дополнительно задерживая процедуру инициализации.

Вы можете увидеть эту технику, например, в случае alignmentProperty из TextField в JavaFX.

Если вы не хотите усложнять ситуацию, «стандартный шаблон», объясненный James_D в его ответе, действительно является стандартом (имя метода такое же, как здесь).

+0

Извините, я неправильно прочитал. Я думал, что objxProperty() будет конструктором. Ваш код в порядке. – GhostCat

Смежные вопросы