Стратифицированный дизайн. Часть № 1 #
Презентация #
Презентацию по теме лекции можно открыть по ссылке.
Видео-запись: Rutube
Документация #
Задания #
Задания выполняются на языке JavaScript в стиле лекции. Графы вызовов рекомендуется оформлять в mermaid или Graphviz (dot -Tsvg). Для каждого задания приводите краткое обоснование принятых решений.
-
Построение графа вызовов. Постройте граф вызовов функции
apply_discountс указанием как функций, так и использованных конструкций языка. Выделите элементы, которые находятся на более низком уровне абстракции, чем остальные, и предложите, какие из них следует скрыть за функциями.function apply_discount(cart, percent) { var copy = cart.slice(); if (!isInCart(copy, "loyalty card")) return copy; for (var i = 0; i < copy.length; i++) { copy[i] = setPrice(copy[i], copy[i].price * (1 - percent / 100)); } return copy; } -
Выделение слоёв по списку вызовов. Даны функции для работы с библиотекой книг и их зависимости:
borrowBook(library, isbn) -> isAvailable, arraySet returnBook(library, isbn) -> isAvailable, arraySet isAvailable(library, isbn) -> indexOfBook indexOfBook(library, isbn) -> цикл for, доступ по индексу arraySet(array, index, value) -> .slice(), доступ по индексу hasOverdueBooks(reader) -> isOverdue, длина массива isOverdue(reader) -> цикл for, доступ по индексуПостройте граф вызовов, выделите слои, назовите назначение каждого слоя и укажите функцию, которая нарушает единый уровень детализации либо находится не на своём слое. Обоснуйте ответ.
-
Несложная реализация. Функция
has_giftсмешивает уровни абстракции: она одновременно работает с бизнес-правилом и с элементами массива. Приведите её к несложной реализации: выделите функции чтения и перестройте вызовы так, чтобыhas_giftоперировал только функциями одного уровня.function has_gift(cart) { var hasBook = false; var hasBookmark = false; for (var i = 0; i < cart.length; i++) { if (cart[i].name === "book") hasBook = true; if (cart[i].name === "bookmark") hasBookmark = true; } return hasBook && !hasBookmark; }Постройте графы вызовов до и после изменения и сравните количество слоёв, которые затрагивает функция.
-
Выделение общей функции. Две функции ниже содержат одинаковый цикл поиска. Реализуйте одну из них в терминах другой, обоснуйте, какая из функций находится ниже, и постройте диаграмму вызовов, включая обращение к циклу
forи индексный доступ.function isInLibrary(library, isbn) { for (var i = 0; i < library.length; i++) { if (library[i].isbn === isbn) return true; } return false; } function bookIndex(library, isbn) { for (var i = 0; i < library.length; i++) { if (library[i].isbn === isbn) return i; } return null; } -
Три уровня масштаба. Для каждого фрагмента определите, на каком уровне масштаба видна проблема: глобальном (взаимодействие между слоями), уровне слоя или уровне одной функции. Предложите исправление для найденной проблемы.
// A function setQuantityByName(cart, name, quantity) { var index = indexOfItem(cart, name); if (index !== null) return arraySet(cart, index, setQuantity(cart[index], quantity)); return cart; } // B function remove_item_by_name(cart, name) { var index = null; for (var i = 0; i < cart.length; i++) { if (cart[i].name === name) index = i; } if (index !== null) return removeItems(cart, index, 1); return cart; } function indexOfItem(cart, name) { for (var i = 0; i < cart.length; i++) { if (cart[i].name === name) return i; } return null; }В варианте A дополнительно оцените длину стрелок графа и укажите, после какого изменения длина самой длинной стрелки сократится. В варианте B поясните, почему проблему нельзя увидеть, рассматривая только одну из функций.
-
Размещение новой функции в слоях. Для корзины уже есть функции
isInCart,remove_item_by_name,add_item,calc_total,setPrice,setPriceByNameи слой КПЗ-операций (arraySet,removeItems). Требуется добавить функциюremove_cheapest(cart), которая удаляет из корзины самый дешёвый товар.- Определите слой для новой функции и обоснуйте решение через её зависимости и назначение.
- Постройте граф вызовов, если бы функция реализовывалась напрямую через элементы массива, и граф после применения шаблона несложной реализации.
- Назовите, какие новые функции общего назначения потребовалось выделить и на каком слое они оказались.