Java Beans: что мне не хватает? - PullRequest
17 голосов
/ 24 ноября 2008

Мне интересно, что-то упущено в Java Beans. Мне нравится, когда мои объекты выполняют как можно больше инициализации в конструкторе и имеют минимальное количество мутаторов. Бобы, кажется, идут прямо против этого и в целом чувствуют себя неуклюже. Какие возможности я упускаю из-за того, что не строю свои объекты как Бобы?

Ответы [ 5 ]

13 голосов
/ 24 ноября 2008

Звучит так, как будто вы на правильном пути. Не вы упускаете из виду смысл Java Beans, а другие программисты злоупотребляют ими.

Спецификация Java Beans была разработана для использования с визуальными инструментами. Идея заключалась в том, что разработчик приложения сможет интерактивно настраивать экземпляр объекта, а затем сериализовывать (или генерировать код) настроенный компонент, чтобы его можно было восстановить во время выполнения; предполагалось, что он не будет видоизменяться во время выполнения.

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

Конечно, вам, как правило, нужно настраивать экземпляры ваших объектов. Просто это должно быть сделано через какую-то особенность конфигурации. Это может быть контейнер для внедрения зависимостей, визуальный инструмент в стиле BeanBox или просто чтение файлов JSON, XML или свойств, которые вы написали вручную. Ключ в том, что во время выполнения эти объекты эффективно неизменяемы; клиенты просто вызывают свои операции, они не имеют доступа к своим свойствам.

7 голосов
/ 24 ноября 2008

Мне нравится, что мои объекты делают столько же инициализация в конструкторе как возможно и иметь минимальное количество мутаторов.

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

Например, предположим, что у вас есть коллекция бинов Person, и у каждого бина есть такие свойства, как имя, возраст, рост и т. Д.

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

Collection<Person> myCollection = // initialise and populate the collection
Comparator nameCompare = new BeanComparator("name");
Collections.sort(myCollection, nameCompare);

Класс BeanComparator знает, как извлечь свойство "name" из каждого объекта, поскольку соблюдается соглашение Java Beans, т.е. вы избавлены от "накладных расходов" на реализацию интерфейса, такого как:

interface Nameable {
    public String getName();
    public void setName(String name);
}

Другим примером Spring MVC является bean-компонент, хранящий параметры URL-адреса запроса. Это можно определить в веб-контроллере (известном как «Действие» в Struts) следующим образом:

public ModelAndView searchUsers(UserSearchCriteria criteria) {
    // implementation omitted
}

Поскольку ожидается, что UserSearchCriteria будет JavaBean, если URL-адрес запроса содержит такой параметр, как maxItems=6, среда Spring «знает», что должна вызвать метод с подписью

void setMaxItems(int maxItems);

По сути, JavaBeans - это просто простое соглашение, которое позволяет динамически обнаруживать свойства класса во время выполнения (обычно с помощью инструмента или инфраструктуры), когда априори неудобно / невозможно узнать свойства, которые могут быть предоставлены.

3 голосов
/ 17 февраля 2009

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

Чтобы получить лучшее из "обоих миров", я думаю, что хорошим вариантом является использование шаблона Builder , слегка модифицирующего Builder для соответствия стандарту JavaBeans. Таким образом, если вам нужна функциональность платформы, которая требует, чтобы ваш класс соответствовал стандарту JavaBeans, вы можете использовать Builder вместо фактического класса.

2 голосов
/ 24 ноября 2008

Когда вы слышите слово «боб», ожидайте, что вы увидите какой-то «контейнер». Идея JavaBean любого рода состоит в том, чтобы обеспечить единообразное соглашение об интерфейсе для компонентов, которые можно добавлять и управлять ими во время выполнения. Простые JavaBeans - это просто простейший пример этого: он представляет все возможности интерфейса и является Сериализуемым, что означает, что вы можете создавать экземпляры компонента, изменять их, сохранять и перезагружать их.

Давным-давно я написал редактор Java, который содержал простую «базу данных», представляющую текстовые строки, и имел «архитектуру подключаемого модуля», в которой использовались bean-компоненты. Вы можете добавить поведение в редактор, перетаскивая bean-компонент из хранилища bean-компонентов и помещая его в редактор; После этого поведение (скажем, Cntl-T для транспонирования символов в курсоре) автоматически стало доступно в редакторе. Бины имели известный интерфейс - они знали, как запрашивать у контейнера структуру данных, и метод doSomething () - и контейнер знал, что нужно динамически загружать файл класса, создавать экземпляр объекта и устанавливать его доступ к база данных.

Кстати, это не обязательно так, что методы доступа нарушают инкапсуляцию; однако верно то, что только потому, что у вас есть член, вам не нужно , чтобы предоставить методы get и set для него. Спецификация JavaBean немного неясна по этому поводу; Дело в том, чтобы обеспечить геттеры и сеттеры для тех вещей, которые должны быть в объекте «контракт».

После того, как самоанализ и рефлексия были добавлены к языку и по-настоящему понятны, необходимость в этих соглашениях несколько уменьшилась; в ранней Java вам нужно было договориться о поиске методов.

1 голос
/ 24 ноября 2008

Бины настраиваются таким образом, чтобы автоматизированные инструменты могли создавать и изменять Бины. Они не обязательно должны быть великолепными шаблонами дизайна.

Примеры этих инструментов:

Hibernate
JMX

...