Книга «Грокаем функциональное мышление»

image Как дела, Хаброжители?

Кодовые базы разрастаются, становясь всё сложнее и запутаннее, что не может не пугать разработчиков. Как обнаружить код, изменяющий состояние вашей системы? Как сделать код таким, чтобы он не увеличивал сложность и запутанность кодовой базы?

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

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

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

Для кого написана эта книга

Книга написана для программистов с практическим опытом от 2 до 5 лет. Предполагается, что вы уже знаете хотя бы один язык программирования. Также желательно, чтобы вы построили хотя бы одну достаточно крупную систему, чтобы представлять, с какими проблемами разработчики сталкиваются при масштабировании. Примеры написаны в стиле JavaScript, направленном на читаемость кода. Если вы понимаете код C, C#, C++ или Java, у вас не будет особых сложностей.


Отдел маркетинга все еще должен согласовывать действия с разработчиками


Абстрактный барьер, который позволил предоставить удобный API для отдела маркетинга, работал, но не так, как было задумано. Да, большая часть работы могла выполняться без координации, но часто отдел маркетинга предлагал команде разработчиков добавить в API новые функции, которые нельзя было выполнить средствами существующего API. Примеры таких запросов:

image


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

Признак «кода с душком»: неявный аргумент в имени функции


Команда маркетинга должна иметь возможность изменять товары в корзине для реализации своих рекламных акций, например назначить некоторым товарам бесплатную доставку или обнулить их цену. Команда разработки потрудилась и написала функции, удовлетворяющие потребностям маркетинга. Тем не менее выглядят эти функции очень похоже. Ниже приведены четыре функции, у которых действительно очень много общего:

image


В этом коде присутствует серьезный признак «кода с душком». Впрочем, если честно, от этих строк вообще разит. Первый и самый заметный признак — дублирование кода. Эти четыре функции почти идентичны.

Но есть и другой, более тонкий признак: главное различие между функциями — строки, определяющие поле, — также содержится в имени функции. Все выглядит так, словно имя функции (или его часть) передается в аргументе. Вот почему этот признак называется неявным аргументом в имени функции. Вместо явной передачи в аргументе значение «передается» как часть имени.

image


image


Директор по маркетингу: Код может пахнуть?

Дженна: Да, в каком-то смысле. Выражение просто означает, что в коде на что-то стоит обратить внимание. Это не значит, что код плох, но это может быть признаком существующей проблемы.

Ким: Да! Этот код определенно попахивает. Только посмотри на все это дублирование.

Дженна: Да, код действительно очень похож. Но я не вижу, как избавиться от дубликатов. Нам нужны средства для назначения цены и количества единиц товара. Разве это не разные функции?

Ким: Дублирование означает, что эти функции почти одинаковы. Единственное различие — строка с именем поля ('price', 'quantity' или 'tax').

Дженна: Да, понимаю! И эта строка также присутствует в имени функции.
Ким: Точно. И это признак «кода с душком»: вместо передачи в аргументе имя поля становится частью имени функции.

Директор по маркетингу: И вы говорите, что его можно исправить?

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

Директор по маркетингу: Первоклассным? В смысле первого класса — как в поезде или самолете?

Ким: Хм. Да, пожалуй. Это просто означает, что имя поля становится аргументом. Мы определим его позднее.

Рефакторинг: явное выражение неявного аргумента


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

Последовательность действий выглядит так:
1. Выявление неявного аргумента в имени функции.
2. Добавление явного аргумента.
3. Использование нового аргумента в теле вместо жестко фиксированного значения.
4. Обновление кода вызова.

Посмотрим, как провести рефакторинг функции setPriceByName (), которая может задать только цену, в функцию setFieldByName (), способную задать значение любого поля товара.

image


Применение этого рефакторинга к коду позволяет заменить четыре существующие функции одной обобщенной, — и кто знает, сколько еще функций нам не придется писать благодаря обобщенной функции setFieldByName ().

Что же здесь произошло? Имя поля было преобразовано в первоклассное значение. Ранее имя поля не раскрывалось перед клиентами API, кроме как в случае неявного раскрытия как части имен функций. Теперь оно стало значением (в данном случае строкой), которое может передаваться в аргументе, но также может храниться в переменной или массиве. Именно это имеется в виду под первоклассным значением: для работы с ним может использоваться полный набор языковых средств. Преобразование к первоклассному статусу является темой этой главы.

На это можно возразить, что такое использование строк небезопасно. Эта тема будет рассмотрена на ближайших страницах, а пока просто продолжайте читать!

Загляни в словарь
Первоклассное значение может использоваться так же, как и любые другие значения в языке.
image


Директор по маркетингу: И нам не придется подавать заявку на изменение каждого поля?

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

Директор по маркетингу: Как мы узнаем, как называется то или иное поле?

Ким: Очень просто. Мы сделаем имена частью спецификации API. Они будут частью абстрактного барьера.

Директор по маркетингу: Хмм… Идея мне начинает нравиться. Но тогда другой вопрос:, а если вы добавите новое поле в спецификацию корзины или товара? Что тогда?

Дженна: Новая функция должна работать как с существующими, так и с новыми полями. Если мы добавляем новое поле, то должны будем сообщить вам его имя, и тогда вы сможете пользоваться всеми функциями, которые вам известны.

Директор по маркетингу: Звучит неплохо. Кажется, такой подход сильно облегчит нашу задачу.

Ким: Так и должно быть! В старом варианте вы должны были знать набор функций (и подавать запросы на новые функции!), а теперь достаточно знать одну функцию и набор имен полей.

image


Более подробно с книгой можно ознакомиться на сайте издательства:
» Оглавление
» Отрывок

По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — Мышление

© Habrahabr.ru