Статьи

О важности стандартной библиотеки

Стандартная библиотека часто рассматривается как удобство, но это гораздо больше; это повышает уровень абстракции и обеспечивает богатую композицию, которая помогает управлять сложностью при создании больших приложений. В этой статье я покажу, как стандартная библиотека достигает этого на примере Dart.

Если это выглядит как список, то это будет список

Давайте начнем с чего-то очень простого. Давайте посмотрим на тип коллекции списка, который мы все знаем и любим. Поскольку List поставляется со стандартной библиотекой Dart, все строится с его использованием. Когда я говорю все, я действительно имею в виду все. Например, добавление класса к элементу HTML выполняется не через какой-то непонятный DOM API, а с использованием стандартных операций со списком.

element.classes.add("my-class") //element.classes is List<String>
element.classes.remove("my-class")
element.classes.clear()

Точно так же вы не используете appendили не prependдобавляете элемент в DOM, потому что в Dart вы просто добавляете элемент в список узлов DOM.

var button = new ButtonElement()..text="OK";
element.nodes.add(button); //element.nodes is List<Node>

Эти два примера показывают, что стандартная библиотека Dart играет роль антикоррупционного слоя. Он скрывает все странности API DOM и дает вам единое представление о базовой платформе.

Стандартная библиотека — это антикоррупционный слой

В экосистеме JavaScript есть библиотеки, которые делают то же самое (например, jQuery), но Дарт выходит далеко за рамки этого. Это не просто тонкий слой поверх DOM. Стандартная библиотека Dart предоставляет строительные блоки, которые существенно повышают уровень абстракции. Одним из них является Stream.

Реактивное программирование с потоками

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

Streams

Теперь это становится интересным. Если вы посмотрите на эти две картинки потока и списка, вы заметите, что они выглядят одинаково.

Потоки и списки

Думаю об этом. Списки и потоки — это просто последовательности значений. Единственное отличие состоит в том, что списки являются последовательностями на основе извлечения, а потоки являются последовательностями на основе выталкивания. Другими словами, работая со списком, вы извлекаете значения из него, пока не достигнете его конца. Поток, с другой стороны, толкает значения до тех пор, пока ничего не останется.

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

var inputs =
  query("#query").
  onKeyUp.
  map((event) => event.target.value).
  where((text) => text.length > 2).
  transform(new Throttle(500)).
  distinct();

inputs.
  map(queryWikipedia).
  where(validResponse).
  listen(printResults);

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

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

inputElement.onKeyUp //Stream<KeyboardEvent>
webSocket.onMessage //Stream<MessageEvent>
mvcModel.onChange //Stream<ChangeEvent>

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

Стандартная библиотека => Композиционность объекта

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

Стандартная библиотека => Возможность компоновки библиотеки

Повышение уровня абстракции

Тот факт, что что-то вроде Stream предоставляется стандартной библиотекой, имеет большое значение, поскольку его можно использовать на границе API других библиотек. Таким образом, большинство библиотек Dart работают с потоками.

В JavaScript, с другой стороны, даже если вы создаете библиотеку поверх Bacon.js, вы не можете сделать Bacon.js частью API вашей библиотеки, потому что если вы возвращаете поток Bacon.js, большинство других библиотек не будут знать, что с ним делать, что заставляет вас использовать обратные вызовы. Вот почему все, кто говорит, что JavaScript достаточно гибок для реализации чего-либо, теряют смысл. Конечно, вы можете реализовать потоки в JavaScript, но чтобы действительно повысить уровень абстракции, вы должны сделать их вездесущими.

Завершение

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

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

Узнайте больше о дартс

Узнайте больше о Дарт на сайте engineering.nulogy.com .