Объединение геттеров и сеттеров


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

@ Чэд, я должен не согласиться с твоим прочтением этого. Его аргумент в том, что ему не хватает четкости и последовательности. Он говорит, что использует его в Smalltalk, потому что его забота связана с другими. Он не утверждает, что соглашения Smalltalk каким-то образом смягчают или устраняют проблему.
Уинстон Эверт

2

Это называется «перегрузка методов» в языках OO или «перегрузка функций» в языках без OO.

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

  • Контекст, в котором он используется, довольно хорошо отделяет одно от другого.
  • Добавление getили setк имени метода добавляет многословие.
  • Если имеется несколько получателей (например, один для intи один для double), изменение типа в LHS присвоения ( int x = foo.bar()против double x = foo.bar()) не требует изменения кода ( barAsInteger()против barAsDouble()) с правой стороны, если класс обеспечивает оба. Обратной стороной этого является то, что иногда бывает трудно точно узнать, какой метод вызывается, просто взглянув на код.

Это также называется «перегрузкой функций» в C ++.
DeadMG

Оба термина применимы к C ++, потому что он имеет как методы, так и голые функции.
Blrfl

1

Поскольку JavaScript не имеет реальных свойств (где установка значения может фактически выполнять код), паттер является тем, который реализует идиому свойства. (Даже если вы называете это чем-то другим.)

Таким образом, в языках, реализующих реальные свойства, вы должны сделать это вместо этого:

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

Если бы вы использовали шаблон JavaScript на языке, который обрабатывает свойства, вы бы сделали что-то ненормальное. Это, вероятно, не будет хорошей идеей. Обрабатывайте свойства так, как это делает язык, чтобы вы не путали других людей, работающих с вами.


msgstr "где установка значения может фактически выполнить код". На самом деле это больше не правда. Это было частью спецификации с ECMA 5
Демиан Брехт

@Demian: Но JQuery работает в браузерах, которые не поддерживают ECMA 5.
Джон Фишер

Я ничего не упоминал о кросс-браузерной совместимости, просто цитата неверна, как написано.
Демиан Брехт

@Demian: текст «JavaScript не имеет реальных свойств» является правильным, если вы предполагаете, что он использует наиболее доступные версии JavaScript. Поскольку мы обсуждаем в контексте реализации JQuery, утверждение будет правильным. Спасибо за то, что указали, что более новые версии JavaScript имеют истинные свойства.
Джон Фишер

0

Я думаю, что вы ищете properties


Это название для функциональности, предоставляемой в C # (и, возможно, других языках .NET?), Которая похожа на эту, но на самом деле это не то же самое.
Томас Оуэнс

Википедия соглашается, хотя: en.wikipedia.org/wiki/Property_(programming)
thekip

Спасибо, на самом деле не вы могли бы иметь случай сказать , где вы установили или получить зарплату лиц в приложении person.salary('10000')или person.salary()или аналогичном.
Яннис

1
Я не вижу как. «Свойства читаются и пишутся как поля», что неверно в примере из исходного поста. Там делаются явные вызовы методов. Это очень похоже, но не совсем то же самое.
Томас Оуэнс

1
@yannis Это не правильно. У JavaScript есть синтаксис для свойств, и это совсем не то, что вы описали в исходном вопросе. См. En.wikipedia.org/wiki/Property_(programming)#JavaScript, чтобы узнать, как реализовать и использовать свойства в JavaScript.
Томас Оуэнс

0

Я полностью против этого по простой причине: класс, метод или функция должны делать только одно - по моему мнению, и объединять getter и setterметод будет нарушать это правило. В результате:

  1. returnЗначение функции изменяется в зависимости от того, если геттер или сеттера блок получить выполнен. Это может просто привести вас в кошмар ремонтопригодности. Ваш метод должен возвращать только один тип данных / объекта в любом случае - или возвращать null, falseили выдавать exceptionв случае ошибки.
  2. Написание модульных тестов будет сложнее, так как функция отвечает за две совершенно разные функциональные возможности.
  3. Написание документации для такого метода или функции сложнее по очевидным причинам.
  4. Это не будет соответствовать , когда несколько геттерных методам необходимы - как уже было сказано в Blrflответе.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.