Java Beans: Превъзхвалявани асоциативни масиви?

Не разбирам природата на Java Beans толкова добре. Е, поне как ги виждам използвани в някои кодови бази, които минават през нашия магазин.

Намерих този въпрос:

Java Beans: Какво пропускам?

Приетият отговор там прави да изглежда, че програмистите са склонни да злоупотребяват с Java Bean (в което наистина не се съмнявам), но виждам, че се случва толкова често и толкова умишлено, че все още пропускам нещо.

Виждам код, който изглежда така:

public class FooBean {
  private int a;
  private int b;
  private int c;

  public int getA() { return a; }
  public int setA(int x) { a = x; }

  // etc...
}

Няма допълнителна структура или контрол освен гетъри и сетери. Има ли някакъв супер страхотен трик на компилатора, който включва отражение, гетери и сетери и необходимостта от някои много неудобни (но оптимизирани от компилатора) статични асоциативни масиви?

Или може би напълно пропускам смисъла. :\

наздраве!

Редактиране:

Тук определено не насърчавам идеята за публични полета.


person Jeremy Powell    schedule 27.07.2009    source източник
comment
За съжаление повечето от отговорите на този въпрос са пропуснали изцяло действителния въпрос и го тълкуват като защо има методи за получаване и настройка...   -  person Mike Daniels    schedule 27.07.2009
comment
От това, което казвате, изглежда, че Java Beans са по-скоро карго култова програмна практика, отколкото нещо друго.   -  person Jeremy Powell    schedule 27.07.2009
comment
@Mike: така че дайте отговора си, ако смятате, че сте го разбрали правилно   -  person dfa    schedule 27.07.2009
comment
Просто реших да спомена - Много бобове се използват за пренос на данни и нямат никакви данни. Стигнах до извода, че това е ужасна загуба на код. Единствената причина, поради която виждам, че това не са просто хеш-таблици, е безопасността на типа. Когато сега имам нужда от пакет свойства като този, всъщност просто капсулирам хеш от свойства в моя пакет. Бих искал да видя Java да възприеме някакъв вид предварително дефиниран безопасен за типа модел на пакет свойства с автоматизирано уведомяване и валидиране, но повечето хора изглежда са щастливи да прекарват дните си в писане на сетери и гетери вместо това.   -  person Bill K    schedule 29.07.2009


Отговори (6)


Всъщност, да, случва се магия.

Това е наистина тъп модел, но GUI bean-овете (каквито са всички компоненти) са предназначени да бъдат рефлективно анализирани от GUI builder. Публичните полета за задаване/получаване са предназначени да бъдат „Свойства“, с които потребителят може да се занимава, докато изгражда своя GUI.

Редактиране: В защита на слънцето трябва да кажа, че въпреки че моделът се оказа доста неприятен поради всички хора, които го копираха и започнаха да го използват в целия си не-bean код, той позволи на хората да интегрират класове с GUI builder без използване на външни метаданни. Нямате нужда от XML файл или файл със свойства за редактора, беше толкова лесно, колкото да разширите Button и да пуснете новия си обект върху палета.

Този модел е използван на други места и, както забелязахте, той е почти същият като да имате публични полета. Мисля, че това е един от най-лошите шаблони, създадени от слънцето при настройване на java, но нямаше други очевидни решения (мисля, че цялата концепция беше някак подхваната от първите хора, които се опитваха да създадат първите GUI builders преди пускането на java).

Сега има много по-добро решение: използвайки анотации за маркиране на частни полета, рефлективният инструмент все още може да ги анализира и да ги обвърже с контролите на компилатора. Това би било много по-чисто и няма да направи всичките ви обекти толкова уязвими към външни промени в състоянието.

person Bill K    schedule 27.07.2009

Java Beans са, както посочвате, доста тривиална конвенция за кодиране.

Полезното е, че те изобщо бяха конвенция. Това позволи да се изградят спомагателни инструменти, които се основаваха на (по това време) нови идеи като уточняване на точното име на гетерите и сетерите и очакване, че специфични методи ще съществуват, без да е необходимо да се приписват на интерфейс. Това позволи достатъчно гъвкавост, за да правите каквото искате, но все пак ви позволи да използвате GUI за сглобяване на бобчета.

На този етап, тъй като пълната интроспекция е норма, а други езици имат формализирана функция за получаване/задаване и много други начини да правят това, което правят Beans, мисля, че те са идея, чието време е минало.

person Alex Feinman    schedule 27.07.2009
comment
+1 за добро обобщение за какво е конвенцията. Но бих оспорил твърдението ви, че конвенцията вече не е необходима. Пролетта е пример, който използва широко окабеляване в стил боб. Ако имате широкомащабна уеб услуга, която до голяма степен се състои от Java компоненти, е много по-добре да ги свържете заедно чрез XML файл, отколкото да напишете Java код, за да извършите свързването. - person Stephen C; 28.07.2009
comment
И повечето сега биха използвали анотации за окабеляване в стил боб, защото стилът на боб е, с една дума, лош. - person Bill K; 29.07.2009

Хората използват прекомерно глупави гетери/сетери, без съмнение в това.

Представете си обаче колко болка трябва да преживеете 2 години по-късно, когато разберете, че трябва да премахнете интервали от низа във вашия setEmail(string email); метод и целият ви код е трудно свързан, за да използва публични полета вместо извикване на метод.

Запомнете едно от основните правила на обектно-ориентирания дизайн „Код към интерфейс, а не реализация“. Достъпът до публични полета на клас със сигурност е последният и ще направи преработването на кода много по-трудно.

person nos    schedule 27.07.2009
comment
Възражението не е непременно срещу идеята за гетери и сетери, а до факта, че трябва да пишем проклетите неща на ръка. - person skaffman; 27.07.2009
comment
@skaffman, съвременните IDE предоставят шаблони, така че е лесно да ги генерирате автоматично. Eclipse може да генерира конструктори и get/set'ers за множество полета. - person Thorbjørn Ravn Andersen; 27.07.2009
comment
Добре, честно,. но все пак се оказвате с купища безполезни бъркотии. - person skaffman; 27.07.2009
comment

Техниката на алфа формите, спомената в този въпрос, обработва общ набор от точки, където връзките на върховете не са известни:

Има ли ефективен алгоритъм за генериране на 2D вдлъбнат корпус?

Въпреки това, тъй като вече знаете информация за "лицето", която може да бъде запазена чрез проекцията, това вероятно не е най-добрият подход.

Алгоритъмът за груба сила може да е осъществим, особено ако се използват структури за пространствено сортиране. например за всеки аспект:

  1. Проектирайте фасет върху равнината
  2. Проверете дали проектираният фасет е напълно затворен от съществуваща геометрия, ако да: готово (няма нужда да разширявате проектирания силует)
  3. Ако точките попадат извън съществуващата геометрия, направете пресичане на триъгълник-триъгълник, за да определите кои части попадат навън, изградете произволен n-ъгълник (евентуално вдлъбнат), за да запълните липсващото пространство, след което нарежете n-ъгълника на триъгълници

Друга идея, в зависимост от прецизността, която изисквате, е просто да изстреляте куп лъчи нормално от вашата проекционна равнина към вашата оригинална геометрия. Създайте 2d попадение/пропускане и го използвайте, за да определите своите граници.

- person Stephen C; 28.07.2009
comment
@nos вашият отговор показва ТОЧНИЯ проблем със сетери и гетери. Вие не питате обект за данни, вие го питате да работи с данните си. Така че може да имате име, но ще го направите окончателно и ще го зададете в конструктора само ако изобщо е възможно (където можете лесно да го манипулирате, преди да зададете полето)... Вероятно не трябва да имате getter, но те са по-малко груби... Но може да имате getPreferredEmail(), който би върнал един от имейл адресите, които съхранява, това не е чист метод за получаване. Още по-добре може да е метод mailTo() във вашия обект. - person Bill K; 29.07.2009

Не пропускаш смисъла. Getters/Setters са грозни, но са вградени в толкова много инструменти, които правят предположения за имена на класове/методи/полета (напр. spring), че (освен очевидната им стойност за капсулиране) те на практика са се превърнали в почти изискване, освен ако не сте работа в много ограничен и частен контекст.

person Steve B.    schedule 27.07.2009
comment
Пролетта сега не предпочита ли анотациите, защото бобът е гаден? Между другото сетерите и гетерите са обратното на капсулирането - те позволяват достъп до вътрешно състояние, което трябва да бъде напълно скрито. - person Bill K; 29.07.2009

'getters' и 'setter' са страхотни, ако искате да замените достъпа до вашите данни, например за регистриране/сигурност или връщане на стойност, различна от оригиналния клас.

person Pierre    schedule 27.07.2009

без сетер не можете да проверите за инварианти:

public void setFoo(Foo foo) { 
     if (foo == null) {
          throw new InvalidFoo();
     }

     this.foo = foo;
}

с публични членове не можете да направите това. Втора точка, в рамките на сетер можете да задействате събития, които други зърна могат да слушат. Не на последно място, можете да наложите правилна проверка на типа (както посочихте във вашия въпрос).

person dfa    schedule 27.07.2009
comment
Това беше справедлив отговор... контриран! - person skaffman; 27.07.2009
comment
Съгласен, няма нищо общо с въпроса. Заслужава ли гласуване за отговор като Water is wet? Това е 100% правилна и много полезна информация, но всъщност не е приложима към разглеждания въпрос. - person Bill K; 29.07.2009
comment
Също така, това е анти-шаблон за инварианти, би било много по-добре да го направите финален и да го зададете в конструктора, по този начин ще знаете със сигурност, че дори вашият собствен код не го задава. Това би било доста полезно, ако абсолютно трябва да използвате шаблона за изграждане, но ако случаят е такъв, трябва да върнете това. - person Bill K; 29.07.2009
comment
антимодел? не можете да моделирате всички обекти като неизменни - person dfa; 29.07.2009
comment
@Bill: както и да си прав, отговорът ми не е добър като приетия - person dfa; 29.07.2009