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


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. Мартин Фаулер делает хорошее замечание о методах получения, которым требуется параметр, но даже в этом контексте дополнительный параметр значения явно обозначает установщик, а также тот факт, что установщик редко появляется в правой части присваивания. И когда вы написания кода, вы должны смотреть на документацию для библиотеки в любом случае.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.