Книги делятся на две категории: fiction и non-fiction. Технические книги — внезапно — не исключение, и поддаются точно такой же классификации. Между учебником по научной дисциплине, начинающегося с аксиоматики и продолжающегося доказательствами теорем, — и практически любой современной литературой по «Computer Science» — лежит пропасть. Что происходит, когда люди долгое время оказываются рабами одной-единственной книги (с продолжениями), нам хорошо известно из истории. Возникает религия.
Потом выясняется, что в рамках «строгой», если так можно выразиться, религии, — людям во всем их многообразии становится тесновато, и появляются секты. Многие годы (фактически тысячелетия) научный подход все больше и больше вытесняет религиозный, и доказательства ценятся в среде так называемых «образованных» людей — больше слепой веры. Везде, кроме той самой пресловутой «Computer Science». Я беру это словосочетание в кавычки, потому что наукой там является буквально мизерная часть, которая по сути своей не что иное, как прикладная математика.
Знаете, что такое «паттерн»? — Это обобщение тезиса «Я подбросил монетку два раза, и она в обоих случаях упала орлом вверх. Орёл — вот на что нужно ставить в казино!». При этом монетка, скорее всего, была не однородной, подбрасывал её хорошо натренированный человек, в вакууме, среди неоднородных гравитационных полей, и у монетки были две одинаковые стороны с орлом на каждой. Кому вообще нужна решка на гирьке для аптекарских весов?
99% процентов литературы по ООП — это талмуд. Вероятность того, что вам подойдет «паттерн» — примерно 50%. Как встретить динозавра на Невском. Знание паттернов полезно в той же степени, что и теология, — и примерно тем же по специальности людям. Всегда полезно уметь отличать по запаху Пана от простого фавна, но практических применений такой эрудиции — не существует.
Например: Singleton
Давайте для примера посмотрим на один из самых простых (и широкоизвестных) паттернов: «Singleton». Его предназначение (согласно Вике):
У класса есть только один экземпляр, и он предоставляет к нему глобальную точку доступа. […] Существенно то, что можно пользоваться именно экземпляром класса, так как при этом во многих случаях становится доступной более широкая функциональность. Например, к описанным компонентам класса можно обращаться через интерфейс […]
Пока неясно, зачем. Давайте читать дальше:
Глобальный «одинокий» объект — именно объект (
log().put("Test");
), а не набор процедур, не привязанных ни к какому объекту (logPut("Test");
) — бывает нужен, если:
Используется существующая объектно-ориентированная библиотека и ей нужен объект, унаследованный от определённого класса/интерфейса.
Есть шансы, что один объект когда-нибудь превратится в несколько.
Дополнительные факторы, исполнимые в обеих концепциях, но хорошо сочетающиеся с методикой ООП:
Интерфейс объекта (например, игрового мира) слишком сложен, и объект/префикс log служит для организации API.
В зависимости от каких-нибудь условий и настроек, создаётся один из нескольких объектов. Например, в зависимости от того, ведётся лог или нет, создаётся настоящий объект, пишущий в файл, или «заглушка», ничего не делающая.
Создание объекта занимает время, и для красоты объект можно создавать, когда на экране уже что-то видно.
Вы видите выше что-нибудь, что может предстать перед вами в момент решения какой-нибудь задачи, как камень преткновения? Я — нет.
Историческая справка: в эрланге модуль :global появился до возникновения термина «ООП». Безо всяких паттернов. Обычный именованный процесс не может быть запущен дважды в пределах одной ноды, глобальный именованный процесс — в пределах кластера. Попытка запустить такой процесс повторно приведет к тому, что из вызова вернется ошибка
{:error, {:already_started, pid}}
, содержащая, на всякий пожарный, идентификатор уже запущенного процесса.
Нужно ли эту реализацию называть специальным словом «паттерн» и обособлять среди других конструкций языка? — Нет, если вы не стараетесь заработать на написании очередной бессмысленной книги. Это просто процесс, такой же, как остальные, просто именованный. Имя уникально. Имена в «Computer Science» вообще обычно уникальны. Никакой когнитивной нагрузки. Никаких подводных камней на собеседовании.
Или вот ещё.
Например: Abstract Factory
Абстрактная фабрика, а не гулькин нос, ясно вам? Нет, серьёзно? Почему я не могу просто создать что-нибудь? Мы же как-то обходимся без абстрактных фабрик при создании констант, переменных, функций, наконец? Что такого специального в объектах?
Историческая справка: в эрланге есть 8 типов данных, из которых всего три — сложные (я немного упрощаю, но без потери общности): списки, кортежи и мапы. Причем мапы появились недавно. И знаете что? — им не нужны фабрики по их производству.
Нет объекта — нет проблемы, как говорил по другому поводу и другими словами один тиран. Чем объект отличается от просто данных? — Ну, наличием методов. Но ситуация, в которой сущность меняется изнутри — исчезающе редка. Кроме барона Мюнхгаузена, тащившего себя за волосы из болота, — так навскидку и не припомнить иной пример.
Иными словами, у нас есть какаой-то другой объект, который совершает действие над нашими данными. Почему же в таком случае методы — вдруг становятся атрибутом объекта приложения усилий, а не субъекта? Инкапсуляция? — Да нет, инкапсуляция достигается совсем другими способами, если вы не хотите завтра получить прямо в дышло вашей инкапсуляции — рефлексию и аспекты.
Последний пример: Adapter & Delegation
Согласно все той же Вике, Делегатор — это фундаментальный шаблон, а Адаптер — структурный. Стало яснее? Ха.
Знаете, кто является прапрабабушкой этих «паттернов»? — Процедура. Инструкция JMP
, если желаете. Вот есть кусок кода, который завтра может захотеться заменить на другой. Оформляем его в виде процедуры, вызываем из основной программы. Настало время улучшений? — Подменяем на другую процедуру с тем же именем. В случае динамической линковки — даже можно не перезапускать основную программу.
Но книга сама себя не напишет, коуч сам себя не прокормит, а кандидат на собеседовании — сам над собой не потешится. Паттерн (два!) вам в репу.
Да ты просто хейтишь ООП!
Ни в коей мере. Я считаю ООП (особенно Аланкаево, но и Гослингово тоже) — прекрасным инструментом, способным решать некоторый круг задач лучше любых других парадигм. Просто не нужно читать всю эту беллетристику вокруг, написанную в подавляющем большинстве людьми, не способными в настоящее индустриальное программирование. Есть такой широко известный в узких кругах персонаж, DHH, автор рельсов.
Он уже двадцать лет решает задачу доработки развесистого круда для своей конторы. Он придумал для этого рельсы — и видит бог! — абсолютно объектный фреймворк решает его задачу лучше всех хаскелей и лиспов вместе взятых. Может ли он перечислить хотя бы пять паттернов со страницы в Вике (или хотя бы из книжки «банды четырёх»?) — я сомневаюсь, а он лично сие отрицал.
Книжки по хорошим практикам, паттернам, и всей остальной околопрофессиональной шелухе наносят непоправимый вред индустрии, замыливая свежий взгляд и насаждая сектантские правила.
Прочитав книгу с посылом «как правильно» — вы получаете в награду когнитивное искажение, сдобренное авторитетом автора (абы кого книжку ведь писать не допустят, что тоже чушь, но сейчас не об этом).
Вместо собственного (возможно неверного) мнения по вопросу — вы обзаводитесь чужим (возможно неверным) мнением. Если не это есть религиозный фанатизм — я не знаю, что тогда.
Вспомните, как возникает любой хайп, — и последний бастион адептов чтения всякой макулатуры — «миллион мух не может ошибаться» — рухнет с таким же грохотом.
Где тогда взять правильное мнение?
Увы. Как я сказал выше — в подавляющем большинстве случаев в определении «Computer Science» уместно только первое слово. Никакой наукой за пределами Идриса (кока, агды, и компании), в некоторых местах и с оговорками — хаскеля, да различных систем типов — и не пахнет.
На вопрос «как решить задачу» — прекрасно отвечает документация, REPL и свой личный велосипед. На вопрос «как правильно решить задачу» — иногда отвечают метрики спустя десять лет эксплуатации, а иногда — ответа просто не существует в природе.
Ваш опыт ничем не хуже опыта авторов бестселлеров, а главное — он ваш. Если уж и вливаться в ту, или иную секту — то только в качестве её верховного главнокомандующего. В пищевых цепочках уместнее и прибыльнее находиться ближе к верхам.
Не формируйте никакого мнения на первых порах. Читайте код, написанный умными людьми, вместо фэнтези, написанной неизвестно кем. С опытом придет понимание важных вещей. Вы сможете заточить своё ООП кунфу, легко переходить в акторную модель, когда уместно, и не брезговать ФП (которое ничуть не сложнее и уж подавно не хуже ООП).
Когда я говорю «опыт», я имею в виду лет десять-пятнадцать минимум, три-пять разных языков минимум и детальное понимание архитектуры и принятых решений в пяти-семи крупных проектах минимум.
Тогда можете начинать формировать собственный взгляд на хорошие практики и уместные парадигмы. До того — оставайтесь максимально непредвзяты. Думайте своей головой, не позволяйте дутым авторитетам из интернетов заменять вам мыслительный процесс своими сектантскими лозунгами.
Удачного нигилизма!