Building Evolutionary Architectures

https://learning.oreilly.com/library/view/building-evolutionary-architectures/9781491986356/

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

В первых главах автор (их несколько, но думаю кто-то из них 🙂 ) рассуждает о том, что в современном мире программные системы не статичны — возможность развития и изменения в соответствии с меняющимися условиям бизнеса является важным требованием сама по себе. При этом любая архитектура программной системы должна удовлетворять своему списку -bilitys (например scalability / high availability / security / … ). Пусть мы определили, какие требования к архитектуре нашей системы и наш программный продукт удовлетворяет им в текущий момент, но если мы говорим о поддержке изменений и развития необходимо отслеживать, что все эти -bilitys продолжают соблюдаться. Для этой цели вводятся fitness functions — измеримые показатели соответствия каждому из -bilitys. Это могут быть время отклика веб страницы, время доставки товара, количество инцидентов, степень покрытия тестами и т.п. Мы встраиваем измерение этих характеристик или просто в наш мониторинг или если речь про характеристики кода — прямо в пайплайн, не позволяя им снижаться.

Далее он рассуждает о разных архитектурах и насколько легко они поддаются эволюции. Несколько легко для них отслеживать связи и зависимости, определять фитнес функции, писать функциональные тесты. Начинает с big ball of mud и через монолит, систему с интеграционной шиной, сервисную архитектуру доходит до микросервисной. В процессе часто упоминается DDD и присущие ему идеи, такие как bounded contexts.

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

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

В последних главах автор рассуждает о том как внедрять эволюционные подходы к построению архитектуры в существующие проекты, а также надо ли это делать. И это очень важные мысли — во-первых, все эти подходы не бесплатны и требуют дополнительных затрат времени и мыслетоплива. Нет смысла применять их, если мы делаем проект, время жизни которого изначально строго ограничено. Во вторых, они имеют смысл начиная с определенного размера проекта (как по объему кода, так и по количеству людей в команде) и должны включать в себя не только технические, но и что важнее определенные организационные подходы. Слабая связанность, микросервисы и т.п. упрощают развитие ПО, только если за эти разные слабо связанные сервисы отвечают разные команды

В целом, повторюсь — потраченного на книгу времени не пожалел 🙂 Идея с фитнес-функциями вроде как лежит на поверхности, но тщательно проговоренная и подкрепленная примерами — особенно хороша.

Isaac Asimov — Foundation’s Edge

Четвертая книга серии (по времени написания) скорее разочаровала. Ответ на вопрос, кто же хранит хранителей оказался прямолинеен — ещё более секретные и ещё более могущественные Хранители. Правда итоговая цель у них более благородная, потому что — тадамс, они направляются роботами, скованными тремя законами робототехники. Прошу прощения за спойлеры (если это применимо к книге, которой много-много лет), но честно говоря, когда стало понятно к чему все идёт, оно как-то совсем не впечатлило.

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

Татьяна Мужицкая — Теория невероятности

Автора посоветовали в каком-то из выпусков подкаста разговоры СТО, ну и решил попробовать послушать.

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

Автор приводит целую систему с построением квадрантов и разной работой с разными желаниями в зависимости от того, насколько их выполнение в наших силах. Но в целом большая часть упражнений сводится к максимально подробному вытаскиванию из себя, чего же ты на самом деле хочешь. Ну а когда желание абсолютно точно формализовано — то тут и сам начинаешь идти к его достижению 🙂 Ещё автор пропагандирует лёгкое отношение к жизни и миру и ожидание от него добра — выбери сам в каком мире ты хочешь жить — мне это близко )

Роберт Сапольски — Кто мы такие? Гены, наше тело, общество

Книга американского нейроэндокринолога. Не знаю зачем в переводе в корне поменяли название — оригинальное гораздо лучше передает суть книги — Monkeyluv: And Other Essays on Our Lives as Animals. Сборник эссе, с обсуждением различных тем, слабо связанных между собой (разве что юмором автора).

Что важнее — гены или воспитание и среда? Действительно внешние признаки (рога у оленей, павлиньи хвосты и т.п.) говорят о лучших генах у их носителя или это просто трата кучи энергии в никуда? Почему во сне всё как во сне — и как отвечая на одни вопросы о работе нашего организма мы в итоге остаемся только со следующим уровнем вопросов? Почему так притягательны азартные игры — рассуждения на примере наблюдавшейся автором френдзоны у обезьян. Почему для нас так важны тела погибших? Как тело влияет на мозг и почему нам так трудно успокоиться после ссоры, когда мы уже завелись? Что ещё можно влиять на мозг — например мозговые паразиты, бррр (пример с токсоплазмой, заставляющей грызунов не бояться кошек впечатляет). Известно, что чтобы жить долго и не болеть — лучше быть богатым 🙂 но иногда это не так и некоторые болезни показывают обратную зависимость — но всегда ли это правда и существуют болезни богатых, или просто у бедных их не диагностируют? Как отличаются культуры пустынь и влажных лесов и как так вышло, что доминирующими культурами на планете стали именно культуры пустынь?

Интересно, подробно, научно и при этом очень живо и с юмором. Понравилось, думаю, что стоит почитать ещё и закинул в план чтения его Психологию стресса 🙂

Eric Evans — Domain-Driven Design: Tackling Complexity in the Heart of Software

После короткой книги Vladik Khononov я решил, что надо углубиться в тему DDD и прочитать книгу Eric Evans, раскрывающую тему более подробно. Совсем не пожалел и в очередной раз убедился, что некое краткое изложение — это хорошо, но более подробная и полная книга позволяет действительно проникнуться идеями.

Книга состоит из 4х больших частей.

В первой автор рассуждает о важности общей модели предметной области — общей и для программистов и для представителей бизнеса. Сама мысль изложена и в What is domain driven design, но тут она подается подробнее, с примерами из жизни. Интересная мысль, что целостность модели и ее общий язык — это не только то о чем мы договорились в начале. Если в процессе работы мы нашли более удачные слова, точнее описывающие нашу область и лучше понятные бизнесу, то необходимо отразить это в том числе в коде. Необходим рефакторинг кода, для того чтобы используемый в нем язык продолжал совпадать с языком модели, чтобы не происходило постепенного расхождения.

Во второй — автор переходит от общих рассуждений о моделецентричности при разработке к конкретным предложениями как проектировать ПО так, чтобы в итоге оно отражало модель предметной области. Для этого сначала вводятся понятия entity, value object, service описывающие различные составные части системы. Затем — aggregate, группирующий их в тесно связанные с точки зрения бизнеса блоки, factory — для создания сущностей и агрегатов, repository — для внешнего хранения сущностей и восстановления их из внешнего хранилища в память. В конце главы приводится пример проектирования системы управления перевозкой товаров на основе предлагаемых принципов из этих кирпичиков.
С одной стороны здесь не описывается ничего революционного, но с другой методично и с примерами показывается как может быть упрощена или наоборот усложнена система, если глубже вникнуть в бизнес требования и отразить их при проектировании. Как влияет на дизайн правильное понимание, что в бизнес области является entity, а что просто value, т.е. определяется только своими свойствами и не требует отслеживания уникальности. Как упрощает систему замена двунаправленных связей однонаправленным, где это возможно. Как грамотное использование репозиториев может решать проблемы с конкретными изменениями (опять таки если бизнес требования позволяют это)

В третьей части автор обсуждает рефакторинг, как необходимый компонент поддержания соответствия кода модели, по мере ее изменения и усовершенствования. Начинает он с примера из жизни, когда вникнув глубже в доменную область, удалось создать более удачную её модель, что с одной стороны позволило упростить дальнейшую разработку, устранив недопонимания с бизнес-заказчиками, но с другой потребовало существенного переписывания системы под новую модель. После этого, ещё порассуждав о том, что модель постоянно улучшается и меняется — переходит к рассуждениям о гибком и в то же время понятном дизайне приложений. Сначала обсуждается, как лучше отражать бизнес-правила и ограничения в коде. Альтернативой вынесения сложной бизнес логики в уровень приложения предлагается создание классов-спецификаций, инкапсулирующих внутри себя проверку неких бизнес-правил, а возможно во взаимодействии с репозиториями и выборку объектов, удовлетворяющих спецификации.
Другими инструментами гибкого дизайна автор называет:
— интерфейсы, с понятными названиям как самих классов, так и методов, чтобы из самих их названий было понятно, что они делаютчистые функции
— операции над иммутабельными объектами
— операции над value objects, которые бы возвращали новые value objects

В четвертой части автор переходит к вопросам организации работы большой компании со сложным продуктом, над которым работает несколько команд. На примерах он показывает, какие проблемы могут возникнуть, когда команды работают в рамках своих моделей, но их границы четко не очерчены и одна команда может вносить изменения, нарушающие работу кода, поддерживаемого другой. Чтобы не допускать таких проблем предполагается концепция bounded contexts — четко очерченных границ моделей, с понятными местами их пересечения. Если это сделано — то, как минимум проблема обозначена и обозначены пересечения, по которым работа должна быть в какой-то степени совместной и надо принять решение как будет построена эта работа.
Автор рассматривает следующие способы взаимодействия команд, по степени уменьшения степени интеграции: continuous integration, shared kernel, upstream/downstream, anticorruption level, open host service, separate ways. Суть ясна из названий, разве что стоит пояснить что под anticorruption автор понимает набор фасадов/адаптеров, которые защищают нашу модель от «повреждения» неподходящей нам чужой моделью. Важная мысль при этом, что выбор модели взаимодействия — это чаще всего не техническое, а организационное решение и зависит прежде всего от размера команд, их взаимоотношений, их организационной подчинённости, общности их целей.

Но возвращаясь чуть назад, как разделить единую и ставшую слишком сложной и запутанной модель на отдельные bounded contexts, чтобы с одной стороны над ними могли работать независимые команды, а с другой — чтобы усилия наиболее сильных программистов (команд) были направлены на действительно важные вещи, а какие-то менее критичные могли бы быть сделаны силами джунов или вовсе отданы на аутсорс?
Для этого необходимо провести model distillation — анализ модели и выделение, что в ней является нашим core domain — тем, что мы на самом деле делаем, что составляет цель нашего продукта, чем он отличается от конкурентов. А что является generic / supporting domains — частями продукта, которые необходимы, но при этом могут быть такими же как у всех вокруг, решают задачи поддержки, не являются основными. Часто такими частями являются биллинг, поддержка, общие технические модели работы с сетью / датами и т.п.
Для упрощения основной модели полезно выделить generic subdomains в отдельные модули / команды, а возможно и отдать на аутсорс для ускорения разработки. Другим подходом может быть наоборот явное выделение в отдельный модуль / сервис в первую очередь core domain (автор называет этот подход segregated core), а уже потом распиливание остатка.

В конце книги автора рассуждает о том, как поддерживать целостный дизайн больших сложных систем. Одним из решений для этого он видит слоеную архитектуру, которая бы с одной стороны ограничивала дизайн-решения, не позволяя создать беспорядочный клубок связей, с другой стороны делала бы систему более понятной (в том числе за счёт дополнительной информации о принадлежности модулей разным слоям). Но при этом автор предупреждает об опасностях излишнего увлечения глобальными структурами / генеральными планами — когда они не дают достаточной гибкости программистам, они становятся не помощниками, а наоборот — силы начинают тратиться на поиски обходных путей и впихивание невпихуемого. Также плоха идея выделения специальной команды лучших программистов чисто для создания общей архитектуры — если они не участвуют в решении повседневных задач, то вероятность создания переусложненной и только мешающей работе системы повышается. И вообще

Team divisions that assume some developers are not smart enough to design are likely to fail because they underestimate the difficulty of application development. If those people are not smart enough to design, they shouldn’t be assigned to develop software. If they are smart enough, then the attempts to coddle them will only put up barriers between them and the tools they need

Оливер Сакс — Человек, который принял жену за шляпу

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

Первая история, давшая название книге, рассказывает о человеке, не просто потерявшем способность различать лица, но даже больше — способность узнавать предмет по его набору свойств — например, видя перчатку, он не может понять что это она, а описывает ее как соединённые между собой кожаные цилиндры.

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

Остаётся ли собой человек, потерявший из памяти 20 лет своей жизни и не помнящий больше последних нескольких часов?

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

Особенно впечатлила история пациента с синдромом Туретта

Что касается органической основы, синдром Туретта и «туреттизм» любого другого происхождения … можно сравнить с редкими, гиперкинетическими формами летаргического энцефалита, а также с перевозбужденными состояниями при приеме L-дофы. По-видимому, во всех этих случаях в мозгу возникает избыток стимулирующих трансмиттеров, в особенности дофамина. Отсюда следует, что, регулируя дофамин, можно влиять на показатели возбуждения. Например, для того чтобы снять апатию у пациентов с болезнью Паркинсона, уровень дофамина следует повысить (именно так, при помощи L-дофы, мне удалось «разбудить» постэнцефалитных пациентов, что описано в книге «Пробуждения»). Неистовые же туреттики нуждаются в понижении уровня дофамина, и для этого используются его нейтрализаторы, такие как галоперидол.

Нервная система работает не так, как в норме — но что есть норма? Может ли существовать человечество, в котором нормальной была бы именно такая работа нервной системы? И вообще, если говорить про то, как по разному может она работать — где грань на шкале от нормы к болезни — кофе, витамины, ноотропы и далее к картинке с Карлсоном ( https://www.meme-arsenal.com/memes/108742e654416037860620649b119726.jpg ).

Тем более и больной с синдромом Туретта при этом получал от своей болезни не только минусы:

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

и он в итоге даже жалеет о результатах лечения

В течение рабочей недели, принимая лекарство, Рэй остается, по его собственным словам, «солидным, трезвым дядей». Движения и мысли его неторопливы и обдуманны, без следа прежней порывистости, но и без каких-либо бурных импровизаций и блестящих идей. Даже сны его стали другими. «Сплошное исполнение желаний, – говорит он сам, – без всяких штучек и выкрутасов Туретта». Он не так колюч и находчив, из него не бьют больше ключом тикозные остроты и остроумные тики. В прошлом все его победы в настольном теннисе и в других играх, в прошлом и удовольствие от них. Рэй утратил инстинкт «побить и добить» соперника, а вместе с ним и склонность к соревнованию и игре. Исчезла внезапность «легкомысленных» ударов, всех застававших врасплох; пропали непристойности, грубая дерзость, вспыльчивость.

Vladik Khononov — What Is Domain-Driven Design?

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

  • Очень кратко описывается понятие домена (core / generic / supporting), субдоменов, ubiquitous language, bounded contexts.
  • Рассматриваются различные способы взаимодействия между командами, работающими в bounded contexts (как оно общепринято переводится на русский искать пока было лень).
  • По верхам пробегается по паттернам организации кода — transaction script, active record, domain model, event sourcing domain model.
  • Также по верхам по архитектурным паттернам — слоеная архитектура, порты и адаптеры, CQRS.
  • Дальше автор перескакивает от кода опять к организационным практикам — обсуждает event storming и эволюцию доменов (переход между core / generic / supporting при изменениях ситуации на рынке)

В целом показалось очень полезным именно чтобы познакомиться с основными понятиями DDD, основными идеями, не погружаясь при этом сразу глубоко.

Карен Прайор — Не рычите на собаку! Книга о дрессировке людей, животных и самого себя

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

Про книгу много отзывов, что она про обучение в целом, в том числе детей и коллег. И в целом да, общие идеи и мысли книги универсальны, но 90% всех примеров всё-таки из области дрессировки животных. При этом хотя самой книге как оказалось больше 35 лет, она не звучит устаревше. Проблема в том, что как недавно слышал уже не помню от кого — что и как делать правильно, знают уже многие, делают — почти никто. С этой точки зрения книга была полезна, поперекладывал описанные приемы на ситуации с детьми, подумал ещё раз где что можно было бы делать лучше 🙂

Philip K. Dick — The Man in the High Castle

Во второй мировой победили Германия и Япония, и действие книги происходит в части США, находящейся под японским протекторатом.

Альтернативная история, но книга всё-таки несколько больше, чем просто «а если бы история пошла по другому». Как минимум потому, что альтернативных историй тут две — герои книги на фоне происходящих с ними событий читают книгу в жанре альтернативной истории, где в войне победили Великобритания и США, без Советского Союза. И во всех трёх реальностях мы имеем две державы союзников, переходящих к соперничеству и войне (холодной или горячей) после неё. Так ли это неизбежно? Обе альтернативы в книге таковы, потому что в реальности так случилось, или есть более глубокие исторические законы, приводящие к этому? Ведь имеем мы сейчас нарастающее противостояние США и Китая (особенно если читать западную прессу). История полна аналогий, в том числе и альтернативная история — Черчилль, правящий 20 лет, к концу которых Британия скатывается в авторитаризм и альтернатива ему непредставима.

И И Цзин, Книга Перемен, Оракул, но не в западном понимании этого слова, он не даёт однозначного ответа, интерпретация сказанного всегда остаётся за спрашивающим. Когда в конце книги гексаграмма «Внутренняя правда» говорит героям, что Германия и Япония на самом деле проиграли в войне — это не пророчество и не откровение. Это ощущение самих героев о том, что их мир нереален, что так не могло быть на самом деле. А реален ли мир? И тот в романе, и этот — с президентом Трампом, войной между Россией и Украиной, людьми в масках на улицах…

Gregor Hohpe, Bobby Woolf — Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions

Книга посвящена паттернам построения приложений на базе систем передачи сообщений. Выпущена в 2003 году и это чувствуется (кругом XML и SOAP, древние версии .net и java) — но при этом основные идеи не устарели и замечательно перекладываются в голове на Redis, Kafka и т.п.

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

Во второй авторы рассматривают 4 основных способа интеграции приложений — передача файлов, общая БД, RPC и передача сообщений (messaging). Описываются их плюсы и минусы, причем не только технические, но и организационные (особенно касаясь общей БД). Наиболее гибкой, но при этом и более сложной авторы видят интеграцию посредством передачи сообщений.

В следующих главах последовательно рассматриваются:

  • Основы построения систем, используя передачу сообщений. Ничего особенного, но полезно посмотреть и на свою систему, используя предлагаемые функциональные элементы.
  • Каналы передачи сообщений — на какие типы можно поделить, и какие когда и как использовать. Важная мысль про спец. каналы для ошибочных сообщений, причем ошибочных именно с точки зрения транспорта и потому явного отделения уровня транспорта от логики приложения
  • Сами сообщения. Рассуждения, что сообщения бывают трёх типов — команды, данные и события и какие есть особенности у разных типов ( такие как, например, канал, куда помещать ответ у команд и время жизни у событий )
  • Message router. Автор рассматривает сначала относительно простые темы, как content based router и альтернативы ему в виде фильтров сообщений, а затем переходит к более сложным (и интересным) темам — как splitter / aggregator сообщений, resequencer (по русски видимо восстановитель очередности — звучит так себе :). Особенно понравилось, что темы не просто поверхностно обозначены, но также обсуждаются сложности при реализации ( например, какие есть варианты аггрегатору понимать, что сообщения закончились? какого размера должен быть буфер у resequencer и как избежать его переполнения?) и трейдофы различных решений.
  • В этой главе интересная мысль, что проблема нарушения очередности сообщений в системе построенной на их обмене — это та же проблема, которая решается в tcp — который по своей сути протокол обмена сообщениями по нестабильной сети, в котором порядок сообщений важен. И потому полезно представлять, как tcp работает и какие решения применяет, и с какими трейдофами (окно сообщений и способы определения его размера / подтверждение получения сообщений и т.п.)
  • Далее рассматриваются ещё более сложные паттерны, реализующие многоэтапный бизнес-процесс — route slip, process manager и message broker. Самое ценное при этом — опять таки обсуждение применимости.
  • Трансформация сообщений. Больше общие рассуждения о том как лучше организовать связь между собой приложений с разными форматами сообщений. Рассматривает такие паттерны как envelope message, content enricher, content filter, claim check и normalizer. Суть большинства ясна из названия, claim check — удаление из сообщения части информации, но с тем, чтобы вернуть ее в него позже, на последующих этапах обработки бизнес-транзакции.
  • Вопросы взаимодействия приложения с системой передачи сообщений. Отделение кода работающего с ней от основного кода приложения, poll / push модели чтения сообщений, способы организации отработки одной очереди несколькими экземплярами приложения или несколькими приложениями.
  • Особенности эксплуатации системы на базе передачи сообщений. Рассматриваются паттерны, описывающие как организовать конфигурирование системы и переконфигурирование ее в реальном времени, логирование запросов, сбор метрик.

Главы сопровождаются примерами на java используя JMS и на .Net, а также бизнес-ситуациями, при которых могут использоваться одни или другие описанные паттерны. Примеры кода часто выглядят сильно учебными и слегка устаревшими (особенно когда там XML и рассуждения про SOAP и чего нет в .Net 1.1), но все равно полезны ещё и для понимания терминологии и того как одни и те же вещи по разному могут называться в разных имплементациях. Особенно полезны несколько глав с примерами ближе к концу книги, где одну и ту же задачу сначала решают разными путями, а потом наворачивают получившееся решения для использования в продакшене — добавляют мониторинг, фейловер одной из систем и т.п.

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

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