Стратифицированный дизайн. Часть № 2 #
Презентация #
Презентацию по теме лекции можно открыть по ссылке.
Видео-запись: Rutube
Документация #
Задания #
Задания выполняются на языке JavaScript в стиле лекции. Для каждого решения приводите обоснование: какое свойство дизайна улучшается и почему выбранное место для кода лучше альтернатив. Справочник по используемым методам: Object, Array.
-
Замена структуры данных за барьером. Корзина реализована массивом, ниже приведены функции барьера из абстракций:
function add_item(cart, item) { return add_element_last(cart, item); } function remove_item_by_name(cart, name) { var index = indexOfItem(cart, name); if (index !== null) return removeItems(cart, index, 1); return cart; } function isInCart(cart, name) { return indexOfItem(cart, name) !== null; } function indexOfItem(cart, name) { for (var i = 0; i < cart.length; i++) { if (cart[i].name === name) return i; } return null; } function calc_total(cart) { var total = 0; for (var i = 0; i < cart.length; i++) { total += cart[i].price; } return total; }Переведите корзину на ассоциативный массив: реализуйте новые версии функций слоя и перечислите, какие функции пришлось изменить, а какие остались нетронутыми. Сформулируйте, что доказывает неизменность функций, лежащих выше барьера.
-
Поиск протечки в барьере. Команда маркетинга написала код, который работает с корзиной:
function has_expensive_item(cart) { for (var i = 0; i < cart.length; i++) { if (cart[i].price > 100) return true; } return false; } function promo_applies(cart) { return indexOfItem(cart, "promo") !== null && calc_total(cart) > 50; }Определите, в каких местах барьер неполный, какие функции нужно добавить в слой, чтобы пользователи могли обойтись без деталей реализации, и перепишите пользовательский код. Отдельно ответьте: что сломается в этом коде после перехода корзины на ассоциативный массив.
-
Минимальный интерфейс. Даны три варианта реализации одной маркетинговой функции. Выберите лучший и обоснуйте решение, а также объясните, что не так с двумя другими и какие обязательства появляются у команды, поддерживающей корзину, в каждом варианте.
// A: внутри барьера function getsWatchDiscount(cart) { var total = 0; var names = Object.keys(cart); for (var i = 0; i < names.length; i++) { total += cart[names[i]].price; } return total > 100 && Object.hasOwn(cart, "watch"); } // B: над барьером function getsWatchDiscount(cart) { return calc_total(cart) > 100 && isInCart(cart, "watch"); } // C: гибридный вариант function getsWatchDiscount(cart) { return calc_total(cart) > 100 && cart["watch"] !== undefined; } -
Действие в слое вычислений. Ниже приведён код корзины, в который встроена запись в журнал:
function add_item(cart, item) { logAddToCart(global_user_id, item); return objectSet(cart, item.name, item); } function update_shipping_icons(cart) { var buttons = get_buy_buttons_dom(); for (var i = 0; i < buttons.length; i++) { var item = buttons[i].item; var new_cart = add_item(cart, item); if (gets_free_shipping(new_cart)) button.show_free_shipping_icon(); } }Покажите цепочку функций, которые становятся действиями из-за вызова
logAddToCart, и объясните, почему запись в журнал будет появляться при просмотре товаров пользователем. Предложите более удачное место для вызова и обоснуйте, почему выбранная функция уже была действием. -
Анализ графа вызовов. Дан фрагмент графа вызовов приложения интернет-магазина:
checkout_handler -> validate_order, calc_total, send_receipt validate_order -> check_fields, check_stock check_stock -> fetch_stock fetch_stock -> HTTP-запрос calc_total -> доступ к полям товара send_receipt -> build_receipt, print_receipt, update_db build_receipt -> доступ к полям заказаОтветьте на три вопроса с обоснованием:
- в какую часть графа поместить новое правило расчёта скидки, которое меняется каждый месяц;
- с каких функций начать написание тестов при ограниченном бюджете и что именно они покрывают;
- какая функция наиболее пригодна к повторному использованию в другом приложении и почему.
-
Оценка пользы барьера. Команда из трёх человек обсуждает выделение барьера из абстракций над таблицей тарифов. Известно, что:
- структура данных тарифов менялась один раз за два года;
- обращение к тарифам встречается в 40 местах;
- кроме команды тарифы используют две другие команды через те же функции;
- изменение поля тарифа требует правки кода в нескольких местах.
Примените шаблон «удобные слои»: решите, стоит ли выделять барьер, какие последствия будет иметь это решение для трёх команд и по какому признаку следует понять, что дальше улучшать дизайн не нужно.