Декларативные запросы в Интернете
Пример сравнения декларативных и императивных подходов из книги "Высыко-нагруженные приложения. Программирование, масштабирование, поддержка" Мартина Клеппмана
Преимущества декларативных языков запросов не ограничиваются использованием только в базах данных. Чтобы проиллюстрировать это утверждение, сравним декларативный и императивный подход в совершенно другой среде: браузере.
Допустим, у нас есть сайт, посвященный морским животным. Пользователь сейчас просматривает страницу об акулах, так что мы помечаем пункт меню Sharks как выбранный в настоящий момент, вот так:
<ul>
<li class="selected">
<p>Sharks</p>
<ul>
<li>Great White Shark</li>
<li>Tiger Shark</li>
<li>Hammerhead Shark</li>
</ul>
</li>
<li>
<p>Whales</p>
<ul>
<li>Blue Whale</li>72 Часть I. Основы информационных систем
<li>Humpback Whale</li>
<li>Fin Whale</li>
</ul>
</li>
</ul>
- Выбранный пункт помечен классом CSS "selected" .
- Заголовок выбранной в настоящий момент страницы — <p>Sharks</p> .
Теперь допустим, что фон заголовка выбранной в настоящий момент страницы должен быть синим — для визуального выделения. Это можно легко сделать с помощью CSS:
li.selected > p {
background-color: blue;
}
Тут CSS-селектор li.selected > p объявляет шаблон для элементов, для которых мы выбираем синий стиль: это все элементы <p> , чьим непосредственным родителем является элемент <li> с CSS-классом selected. Элемент <p>Sharks</p> в примере соответствует этому шаблону, а <p>Whales</p> — нет, поскольку у его родительского класса отсутствует class="selected" .
Если же использовать XSL вместо CSS, то можно сделать нечто схожее:
<xsl:template match="li[@class='selected']/p">
<fo:block background-color="blue">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
В этом фрагменте кода XPath-выражение li[@class='selected']/p эквивалентно CSS-селектору li.selected > p из предыдущего примера. XSL и CSS объединяет то, что они оба — декларативные языки описания стилей документа.
Представьте только, как выглядела бы ваша жизнь, если бы пришлось задействовать императивный подход. В JavaScript при использовании базового API объектной модели документа (document object model, DOM) результат выглядел бы примерно так:
var liElements = document.getElementsByTagName("li");
for (var i = 0; i < liElements.length; i++) {
if (liElements[i].className === "selected") {
var children = liElements[i].childNodes;
for (var j = 0; j < children.length; j++) {
var child = children[j];
if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "P") {
child.setAttribute("style", "background-color: blue");
}
}
}
}
JavaScript императивно задает синий цвет фона для элемента <p>Sharks</p> , но код ужасен. Он не только намного длиннее и труднее для понимания, чем эквивалентный код XSL/CSS, но и включает некоторые довольно серьезные проблемы.
При удалении класса selected (например, при щелчке пользователя на другой странице) синий фон останется даже в случае повторного выполнения кода, так что элемент останется выделенным до тех пор, пока не будет перезагружена страница целиком. В CSS браузер автоматически определит, когда правило li.selected > p перестанет действовать и уберет синий фон сразу же при удалении класса selected .
Если вам хотелось бы воспользоваться преимуществами нового API, например document.getElementsByClassName("selected") или даже document.evaluate() — для улучшения производительности, то придется переписать код. С другой стороны, создатели браузеров имеют возможность улучшать производительность CSS и XPath без нарушения совместимости.
В браузере использование декларативных CSS-стилей намного удобнее императивного управления стилями из JavaScript. Аналогично в базах данных декларативные языки запросов, такие как SQL, оказываются намного более удобными, чем императивные API запросов.
Теперь у вас тоже появилоась желание изучать функциональные языкы с декларативным подходом? :D
Статья написана для @response418