Альтернативы JavaBeans?

Вы можете сделать это, используя отражение с чем-то вроде этого:

  val b = B("foo")
  val c = b.copy()
  println(b.i) // prints 1
  val field = classOf[A].getDeclaredFields.head
  field.setAccessible(true)
  field.setInt(c, 2)
  println(c.i) // prints 2

Но будьте осторожны, это не просто «плохая практика программирования», а скорее полный разрыв договора .

Ваша декларация case class B(s: Sting) extends A(1) обещает, что все экземпляров B будут всегда иметь i, равное 1, что является ложью.

Не говоря уже о забавных фактах, таких как b == c - true или c.copy.i - 1 и т. Д. Не делайте этого.

11
задан SamBeran 14 January 2009 в 02:11
поделиться

9 ответов

Я думаю, что Вы достаточно близки с объявлением, которое Вы имеете там (см. ниже для эскиза). Однако при помощи небобового подхода, Вы, вероятно, потеряете поддержку, оказанную большинством инструментов, которые предполагают, что протокол JavaBeans в действительности. Будьте добры. Код ниже первое, что пришло на ум...

public class Property<T> {
    public final String name;
    T value;
    private final PropertyChangeSupport support;

    public static <T> Property<T> newInstance(String name, T value, 
                                              PropertyChangeSupport support) {
        return new Property<T>(name, value, support);
    }

    public static <T> Property<T> newInstance(String name, T value) {
        return newInstance(name, value, null);
    }

    public Property(String name, T value, PropertyChangeSupport support) {
        this.name = name;
        this.value = value;
        this.support = support;
    }

    public T getValue() { return value; }

    public void setValue(T value) {
        T old = this.value;
        this.value = value;
        if(support != null)
            support.firePropertyChange(name, old, this.value);
    }

    public String toString() { return value.toString(); }
}

и затем разрешение и использование это:

public class Customer {
    private final PropertyChangeSupport support = new PropertyChangeSupport();

    public final Property<String> name = Property.newInstance("name", "", support);
    public final Property<Integer> age = Property.newInstance("age", 0, support);

    ... declare add/remove listenener ...
}


Customer c = new Customer();
c.name.setValue("Hyrum");
c.age.setValue(49);
System.out.println("%s : %s", c.name, c.age);

Так, теперь объявление свойства является одной строкой кода, и поддержка изменения свойства включена. Я назвал методы setValue () и getValue (), таким образом, он будет все еще похож на боб для кодирования как Носорог и материал, но для сжатого, Вы могли добавить, просто получают () и устанавливают (). Остальное оставляют как осуществление для читателя:

  • Правильно сериализация дескриптора
  • Обработайте проверку нулевого значения
  • Возможно, добавьте специализации для атомарных типов, если Вы заботитесь об автоупаковке наверху.
  • ?? Я уверен, что существует больше глюков

Также обратите внимание, что можно разделить на подклассы (обычно как анонимный класс) и переопределить setValue () для обеспечения дополнительной проверки параметра.

Я не думаю, что можно действительно убежать "От строковых ссылок", так как это в значительной степени что отражение все о.

Печально, хотя, в этот день и возраст, это все еще отчасти похоже на программирование в блоке... Groovy, C#, и т.д., и т.д. может все еще быть лучшим выбором, если у Вас есть выбор.

10
ответ дан 3 December 2019 в 05:59
поделиться

Проверьте мои Бобовые аннотации в

http://code.google.com/p/javadude/wiki/Annotations

В основном Вы делаете вещи как:

@Bean(
  properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
  }
)
public class Person extends PersonGen {}

вместо того, чтобы определять все, дополнительные получают/устанавливают и т.д. методы самостоятельно.

Существуют другие атрибуты для определения, равняется/хэш-код, наблюдатели, делегаты, mixins, и т.д.

Это - ряд аннотаций и процессора аннотации, который работает в затмении или в сборке командной строки (у муравья, например). Процессор генерирует суперкласс для содержания всего сгенерированного кода (процессоры аннотации не могут изменить класс, содержащий аннотации, btw),

4
ответ дан 3 December 2019 в 05:59
поделиться

Можно хотеть проверить Groovy - с динамическим контролем типов, основанное на JVM (и полностью совместимый с Java) язык с "реальными" свойствами.

3
ответ дан 3 December 2019 в 05:59
поделиться

Используйте Платформу Spring. Его цель состоит в том, чтобы упростить разработку Java путем абстракции большого количества основы, на которую Вы жалуетесь.

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

Полезные сайты:

www.springsource.org/download

www.hibernate.org/

1
ответ дан 3 December 2019 в 05:59
поделиться

Для сети я предложил бы JSON (Объектная нотация JavaScript),

легкий формат обмена данными

. Здесь ссылка к JSON? Бобовый переводчик.

1
ответ дан 3 December 2019 в 05:59
поделиться

Вы могли также создать генератор кода, который создает Ваши .java классы из DSL, который Вы пишете. У Вас могла быть некоторая разметка, которая описывает название Вашего класса, свойства, которые Вы хотите, и их типы. Затем обработайте тот файл с программой, которая генерирует Ваш javabeans. Или Вы могли использовать аннотацию и выполнить последующую обработку файлы класса с помощью чего-то как ASM для введения средств доступа и мутаторов. Я полагаю также, что Spring обеспечивает некоторые из подобных функций, но я не использовал их.

0
ответ дан 3 December 2019 в 05:59
поделиться

Попробуйте платформу ШВА от JBoss, Вы хотели бы его.

0
ответ дан 3 December 2019 в 05:59
поделиться

После того как я попробовал это:

interface IListenable {
    void addPropertyChangeListener( PropertyChangeListener listener );
    void removePropertyChangeListener( PropertyChangeListener listener );
}

abstract class MyBean extends IListenable {
    public abstract void setName(String name);
    public abstract String getName();

    // more things
}

public class JavaBeanFactory {

   public <T> Class<T> generate(Class<T> clazz) {
      // I used here CGLIB to generate dynamically a class that implements the methods:
      // getters
      // setters
      // addPropertyChangeListener
      // removePropertyChangeListener
   }
}

Я использовал это в качестве этого (это - просто пример):

public class Foo {
    @Inject
    public Provider<MyBean> myBeanProvider;

    public MyBean createHook(MyBean a) {
        final MyBean b  = myBeanProvider.get();
        a.addPropertyChangeListener(new PropertyChangeListener() {
             public void propertyChange(PropertyChangeEvent evt) {
                 b.setName((String) evt.getNewValue());
             }
        });
        return b;
    }
}
0
ответ дан 3 December 2019 в 05:59
поделиться

Когда я впервые использовал C #, мне понравились свойства, но теперь, после некоторого времени использования их с VS 2008, я должен сказать, что предпочитаю set- / get-методы.

Главное - мой личный стиль работы. Когда у меня есть новый класс и я хотел бы знать, что я могу с ним сделать, я просто набираю classname.set, и Eclipse показывает мне, какие «Свойства» я могу изменить. То же самое и с получением. Возможно, это просто плохой способ VS, но там мне нужно пролистать длинный список этого itelisense (где все смешано, вместо того, чтобы сначала показывать свойства), чтобы узнать после компиляции, что свойство, которое я хотел установить, доступно только для чтения. ..doh!

Да, в Java вам нужно много строк, но я просто пишу свои атрибуты и говорю IDE: «Пожалуйста, создайте для меня геттеры и сеттеры». Но эти методы обычно занимают много места,

1
ответ дан 3 December 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: