Каковы преимущества «комбинированного» метода получения / установки по сравнению с индивидуальными методами?

12

Это то, что я называю «комбинированным» методом получения / установки (из jQuery):

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.text(); // myHTML now equals "This is my HTML" (Getter)
foo.text("This is a new value"); // The text now equals "This is a new value")

Это та же логика с отдельными (теоретическими) методами:

var foo = $("<div>This is my HTML</div>"),
    myText;

myText = foo.getText(); // myHTML now equals "This is my HTML" (Getter)
foo.setText("This is a new value"); // The text now equals "This is a new value")

Мой вопрос:

При разработке библиотеки, такой как jQuery, почему вы решили пойти первым путем, а не вторым? Не является ли второй подход более ясным и понятным с первого взгляда?

Леви Хэквит
источник
6
Мартин Фаулер не фанат того, что он называет «перегруженными установщиками геттеров
vaughandroid
1
Раньше мне нравился метод разделения get / set (думая, что он сделал код более «очевидным»), но я считаю, что перегруженный шаблон getter / setter более привлекательный в наши дни. Это может сделать код чище. Мне никогда не нравился компромисс мистера Фаулера. Мне кажется, что это худшее из обоих миров.
Брайан Кноблаух
Единственный реальный аргумент Мартина Фаулера против этого - когда «геттер» передает аргумент, и в этом случае он сбивает с толку читателя тем, что он не похож на геттер. На данный момент я пришел к выводу, что если вы придерживаетесь соглашения о том, что метод получения не принимает аргументов, а метод установки принимает один, то наряду с четкими комментариями API подход jQuery / Angular должен быть вполне подходящим. На данный момент.
zumalifeguard

Ответы:

13

Здесь чисто предположения, но я склонен полагать, что разработчики jQuery, которые использовали много функциональных стилей при структурировании jQuery, явно склоняются к функциональной парадигме.

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

Практикуйтесь в функциональной парадигме, и вы быстро преодолеете это желание к церемонии и научитесь ценить способность делать больше с меньшими затратами. Хотя это, безусловно, субъективный выбор, основанный на предпочтениях, так же, как многие люди имеют предпочтения в отношении управления пробелами. Таким образом, я не говорю, что один из способов лучше, скорее, это то, к чему люди привыкли, и именно поэтому jQuery использует такой подход.

Вот почему я считаю, что разработчики jQuery сделали это, и в целом почему кто-то может использовать этот подход.

Джимми Хоффа
источник
2
Согласился, плюс я бы добавил желание максимально уменьшить размер JS.
Мэтт S
-1 для императивных / подробных и функциональных / неявных точек.
3
@ MattFenwick Я не хочу обидеть, вы говорите, что это неправда, что функциональная парадигма имеет склонность к неявности, где императивная парадигма склоняется к явности? Я не говорю, что лучше, просто то, что один может привыкнуть к одному или другому, что заставит вас автоматически делать вещи таким образом, а не другим (это в любом случае одинаково)
Джимми Хоффа,
@ Джимми, нет проблем; моя точка зрения заключалась лишь в том, что по своему опыту я обнаружил, что неявность / явность ортогональны FP / императиву.
@MattFenwick может быть, но я бы сказал, что помимо вывода типов, который допускает большую неявность и является общим для системы типов HM, другие вещи, общие для языков FP, склоняются к неявности, как и все операторы как функции, где Функция не имеет явного имени, просто символ, который вы должны изучать и узнавать неявно, или обычное использование списков или кортежей, требующих неявного знания значения и местоположения члена вместо DU (подумайте о том, как работает монада писателя). Я также склонен видеть общность однобуквенных имен параметров, но вы можете быть правы
Джимми Хоффа,
2

Форма

foo.text("This is a new value"); 

может подразумевать несколько вещей. Чаще всего он предлагает fooобъект с методом, textпринимающим строку, который что-то делает . Нет никакого смысла в том, что это свойство вообще.

Во многих языках это можно считать сокращенной формой

var result = foo.text("This is a new value"); 

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

Роберт Харви
источник
Это отличный момент! Я надеваю очки FP, когда читаю javascript, и все выглядит иначе, поэтому я даже не задумывался об этом, но если бы я видел такой код в C #, я бы получил именно ту реакцию, на которую вы ссылаетесь: «Что делает этот метод? ??».
Джимми Хоффа
1

Это немного умозрительно, но вот мой выстрел в этом.

JQuery полностью охватывает функциональную природу JavaScript. Это то, что делает его таким замечательным, но многие разработчики могут почесать голову, когда они исходят из более чисто ОО-языка, такого как Java. Кажется, это нарушает все обычаи и хорошие практики.

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

var eligible = customers.where(c => c.age > 30);

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

for (customer in customers)
    if (customer.age > 30)
        eligible.add(customer)

Это можно прочитать как «Проверьте каждого клиента, и если его возраст превышает 30 лет, добавьте его в соответствующую коллекцию»

Добавление aa setи getоперации сделало бы jQuery похожим на императивную библиотеку. Вы можете ограничить способ чтения следующих утверждений

// The element tag have an html of <p>hello</p>
$("#element").html("<p>hello</p>"); 

// content represent the html of the element tag
var content = $("#element").html();


//Imperative style

// Set the element tag to an inner html of <p>hello</p>
$("#element").setHtml("<p>hello</p>");

//Get the html of #element, and put it in the content variable
var content = $("#element").getHtml();

Не добавляя глагол действий в API jQuery, они создавали ощущение декларативного API. Это дает последовательное, функциональное чувство к библиотеке. Вот почему я думаю, что они перегружены ключевыми словами.

Лоран Бурго-Рой
источник
1

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

Если вы когда-либо рассматривали определение класса, полное таких свойств, префиксы «set» и «get» выглядят излишними, потому что добавление параметра value уже говорит вам, что это setter. Мартин Фаулер делает хорошее замечание о методах получения, которым требуется параметр, но даже в этом контексте дополнительный параметр значения явно обозначает установщик, а также тот факт, что установщик редко появляется в правой части присваивания. И когда вы написания кода, вы должны смотреть на документацию для библиотеки в любом случае.

Поскольку вы просили только преимущества, я не буду освещать недостатки.

Карл Билефельдт
источник