Поєднання геттерів та сетерів


16

Бібліотеки JavaScript, такі як jQuery, комбінують 'getters' та 'setters' в інтерфейсі програмування, наприклад:

 $('element').css({'color','blue'});

встановить колір або

 $('element').css();

отримає css для елемента.

Чи є назва такого шаблону і чи вдалу практику використовувати в додатках?

Відповіді:


12

Нещодавно Мартін Фаулер назвав його в цій статті перевантаженим геттером і сетером :

Нещодавно я розмовляв у Javascript, і мене вразила одна річ - звичка використовувати однакові назви функцій для геттера та сеттера. Отже, якщо ви хочете дізнатися висоту вашого банера в jQuery, який ви б використовували, $("#banner").height()і якщо ви хочете змінити висоту, яку ви будете використовувати $("#banner").height(100).

Ця конвенція мені знайома, оскільки її використовував Smalltalk. Ви можете отримати значення banner heightі змінити його за допомогою banner height: 100. Знання, що це умова про невеликі розмови, досить, щоб очікувати, що мені сподобається, оскільки я маю далеку, але дотриману любов до цієї мови. Але навіть у найкращих речей є вади, і я не можу приховати свою неприязнь до цього стилю кодування ...

Незважаючи на цю перевагу, ви повинні дотримуватися конвенцій мови, якою ви маєте справу. Якби я знову писав Smalltalk, я все-таки використовував би height:100для того, щоб зберегти узгодженість з умовами мови. Однак Javascript не відзначається тим, що він має чіткі умови, тому тут я вважаю за краще уникати цієї конвенції, навіть якщо вона використовується jQuery ...


1
Хоча я зазвичай згоден з більшістю того, що каже Фоулер, я не згоден з його неприязню до цього. Його міркування полягають у тому, що JavaScript не має чітких умов, таких як Smalltalk, що робить його зручним для використання там. Однак jQuery має чіткі умови, а JavaScript - це не jQuery. jQuery - це рамка.
CaffGeek

@Chad, я не погоджуюся з твоїм читанням цього. Його аргумент полягає в тому, що йому не вистачає чіткості та послідовності. Він каже, що використовує його в Smalltalk, оскільки послідовність з іншими козирями викликає його стурбованість. Він не стверджує, що конвенції Smalltalk якимось чином пом'якшують або усувають проблему.
Вінстон Еверт

2

Його називають "методом перевантаження" в мовах ОО або "функцією перевантаження" в мовах, що не належать до ОО.

Незалежно від того, чи це хороша практика, чи ні, це тема майже такої ж дискусії, як і геттери / сетери проти громадських членів. Ті, хто з прихильників і, зрештою, вирізали зуби на мовах, які мали цю особливість або не мали, і їх налаштовують. Я використовую це і люблю практику з кількох причин:

  • Контекст, в якому він використовується досить добре, відокремлює один від іншого.
  • Попередження getабо setім'я методу додає багатослівність.
  • Якщо є кілька видобувачів (наприклад, один для intі один для double), змін типу в LHS присвоєння ( int x = foo.bar()проти double x = foo.bar()) не вимагають змін коди ( barAsInteger()проти barAsDouble()) на праву сторону , якщо клас забезпечує як. Суть до цього полягає в тому, що колись може бути важко дізнатися, який саме метод викликається, просто переглянувши код.

Це також називається "функція перевантаження" в C ++.
DeadMG

Обидва терміни стосуються C ++, оскільки він має як методи, так і голо-голі функції.
Blrfl

1

Оскільки JavaScript не має фактичних властивостей (там, де встановлення значення може фактично виконувати код), patter - це той, який реалізує ідіому властивості. (Навіть якщо ви називаєте це чимось іншим.)

Отже, у мовах, що реалізують реальні властивості, ви робите це:

element.css = ...
x = element.css

Якби ви використовували шаблон JavaScript на мові, яка обробляє властивості, ви б робили щось ненормальне. Це, ймовірно, не буде гарною ідеєю. Обробляйте властивості способу поводження з ними, щоб не плутати інших людей, що працюють з вами.


"де встановлення значення може фактично виконати код". Це насправді вже не так. Це частина специфікації з ECMA 5
Demian Brecht

@Demian: Але JQuery працює в браузерах, які не застосовують ECMA 5.
Джон Фішер

Я нічого не згадував про сумісність між браузерами, лише те, що цитата неправильна, як написана.
Дем'ян Брехт

@Demian: Текст "JavaScript не має фактичних властивостей" є правильним, якщо ви вважаєте, що він використовує найпоширеніші версії JavaScript. Оскільки ми обговорюємо в контексті реалізації JQuery, це твердження було б правильним. Дякуємо, що вказали, що новіші версії JavaScript мають справжні властивості.
Джон Фішер

1

Я якось суворо проти цього з простої причини: Клас, метод чи функція повинні робити лише одне - на мою думку, і поєднання методу getterі setterметоду порушить це правило. Як результат:

  1. returnЗначення функції змінюється в залежності від того, якщо геттер або сетера блок отримати виконаний. Цей може просто призвести вас до кошмару ремонту. Ваш метод повинен повернути лише один тип даних / об’єкта в будь-якому випадку - або повернути null, falseабо викинути exceptionв разі помилки.
  2. Тести написання одиниць будуть складнішими, оскільки функція відповідає за два абсолютно різні функції.
  3. Написання документації для такого способу чи функції складніше з зрозумілих причин.
  4. Це не буде послідовно, коли потрібно кілька методів отримання - як уже згадувалося у Blrflвідповіді.

0

Я думаю, ти шукаєш properties


Ось назва функціоналу, що надається в C # (і, можливо, інших мовах .NET?), Схожа на це, але насправді це не те саме.
Томас Оуенс

Wikipedia погоджується, хоча: en.wikipedia.org/wiki/Property_(programming)
thekip

Спасибі, на самому ділі не ви могли б мати випадок сказати , де ви встановили або отримати зарплату осіб в додатку person.salary('10000')або person.salary()або аналогічному.
янніс

1
Я не бачу як. "Властивості читаються і записуються як поля", що не відповідає дійсності в прикладі в оригінальній публікації. Там проводяться явні виклики методів. Це дуже схоже, але не зовсім те саме.
Томас Оуенс

1
@yannis Це неправильно. У JavaScript є синтаксис властивостей, і це зовсім не те, що ви описали в оригінальному запитанні. Див. En.wikipedia.org/wiki/Property_(programming)#JavaScript для того, як реалізувати та використовувати властивості в JavaScript.
Томас Оуенс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.