Разрешает ли установщик Java bean вернуть это? - PullRequest
14 голосов
/ 21 апреля 2011

я могу определить метод установки для возврата этого, а не void?

Как:

ClassA setItem1() {
      return this;
}

ClassA setItem2() {
      return this;
}

тогда я могу использовать новый ClassA (). SetItem1 (). SetItem2 ()

Ответы [ 10 ]

14 голосов
/ 21 апреля 2011

Существует много недоразумений относительно спецификации JavaBeans.

Основная причина его существования - унифицированная модель Java "компонент". Это способ программного взаимодействия с Java-объектом с помощью Reflection. Сам API называется JavaBeans Introspection . Пожалуйста, ознакомьтесь с примерами использования, и Вы узнаете намного больше, чем обычный программист на Java.

API самоанализа можно использовать для унифицированного управления элементами графического интерфейса. Ваш компонент предоставляет свои свойства в виде пары методов получения и установки, чтобы их можно было обнаружить и манипулировать ими во время выполнения на странице свойств компоновщика графического интерфейса.

Итак, смешивать API и JavaBeans Spec на мой взгляд не стоит. Это две совершенно не связанные между собой концепции, которые могут нарушать друг друга. Самоанализ JavaBeans может не работать, если сигнатура метода отличается (тип возвращаемого значения).

Взгляните на этот пример (взят из связанного урока):

public class SimpleBean
{
private final String name = "SimpleBean";
private int size;

public String getName()
{
    return this.name;
}

public int getSize()
{
    return this.size;
}

public void setSize( int size )
{
    this.size = size;
}

public static void main( String[] args )
        throws IntrospectionException
{
    BeanInfo info = Introspector.getBeanInfo( SimpleBean.class );
    for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
        System.out.println( pd.getName() );
}
}

В этом примере создается невизуальный компонент и отображаются следующие свойства, полученные из объекта BeanInfo:

  • класс
  • имя
  • размер

Возможно, вы захотите посмотреть, что произойдет, если вы измените тип возврата void на что-либо еще. Я так и сделал, и результат тот же. Так значит ли это, что это разрешено?

Боюсь, нет. Спецификация JavaBeans довольно строга в отношении этих сигнатур методов. Просто так получилось, что реализация прощает. Тем не менее, я бы не советовал смешивать свободный интерфейс с JavaBeans. Вы не можете полагаться на это, если открытие работает сейчас, оно также будет и в будущем.

Но с другой стороны - похоже, вы не используете JavaBeans в полной мере. Только пара методов получения / установки. Вам решать, как Вы реализуете и разрабатываете свои API.

13 голосов
/ 21 апреля 2011

Спецификация JavaBeans описывает JavaBean как:

Java Bean - это программное обеспечение многократного использования компонент, которым можно манипулировать визуально в конструкторе

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

Обычно вызывается «Java Bean» для простого старого Java-объекта с методами доступа, следуя спецификации JavaBeans (раздел 7.1 и 8.3). Правда состоит в том, что такой объект все еще может быть далеко не соответствующим всем требованиям.

Если объект, который вы определяете в этом классе, на самом деле является JavaBean, тогда ваш метод должен вернуть void в соответствии со Спецификацией JavaBean, раздел 7.1, где методы доступа описаны следующим образом:

void setFoo(PropertyType value); // simple setter
PropertyType getFoo(); // simple getter

В разделе 8.3 названы разработанные шаблоны для свойств:

По умолчанию мы используем шаблоны проектирования для поиска свойств путем поиска методов вида:

public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);

Кроме того, для логических свойств мы разрешаем методу getter соответствовать шаблону:

public boolean is<PropertyName>();

Однако, если ваш класс - просто POJO, то нет ничего плохого в использовании стратегии цепочки методов, поскольку вам разрешено отклоняться от спецификации, поскольку вы на самом деле не строите JavaBean. В конце концов, не все классы, которые вы определяете, должны быть JavaBeans, верно?

Возможно, вы захотите взглянуть на Oracle JavaBeans Tutorial .

7 голосов
/ 21 апреля 2011

Нет причин, по которым ты не мог этого сделать. Лично, если сеттеры используются во время создания объекта, я бы назвал их с помощьюItem1 () и withItem2 ().

ClassA obj = new ClassA().withItem1(item1).withItem2(item2);

Делает немного более ясным (для меня, во всяком случае), каковы цели методов.

5 голосов
/ 21 апреля 2011

После проверки страниц Oracle JavaBean я не нашел ничего, что явно указывало бы, что сеттеры должны быть недействительными.Тем не менее, все примеры имеют void set-method.

PropertyDescriptor в Java API поддерживает не-void установщики, поэтому я думаю, что это должно быть довольно безопасно, чтобы ваши установщики возвращали это.Чтобы быть в безопасности, вы, вероятно, должны проверить, используют ли фреймворки, в которых вы собираетесь использовать отражение.Например, Spring не поддерживает не пустые сеттеры в конфигурации xml до версии 3.1 .

3 голосов
/ 21 апреля 2011

Я думаю, это не является нарушением спецификации JavaBean, хотя я не уверен в этом.

Проверьте следующий пример:

public class JavaBean {

    private String value;

    public String getValue() {
        return value;
    }

    public JavaBean setValue(String value) {
        this.value = value;
        return this;
    }

    public static void main(String[] args) throws Exception {
        JavaBean bean = new JavaBean();
        JavaBean.class.getMethod("setValue", String.class).invoke(bean, "test");
        System.out.println(bean.getValue());
    }
}

Многие фреймворки получают доступ к JavaBeans с помощью API отражения. Как вы можете видеть выше, доступ к установщику, который возвращает 'this', не зависит от типа возвращаемого значения (тип возвращаемого значения не используется для определения местоположения метода с помощью отражения). Это также имеет смысл, потому что вы не можете иметь два метода в одной области видимости, кроме их возвращаемого типа.

1 голос
/ 28 марта 2012

Просто добавлю, что для людей, использующих Spring 3.1+, это больше не проблема

см http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/new-in-3.1.html

1 голос
/ 21 апреля 2011

Абсолютно ничто не мешает вам делать это, но почему. Если вы хотите сделать это, создайте конструктор, который принимает аргументы. Не забывайте, что некоторые программы, использующие bean-компоненты, не будут ожидать возвращаемых значений и могут иметь неожиданные результаты

Если вы просто хотите упростить инициализацию, (возможно, для настройки тестов), вы можете использовать какой-то отличный код.

1 голос
/ 21 апреля 2011

Да. Это несколько распространенный метод, называемый «Метод цепочки», и его можно использовать для создания «свободного интерфейса».

См .: http://en.wikipedia.org/wiki/Method_chaining, http://en.wikipedia.org/wiki/Fluent_interface

0 голосов
/ 13 декабря 2013

Шаблон Builder обычно используется для построения неизменяемых объектов. Хотя JavaBeans по своей природе не является неизменным, я часто использовал шаблон компоновщика на моих JavaBeans, потому что он обеспечивает свободный интерфейс, который я могу использовать в своих тестах. Они легко совместимы друг с другом, не нарушая спецификации JavaBean. Вы можете проверить это в Переполнении стека в Шаблон Builder в эффективной Java

Вам просто нужно убедиться, что вы включили конструктор по умолчанию, а также частный конструктор Builder, а затем поместили ваши стандартные методы получения и установки в объект JavaBean.

Это намного чище, чем построение цепочки, и легче читать.

0 голосов
/ 21 апреля 2011

Ничто не мешает вам предоставлять методы установки, которые возвращают целевой объект как соглашение в вашем интерфейсе ...

Однако , вы также должны использовать каноническую подпись для простых свойств Java Bean методов установки (например, void setProp(Type t)), иначе свойство bean не будет распознано как доступное для записи другим программным обеспечением которая ожидает эту подпись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...