Привет!
Сёня давно забытая рубриа хорошие книги:)
Прочитал тут Clojure Applied (чё думаете я про кложуру-то заговорил?:) ).
В целом хорошая книга, и ради 6ой главы (Creating Components) я бы порекомендовал её даже тем, кто кложурой не интересуется.
Там практически один в один расписаны компоненты ЭП. Даже называются так же:)
И казалось бы - я изобретаю велосипед и надо прекратить это делать. Но есть ряд причин, почему я продолжу изобретать свой велосипед:
1) все эти сходства говорят о том, что ЭП - это не записки сумашедшего идиалиста, а... как минимум записки толпы сумашедших идиалистов:) Ну либо вполне себе рабочая концепция:)
2) Я думаю у меня есть потенциал, придумать как минимум хорошую новую приблуду к этому велосипеду
3) это прикольно:)
Так что оставайтесь на нашей волне:) Вторничный пост пока не обещаю - неделька реально тяжёлая - но небольшой прогресс есть:)
#books@ergonomic_code #clojure@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #design
Сёня давно забытая рубриа хорошие книги:)
Прочитал тут Clojure Applied (чё думаете я про кложуру-то заговорил?:) ).
В целом хорошая книга, и ради 6ой главы (Creating Components) я бы порекомендовал её даже тем, кто кложурой не интересуется.
Там практически один в один расписаны компоненты ЭП. Даже называются так же:)
И казалось бы - я изобретаю велосипед и надо прекратить это делать. Но есть ряд причин, почему я продолжу изобретать свой велосипед:
1) все эти сходства говорят о том, что ЭП - это не записки сумашедшего идиалиста, а... как минимум записки толпы сумашедших идиалистов:) Ну либо вполне себе рабочая концепция:)
2) Я думаю у меня есть потенциал, придумать как минимум хорошую новую приблуду к этому велосипеду
3) это прикольно:)
Так что оставайтесь на нашей волне:) Вторничный пост пока не обещаю - неделька реально тяжёлая - но небольшой прогресс есть:)
#books@ergonomic_code #clojure@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #design
Pragprog
Clojure Applied
Take the next step in Clojure, with extended lessons on the best practices and most critical decisions you’ll need to make.
Привет!
И всё-таки неделька выдалась лёгкая и я накатал небольшой линкопост-заметку о том, как декомпозировать систему на компоненты.
#posts@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #design@ergonomic_code
И всё-таки неделька выдалась лёгкая и я накатал небольшой линкопост-заметку о том, как декомпозировать систему на компоненты.
#posts@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #design@ergonomic_code
Telegraph
О декомпозиции систем
Дисклаймер: это небольшой линко-пост на тему, достойную главы книги Наконец-то свершилась ваша мечта и вам досталось сделать проект с чистого листа. Наконец-то вы можете сделать всё правильно, а не воевать с легаси написанным сто лет назад людьми, которых…
Привет!
Скреативил пост в формате "ночные мысли вслух". Вообще ему место здесь, в канале, но там куча картинок, поэтому опубликовал на сайте.
И как-то так вышло, что я случайно изложил в нём всю суть Эргономичного подхода:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach
Скреативил пост в формате "ночные мысли вслух". Вообще ему место здесь, в канале, но там куча картинок, поэтому опубликовал на сайте.
И как-то так вышло, что я случайно изложил в нём всю суть Эргономичного подхода:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach
Алексей Жидков
Архитектура ориентированная на трансформацию - Алексей Жидков
https://azhidkov.pro/
Привет!
А вот и обещанный пост о структурах программ, к которым я стремлюсь в работе.
Но этот раз всего 20 минут и с картинками:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
А вот и обещанный пост о структурах программ, к которым я стремлюсь в работе.
Но этот раз всего 20 минут и с картинками:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
⚡️Spring рекомендует концептуальную декомпозицию!
И называет это разумным способом структурирования приложения
Вы, возможно, скажете, что заводить по пакету на таблицу - это маразм.
И я с вами соглашусь. Надо заводить по пакету на ДДД-агрегат или даже на группу сильно связанных агрегатов. Пост по агрегатам (не считая трёх постов прелюдии:) ) уже наполовину отредактирован:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #spring@ergonomic_code
И называет это разумным способом структурирования приложения
Вы, возможно, скажете, что заводить по пакету на таблицу - это маразм.
И я с вами соглашусь. Надо заводить по пакету на ДДД-агрегат или даже на группу сильно связанных агрегатов. Пост по агрегатам (не считая трёх постов прелюдии:) ) уже наполовину отредактирован:)
#posts@ergonomic_code #ergo_arch@ergonomic_code #spring@ergonomic_code
Привет!
Пост о подходах к декомпозиции уже на финишной прямой и если не случится форс-мажёров, я его опубликую до конца месяца.
А тем временем я накатал микропост с историей своих метаний о том как выполнять декомпозицию.
#posts@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Пост о подходах к декомпозиции уже на финишной прямой и если не случится форс-мажёров, я его опубликую до конца месяца.
А тем временем я накатал микропост с историей своих метаний о том как выполнять декомпозицию.
#posts@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
👍3
image_2022-11-30_12-44-40.png
202.6 KB
Привет!
Я в целом собрал свою версию структуры модуля. Она всё так же похожа на структуру из Let's build components, not layers и базируется на интерфейсе и реализации. Но я решил отдельно вынести порты - штуки, которые публикуют АПИ модуля наружу и "конфиг" - спринговый конфиг, который позволяет создать экземпляр модуля в рантайме.
У меня получился такой список типовых (под)пакетов модуля:
- api
- dtos - классы DTO АПИ модуля
- events - классы событий модуля
- model - классы сущностей и объектов-значений из DDD, в случае если они "выставлены" в АПИ
- *Exception - файл с иерархией исключений модуля
- *Service - файл с интерфейсом модуля
- internal
- db - классы репозитория и сущностей модуля и, при наличии, DAO и строки
- submodule1 - подпакет с кодом реализации подмодуля
- Submodule2.kt - котлин-файл кодом реализации подмодуля
- *ServiceImpl - файл с классом реализации интерфейса модуля
- *Props - класс конфигурационных параметров модуля
- ports
- *Controller - Spring MVC контроллер и обработчик ошибок
- *Listener - Spring RabbitMQ слушателя
- *Config - Spring-конфигурация модуля
Я перепаковал так Проект Э, TSP Project и ещё один нетиповой проект - пока полёт нормальный. Дальше хочу ещё перепаковать Кэмп, Проект Л и ещё один коммерческий проект (у каждого из них есть уникальные особенности) и после этого пойти писать вторую версию поста "Структура эргономичной кодовой базы" (осторожно, материал этого поста частично устарел).
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #project_e@ergonomic_code #project_camp@ergonomic_code #project_geoservices@ergonomic_code
Я в целом собрал свою версию структуры модуля. Она всё так же похожа на структуру из Let's build components, not layers и базируется на интерфейсе и реализации. Но я решил отдельно вынести порты - штуки, которые публикуют АПИ модуля наружу и "конфиг" - спринговый конфиг, который позволяет создать экземпляр модуля в рантайме.
У меня получился такой список типовых (под)пакетов модуля:
- api
- dtos - классы DTO АПИ модуля
- events - классы событий модуля
- model - классы сущностей и объектов-значений из DDD, в случае если они "выставлены" в АПИ
- *Exception - файл с иерархией исключений модуля
- *Service - файл с интерфейсом модуля
- internal
- db - классы репозитория и сущностей модуля и, при наличии, DAO и строки
- submodule1 - подпакет с кодом реализации подмодуля
- Submodule2.kt - котлин-файл кодом реализации подмодуля
- *ServiceImpl - файл с классом реализации интерфейса модуля
- *Props - класс конфигурационных параметров модуля
- ports
- *Controller - Spring MVC контроллер и обработчик ошибок
- *Listener - Spring RabbitMQ слушателя
- *Config - Spring-конфигурация модуля
Я перепаковал так Проект Э, TSP Project и ещё один нетиповой проект - пока полёт нормальный. Дальше хочу ещё перепаковать Кэмп, Проект Л и ещё один коммерческий проект (у каждого из них есть уникальные особенности) и после этого пойти писать вторую версию поста "Структура эргономичной кодовой базы" (осторожно, материал этого поста частично устарел).
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #project_e@ergonomic_code #project_camp@ergonomic_code #project_geoservices@ergonomic_code
👍3🌚1
Привет!
У меня появилась странная идея. Написать пост "Зачем декомпозировать систему?". Кажется, идея провалится, потому что ответ пока что сводится к "затем", но эта деятельность натолкнула меня на хорошую мысль.
Нам в любом случае надо декомпозировать систему и по техническим аспектам (слоям) и по функциональности (области предметной области). Но мы пока что умеет декомпозировать только в иерархии (а не матрицы), соответственно вопрос в том, что должно быть на перовом уровне, а что на втором - технические аспекты или предметная область?
И интуитивно кажется, что первый уровень имеет большее значение, чем второй. Так же интуитивно кажется, что предметная область имеет большее значение, чем техническая реализация. Поэтому, кажется, начинать надо с декомпозиции предметной области.
Но это я прямо сейчас креатив сипровизировал, и на самом деле я не об этом.
Зато есть несколько вещей, в которых я уверен:
0. кодовая база должна иметь регулярную структуру, для того чтобы в ней было проще ориентироваться
1. декомпозиция второго уровня неизбежно будет дублироваться - внутри каждого модуля первого уровня надо будет поддерживать декомпозицию второго уровня, такую же, как и в соседних. Из-за этого декомпозицию второго уровня поддерживать сложнее, чем первого
2. техническая декомпозиция уже устоялась и практически не меняется. В разных командах могут быть небольшие отличия, но множества ключевых слоёв и типов классов имеют конечный размер. Благодаря этому техническую декомпозицию поддерживать просто.
3. декомпозиция предметной области (для всех проектов) не может быть устоявшейся, т.к. количество предметных областей условно бесконечно. Из-за этого:
3.1. каждой команде надо заново придумывать свою декомпозицию предметной области
3.2. декомпозиция может эволюционировать вместе с пониманием командой предметной области или даже самой предметной областью
3.3. поддерживать декомпозицию предметной области сложно - её нельзя заучить один раз на всю карьеру, она меняется даже в течении жизни одного проекта и в целом она может быть намного сложнее, чем 3 слоя и десяток типов классов
И так мы приходим к выводу: разумно на первый уровень выносить декомпозицию предметной области для того, чтобы частично компенсировать сложность её поддержки, за счёт относительной просты поддержки декомпозиции первого уровня.
Ну а декомпозировать систему в принципе надо потому что потому. Я серьёзно. В литературе так и пишут
Например, в статье о структурном дизайне пишут, что мистер Константин "наблёл", что проще реализовывать и изменять те программы, что состоят из простых независимых модулей.
> Mr. Constantine has observed that programs that were the easiest to implement and change were those composed of simple, independent modules
Никакими фактическими данными по объективным метрикам наблюдения мистера Константина не подкрепляются.
Наконец, пришёл я ко всей этой цепочке в процессе [мысленной] дискуссии с Фаулером по мотивам его статьи о сцепленности, где он на первый (и единственный) уровень вытащил техническую декомпозицию и на которую я натолкнулся как раз в процессе поиска ответа на вопрос "зачем декомпозировать системы"
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #papers@ergonomic_code
У меня появилась странная идея. Написать пост "Зачем декомпозировать систему?". Кажется, идея провалится, потому что ответ пока что сводится к "затем", но эта деятельность натолкнула меня на хорошую мысль.
Нам в любом случае надо декомпозировать систему и по техническим аспектам (слоям) и по функциональности (области предметной области). Но мы пока что умеет декомпозировать только в иерархии (а не матрицы), соответственно вопрос в том, что должно быть на перовом уровне, а что на втором - технические аспекты или предметная область?
И интуитивно кажется, что первый уровень имеет большее значение, чем второй. Так же интуитивно кажется, что предметная область имеет большее значение, чем техническая реализация. Поэтому, кажется, начинать надо с декомпозиции предметной области.
Но это я прямо сейчас креатив сипровизировал, и на самом деле я не об этом.
Зато есть несколько вещей, в которых я уверен:
0. кодовая база должна иметь регулярную структуру, для того чтобы в ней было проще ориентироваться
1. декомпозиция второго уровня неизбежно будет дублироваться - внутри каждого модуля первого уровня надо будет поддерживать декомпозицию второго уровня, такую же, как и в соседних. Из-за этого декомпозицию второго уровня поддерживать сложнее, чем первого
2. техническая декомпозиция уже устоялась и практически не меняется. В разных командах могут быть небольшие отличия, но множества ключевых слоёв и типов классов имеют конечный размер. Благодаря этому техническую декомпозицию поддерживать просто.
3. декомпозиция предметной области (для всех проектов) не может быть устоявшейся, т.к. количество предметных областей условно бесконечно. Из-за этого:
3.1. каждой команде надо заново придумывать свою декомпозицию предметной области
3.2. декомпозиция может эволюционировать вместе с пониманием командой предметной области или даже самой предметной областью
3.3. поддерживать декомпозицию предметной области сложно - её нельзя заучить один раз на всю карьеру, она меняется даже в течении жизни одного проекта и в целом она может быть намного сложнее, чем 3 слоя и десяток типов классов
И так мы приходим к выводу: разумно на первый уровень выносить декомпозицию предметной области для того, чтобы частично компенсировать сложность её поддержки, за счёт относительной просты поддержки декомпозиции первого уровня.
Ну а декомпозировать систему в принципе надо потому что потому. Я серьёзно. В литературе так и пишут
Например, в статье о структурном дизайне пишут, что мистер Константин "наблёл", что проще реализовывать и изменять те программы, что состоят из простых независимых модулей.
> Mr. Constantine has observed that programs that were the easiest to implement and change were those composed of simple, independent modules
Никакими фактическими данными по объективным метрикам наблюдения мистера Константина не подкрепляются.
Наконец, пришёл я ко всей этой цепочке в процессе [мысленной] дискуссии с Фаулером по мотивам его статьи о сцепленности, где он на первый (и единственный) уровень вытащил техническую декомпозицию и на которую я натолкнулся как раз в процессе поиска ответа на вопрос "зачем декомпозировать системы"
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #papers@ergonomic_code
👍6
Привет!
Моя дилемма последней недели.
Я забацал небольшой демо-проект архитектуры, которую я использую в своих проектах и на этой базе написал пост с её описанием. Но не могу его опубликовать, потому что не могу придумать название и написать введение.
Я 4 года воздерживался от того, чтобы вводить 100500-ую архитектуру и говорил, что у меня функциональная архитектура. Но сейчас у меня не получается связать функциональную архитектуру с тем, что у меня в коде и посте реально происходит.
Во многом, потому что ФА ни где не описана. Для неё даже на вики странички нет.
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Моя дилемма последней недели.
Я забацал небольшой демо-проект архитектуры, которую я использую в своих проектах и на этой базе написал пост с её описанием. Но не могу его опубликовать, потому что не могу придумать название и написать введение.
Я 4 года воздерживался от того, чтобы вводить 100500-ую архитектуру и говорил, что у меня функциональная архитектура. Но сейчас у меня не получается связать функциональную архитектуру с тем, что у меня в коде и посте реально происходит.
Во многом, потому что ФА ни где не описана. Для неё даже на вики странички нет.
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
❤1
Привет!
Вы когда-нибудь задавались вопросом, почему некоторые разработчики (например анкл Боб в чистой архитектуре) методы или классы, реализующие один эндпонит, называют юзкейсами? Ведь юзкейс - это многошаговый сценарий, в котором каждый шаг - вызов отдельного эндпоинта.
Я - задавался.
А сейчас начал читать матчасть по юзкейсам и узнал почему.
Оказывается, юзкейсы рекурсивны.
На самом верхнем уровне - бизнес юзкейсы (Кокбёрн называет их ещё белыми), они состоят из пользовательских юзкейсов (синие) - это то, что я понимал под юзкейсами -, которые, в свою очередь, состоят из юзкейсов-подфункций (индиго/чёрные) - вот это и есть те самые юзкейсы из чистой архитектуры.
А ещё, кажется, я тут нашёл стратегию декомпозиции слоя приложения - собственно по юзкейсам. Правда она предполагает, что эти самые юз кейсы есть и структурированы, но сейчас у меня такое ощущение, что их наличие - действительно важно для успеха проекта и если это не делает аналитик/бизнес - это должен делать техлид в рамках проектирования.
Ну и книгу я ещё прочитал только процентов на 50, но уже готов её порекомендовать.
#books@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Вы когда-нибудь задавались вопросом, почему некоторые разработчики (например анкл Боб в чистой архитектуре) методы или классы, реализующие один эндпонит, называют юзкейсами? Ведь юзкейс - это многошаговый сценарий, в котором каждый шаг - вызов отдельного эндпоинта.
Я - задавался.
А сейчас начал читать матчасть по юзкейсам и узнал почему.
Оказывается, юзкейсы рекурсивны.
На самом верхнем уровне - бизнес юзкейсы (Кокбёрн называет их ещё белыми), они состоят из пользовательских юзкейсов (синие) - это то, что я понимал под юзкейсами -, которые, в свою очередь, состоят из юзкейсов-подфункций (индиго/чёрные) - вот это и есть те самые юзкейсы из чистой архитектуры.
А ещё, кажется, я тут нашёл стратегию декомпозиции слоя приложения - собственно по юзкейсам. Правда она предполагает, что эти самые юз кейсы есть и структурированы, но сейчас у меня такое ощущение, что их наличие - действительно важно для успеха проекта и если это не делает аналитик/бизнес - это должен делать техлид в рамках проектирования.
Ну и книгу я ещё прочитал только процентов на 50, но уже готов её порекомендовать.
#books@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
👍6🔥1
Эргономичный код
Привет! Кажется у меня по мотивам Проекта Э на горизонте замаячил очередной кризис Эргономичного подхода. При том зашатались одновременно два столпа - декомпозиция на базе эффектов и функциональная архитектура. С декомпозицией на базе эффектов в одном из…
Привет!
Вы, наверное, забыли, что полтора года назад в Эргономичном подходе было две проблемы (см. цитируемое сообщение), а я - нет:)
В общем я тут внезапно осознал, что гамак-дривен девелопмент сработал и я тихой сапой решил обе проблемы:)
Проблема №1
Тут сейчас ответ такой: пофиг:) Лишь бы команде было удобно ориентироваться. Можете делать так же, как сейчас раскладываете контроллеры. Может плясать от страниц/экранов/компонентов UI, можете от ролей пользователей, можете от юз кейсов, можете от ресурсов REST API.
В Trainer-Advisor, например, сейчас код приложения сначала разбит по ролям пользователей, потом по страницам/компонентам
Проблема №2
Во-первых, я сформулировал к каким систематическим проблемам это ведёт. К заметанию сложности под ковёр. И в итоге появлению таких скрытых монстров, как на картинке №1 - чтобы осознать весь масштаб трагедии этой операции, мне пришлось 4 часа методично код читать.
Во-вторых, я нашёл решение этой проблемы.
Оно состоит из двух частей:
1. Я отказался от сервисов приложений в пользу классов-операций - класс, который имеет один публичный метод, реализующий одну операцию (эндпоинт) системы и имеющий поля для всех ресурсов (гейтвеев, репозов, клиентов внешних систем), требующихся для реализации этой операции. См, например операцию регистрации терапевта в Trainer-Advisor
2. Я завёл штуки, которые сейчас называю "доменные операции" - это процедуры (Kotlin top-level function), которые нужные им ресурсы получают в качестве параметров. В том же коде регистрации терапевта надо CreateTherapistUserWorkflow заменить на процедуру
с кодом его реализации, которая зависимости получает явно в качестве параметров. Реального публичного кода с иллюстрацией у меня пока нет, но есть картинка №2:)
В результате, для того чтобы оценить масштаб трагедии достаточно посмотреть на кол-во зависимостей класса-операции. А для того чтобы ограничить масштаб трагедии - достаточно ввести ограничение на кол-во зависимостей.
При том вы можете избегать дублирования "подопераций" и в целом ограничивать длину методов операций и вводить промежуточные уровни абстракции.
Параметры с ресурсами, конечно, придётся таскать - но это будет напоминалкой, чтобы искать возможность повысить уровень абстракции ресурсов и/или уменьшить количество вещей, которые делает операция. В примере из TA, например, пришло время завести UsersService, который скрывает за собой usersRepo и usersFactory
вин-вин-вин, я считаю:)
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Вы, наверное, забыли, что полтора года назад в Эргономичном подходе было две проблемы (см. цитируемое сообщение), а я - нет:)
В общем я тут внезапно осознал, что гамак-дривен девелопмент сработал и я тихой сапой решил обе проблемы:)
Проблема №1
А вот как декомозировать слой приложения - я пока не знаю.
Тут сейчас ответ такой: пофиг:) Лишь бы команде было удобно ориентироваться. Можете делать так же, как сейчас раскладываете контроллеры. Может плясать от страниц/экранов/компонентов UI, можете от ролей пользователей, можете от юз кейсов, можете от ресурсов REST API.
В Trainer-Advisor, например, сейчас код приложения сначала разбит по ролям пользователей, потом по страницам/компонентам
Проблема №2
Однако на практике у меня некоторые операции ещё и другие операции дёргают. И мне это кажется нарушением принципа одного уровня абстракции.
Но я пока не могу сформулировать к каким систематическим проблемам это ведёт.
Во-первых, я сформулировал к каким систематическим проблемам это ведёт. К заметанию сложности под ковёр. И в итоге появлению таких скрытых монстров, как на картинке №1 - чтобы осознать весь масштаб трагедии этой операции, мне пришлось 4 часа методично код читать.
Во-вторых, я нашёл решение этой проблемы.
Оно состоит из двух частей:
1. Я отказался от сервисов приложений в пользу классов-операций - класс, который имеет один публичный метод, реализующий одну операцию (эндпоинт) системы и имеющий поля для всех ресурсов (гейтвеев, репозов, клиентов внешних систем), требующихся для реализации этой операции. См, например операцию регистрации терапевта в Trainer-Advisor
2. Я завёл штуки, которые сейчас называю "доменные операции" - это процедуры (Kotlin top-level function), которые нужные им ресурсы получают в качестве параметров. В том же коде регистрации терапевта надо CreateTherapistUserWorkflow заменить на процедуру
fun createTherapistUser(
usersRepo: UsersRepo,
therapistsRepo: TherapistsRepo,
usersFactory: UsersFactory,
registerTherapistRequest: RegisterTherapistReques,
password: CharSequence) {
...
}
с кодом его реализации, которая зависимости получает явно в качестве параметров. Реального публичного кода с иллюстрацией у меня пока нет, но есть картинка №2:)
В результате, для того чтобы оценить масштаб трагедии достаточно посмотреть на кол-во зависимостей класса-операции. А для того чтобы ограничить масштаб трагедии - достаточно ввести ограничение на кол-во зависимостей.
При том вы можете избегать дублирования "подопераций" и в целом ограничивать длину методов операций и вводить промежуточные уровни абстракции.
Параметры с ресурсами, конечно, придётся таскать - но это будет напоминалкой, чтобы искать возможность повысить уровень абстракции ресурсов и/или уменьшить количество вещей, которые делает операция. В примере из TA, например, пришло время завести UsersService, который скрывает за собой usersRepo и usersFactory
вин-вин-вин, я считаю:)
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
👍9🔥4❤3
Привет!
Мысли в слух.
Наткнулся на очередную свеженькую статью по чистой архитектуре.
В двух словах: чистая архитектура - это не про пакеты - не заводите пакеты domain, application, infrastructure, web, заводите пакеты по фичам.
В целом ничего супероригинального, но любопытный аргумент в пользу пакетирования по фичам там есть — по мере жизни приложения, у него появляются новые фичи, а новые слои — практически никогда.
И так как покой мне только снится, это меня натолкнуло на мысль о потенциальной эргономичной структуре программ в4. в3 выглядит так, напомню.
Сейчас она у меня в целом работает и серьёзных нареканий нет, но мне не нравится фактическое дублирование содержания пакетов app и core, в случае если app декомпозируется по фичам.
И вот глядя на этот пост, я подумал, что гипотетически, в в4 я мог бы вернуться к декомпозиции по домену/фичам на первом уровне, но для решения проблемы лишних зависимостей добавил бы компоненты без состояния.
#posts@ergonomic_code #clean_architecture@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Мысли в слух.
Наткнулся на очередную свеженькую статью по чистой архитектуре.
В двух словах: чистая архитектура - это не про пакеты - не заводите пакеты domain, application, infrastructure, web, заводите пакеты по фичам.
В целом ничего супероригинального, но любопытный аргумент в пользу пакетирования по фичам там есть — по мере жизни приложения, у него появляются новые фичи, а новые слои — практически никогда.
И так как покой мне только снится, это меня натолкнуло на мысль о потенциальной эргономичной структуре программ в4. в3 выглядит так, напомню.
Сейчас она у меня в целом работает и серьёзных нареканий нет, но мне не нравится фактическое дублирование содержания пакетов app и core, в случае если app декомпозируется по фичам.
И вот глядя на этот пост, я подумал, что гипотетически, в в4 я мог бы вернуться к декомпозиции по домену/фичам на первом уровне, но для решения проблемы лишних зависимостей добавил бы компоненты без состояния.
#posts@ergonomic_code #clean_architecture@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code
Medium
Clean Architecture is NOT a project structure.
Clean Architecture is NOT a project structure. Countless articles are written about Clean Architecture, and some of the basic stuff people get right. But there’s one common issue I see over and …
Привет!
Периодически гипотезы, лежащие в основе ЭП, рушатся о жестокую реальность промышленной разработки, что приводит к кризисам ЭП, которых уже было три штуки: раз по мотивам проекта Barcoder (решение), два (решение) и три (решение - нафик ООД, ДДД и private внутри одного репоза😀) - по мотивам #project_e.
И вот по мотивам #project_r за последние 5 дней у меня случился и благополучно разрешился очередной кризис ЭП:)
В связи с чем у меня пачка новостей.
Книга
Это уже новость второй свежести, но для контекста надо проговорить - я договорился с менеджером проектов издательства Питер начать с апреля плотную работу над книгой про ЭП. Так что надеюсь, на горизонте пары лет книга увидит свет.
Отказ от ФА
Номинально самая большая новость - я решил отказаться от ФА (которая когда-то была одним из трёх столпов ЭП).
Но по сути ничего не меняется - ЭП всё так же предполагает использование неизменяемых структур данных и максимально возможное разделение логики и ио.
Это просто признание реальности, что в ЭП, который начинался как сильно функциональный, я методично отказываюсь от отличительных черт ФА/ФП:
1. уже очень давно я отказался от монад и ROP-а в пользу защитных условий
2. затем я затащил операции в императивную оболочку
3. во многом по мотивам Проекта Р я вернул в милость выброс исключений вместо возвращения Result
4. по мотивам Проекта Р, я утащил сбалансированную форму системы с архитектурного уровня системы, на локальный уровень отдельных методов
Отказ от SDJ как дефолтной технологии работы с БД
А вот по сути самое больше изменение - я решил отказаться от SDJ в качестве дефолта для работы с БД.
Это всё ёще допустимый в рамках ЭП т.к. его всё ещё легче "продать" заказчикам и коллегам, но по умолчанию я теперь предлагаю использовать какой-то легковесный DSL - jooq или Exposed, ещё не решил что именно.
Это опять же обусловлено опытом Проекта Р - там у меня львиная доля запросов чтения рукописные, потому что SDJ не в состоянии эффективно доставать данные этого проекта, а после того, как мне пришлось ещё и два кастомных метода сохранения написать - стало понятно, что я борюсь с технологией. Этому решению так же поспособствовали пост из канала одного из участников нашей группы.
И решение перейти на UUID-ы, которое так же было обусловлено опытом разработки Проекта Р, где надо сетапать огромные графы объектов в тестах и с генераций ИДов на уровне БД это очень сложно.
Новая версия описания Эргономичной архитектуры
На мой взгляд самая крутая новость - я выложил новый подход к описанию ЭА.
По сути там ничего не изменилось, изменилась только подача.
Но эта новая подача мне настолько нравится, что я решил показать самый первый черновик.
Основная фишка - я отказался от попытки быть как все и уместить архитектуру на одну картинку и ввёл идею проекций. Их три:
1. проекция структуры данных (модель данных) - тут про агрегаты и связи между ними
2. проекция состояния (объектная модель) - тут про объекты в рантайме (порты, операции, ресурсы) и связи между ними
3. проекция структуры поведения (процедурная модель) - тут про методы и связи между ними
Плюс я туда сразу накидал кучу примеров (пока на словах😕), а так же процессы построения всех этих структур и итоговой архитектуры.
Над единой картинкой я тоже ещё подумаю: кажется, судя по проектам физических изделий, где есть проекции по плоскостям плюс изометрия или проекты зданий, где есть тоже должны быть разные проекции и разные слои (с электропроводкой, например) - для ЭА тоже можно что-то такое сделать.
И возвращаясь к книге - эта статья по сути - четверть книги. Заполнить там пробелы, добавить примеры и теоретическая часть по ЭА готова. Вспоминая про бейзкамповский Hill Chart, у меня сейчас такое ощущение, что я достиг холма реализации ЭА и дальше только дело техники. Лишь бы очередной проект не зафейлил очередную гипотезу😄
#the_book@ergonomic_code #functional_architecture@ergonomic_code #ergo_arch@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
Периодически гипотезы, лежащие в основе ЭП, рушатся о жестокую реальность промышленной разработки, что приводит к кризисам ЭП, которых уже было три штуки: раз по мотивам проекта Barcoder (решение), два (решение) и три (решение - нафик ООД, ДДД и private внутри одного репоза😀) - по мотивам #project_e.
И вот по мотивам #project_r за последние 5 дней у меня случился и благополучно разрешился очередной кризис ЭП:)
В связи с чем у меня пачка новостей.
Книга
Это уже новость второй свежести, но для контекста надо проговорить - я договорился с менеджером проектов издательства Питер начать с апреля плотную работу над книгой про ЭП. Так что надеюсь, на горизонте пары лет книга увидит свет.
Отказ от ФА
Номинально самая большая новость - я решил отказаться от ФА (которая когда-то была одним из трёх столпов ЭП).
Но по сути ничего не меняется - ЭП всё так же предполагает использование неизменяемых структур данных и максимально возможное разделение логики и ио.
Это просто признание реальности, что в ЭП, который начинался как сильно функциональный, я методично отказываюсь от отличительных черт ФА/ФП:
1. уже очень давно я отказался от монад и ROP-а в пользу защитных условий
2. затем я затащил операции в императивную оболочку
3. во многом по мотивам Проекта Р я вернул в милость выброс исключений вместо возвращения Result
4. по мотивам Проекта Р, я утащил сбалансированную форму системы с архитектурного уровня системы, на локальный уровень отдельных методов
Отказ от SDJ как дефолтной технологии работы с БД
А вот по сути самое больше изменение - я решил отказаться от SDJ в качестве дефолта для работы с БД.
Это всё ёще допустимый в рамках ЭП т.к. его всё ещё легче "продать" заказчикам и коллегам, но по умолчанию я теперь предлагаю использовать какой-то легковесный DSL - jooq или Exposed, ещё не решил что именно.
Это опять же обусловлено опытом Проекта Р - там у меня львиная доля запросов чтения рукописные, потому что SDJ не в состоянии эффективно доставать данные этого проекта, а после того, как мне пришлось ещё и два кастомных метода сохранения написать - стало понятно, что я борюсь с технологией. Этому решению так же поспособствовали пост из канала одного из участников нашей группы.
И решение перейти на UUID-ы, которое так же было обусловлено опытом разработки Проекта Р, где надо сетапать огромные графы объектов в тестах и с генераций ИДов на уровне БД это очень сложно.
Новая версия описания Эргономичной архитектуры
На мой взгляд самая крутая новость - я выложил новый подход к описанию ЭА.
По сути там ничего не изменилось, изменилась только подача.
Но эта новая подача мне настолько нравится, что я решил показать самый первый черновик.
Основная фишка - я отказался от попытки быть как все и уместить архитектуру на одну картинку и ввёл идею проекций. Их три:
1. проекция структуры данных (модель данных) - тут про агрегаты и связи между ними
2. проекция состояния (объектная модель) - тут про объекты в рантайме (порты, операции, ресурсы) и связи между ними
3. проекция структуры поведения (процедурная модель) - тут про методы и связи между ними
Плюс я туда сразу накидал кучу примеров (пока на словах😕), а так же процессы построения всех этих структур и итоговой архитектуры.
Над единой картинкой я тоже ещё подумаю: кажется, судя по проектам физических изделий, где есть проекции по плоскостям плюс изометрия или проекты зданий, где есть тоже должны быть разные проекции и разные слои (с электропроводкой, например) - для ЭА тоже можно что-то такое сделать.
И возвращаясь к книге - эта статья по сути - четверть книги. Заполнить там пробелы, добавить примеры и теоретическая часть по ЭА готова. Вспоминая про бейзкамповский Hill Chart, у меня сейчас такое ощущение, что я достиг холма реализации ЭА и дальше только дело техники. Лишь бы очередной проект не зафейлил очередную гипотезу
#the_book@ergonomic_code #functional_architecture@ergonomic_code #ergo_arch@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥6👍4❤2
Эргономичный код
Привет! С подачи Романа Русакова запоем прочитал The API. Очень крутая книга, рекомендую. Роман - спасибо:) Так же вы, возможно, задаётесь вопросом что это я затих. Вряд ли, конечно, но я всё равно отвечу - лопачу джиру Проект Э:) Чтобы понять стоило ли…
Привет!
Я тут недавно прочитал Overengineering in Onion/Hexagonal Architectures (перевод).
В целом с посылом поста я согласен (кроме мёржа REST-аннотаций в сервисы, хотя сам об этом думал), но там ничего суперкрутого - этот мой пост не про тот пост:)
А про собственную...Глу... человечность, назовём это так:)
В посте по ссылке есть тезис:
Но я в 22-ом году (на 18-ом году коммерческой практики и примерно 5-ом году знания про Чистую архитектуру, ДДД, оркестрацию и сервисы приложений) всё равно изобрёл объектно-ориентированную декомпозицию. И пошёл делать по ней #project_e. И получил ровно, то, чего позволяют избегать сервисы приложений - высокую связанность между модулями-объектами.
Сколько ещё у меня таких "изобретений" из-за того что "смотрю в книгу, вижу фигу"? Вопрос риторический, конечно. Время покажет, всё что покажет - расскажу как на духу. Сегодня начал писать пост с ретро #project_r
PS>
И в топик "простых" CRUD приложений из комментов ко вчерашнему посту: в Overengineering in Onion/Hexagonal Architectures про них тоже тоже есть:
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
Я тут недавно прочитал Overengineering in Onion/Hexagonal Architectures (перевод).
В целом с посылом поста я согласен (кроме мёржа REST-аннотаций в сервисы, хотя сам об этом думал), но там ничего суперкрутого - этот мой пост не про тот пост:)
А про собственную...
В посте по ссылке есть тезис:
To put it another way, it is a design goal of the Application Service to host orchestration logic to allow lower-level components to become less coupled to one another.
—
Другими словами, Application Services предназначены для размещения логики оркестрации, что позволяет компонентам более низкого уровня быть менее связанными друг с другом.
Но я в 22-ом году (на 18-ом году коммерческой практики и примерно 5-ом году знания про Чистую архитектуру, ДДД, оркестрацию и сервисы приложений) всё равно изобрёл объектно-ориентированную декомпозицию. И пошёл делать по ней #project_e. И получил ровно, то, чего позволяют избегать сервисы приложений - высокую связанность между модулями-объектами.
Сколько ещё у меня таких "изобретений" из-за того что "смотрю в книгу, вижу фигу"? Вопрос риторический, конечно. Время покажет, всё что покажет - расскажу как на духу. Сегодня начал писать пост с ретро #project_r
PS>
И в топик "простых" CRUD приложений из комментов ко вчерашнему посту: в Overengineering in Onion/Hexagonal Architectures про них тоже тоже есть:
Like any tool, concentric architectures are not suitable for any software project. If the domain complexity of your problem is fairly low (CRUD-like), or if the challenge of your application is NOT in the complexity of its business rules, then the Onion/Hexagonal/Ports-Adapters/Clean Architecture might not be the best choice, and you might be better off with vertical slicing, anemic model, CQRS, or another type of architecture.
—
Как и любой другой инструмент, концентрическая архитектура подходит не для всех проектов. Если сложность предметной области вашей задачи довольно низкая (CRUDо-подобная) или если сложность вашего приложения заключается не в сложности его бизнес-правил, то архитектура Onion/Hexagonal/Ports-Adapters/Clean может оказаться не лучшим выбором, и вам, возможно, лучше использовать вертикальную архитектуру, анемичную модель, CQRS или другой тип архитектуры.
#posts@ergonomic_code #ergo_arch@ergonomic_code #ergo_approach@ergonomic_code
Victor Rentea
Overengineering in Onion/Hexagonal Architectures
Clean Architecture, Onion Architecture, and Hexagonal Architecture (aka Ports-and-Adapters) have become the norm for backend system design today. Powerful influencers have promoted these architectures without stressing enough that they are (overly)complex…
❤6
Привет!
Довольно существенно дополнил, отполировал и актуализировал разделы "Проекция структуры компонентов" и "Раскладка кода по пакетам" из статьи об Эргономичной архитектуре.
И даже наконец добавил пару первых картинок:)
#ergo_arch@ergonomic_code
Довольно существенно дополнил, отполировал и актуализировал разделы "Проекция структуры компонентов" и "Раскладка кода по пакетам" из статьи об Эргономичной архитектуре.
И даже наконец добавил пару первых картинок:)
#ergo_arch@ergonomic_code
Эргономичный подход
Эргономичная архитектура (v3.0.0)
Текущая версия статьи написана в режиме потока сознания и пока что я не проводил даже проверки правописания, не говоря уж о том, чтобы сопроводить идеи иллюстрациями и кодом.
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
1🔥8
Привет!
Я закончил большой 5-месячный долгострой на 43 коммита по интеграции Google Calendar в Trainer Advisor.
В реализации этой фичи довольно много интересных, на мой взгляд, аспектов, каждый из которых заслуживает отдельного поста. Но сейчас их писать настроения нет, поэтому я ограничился микропостом с обзором реализации. Ну как микро - 25 минут чтения по оценке ФФ:)
И чтобы вам не продираться сквозь 25 минут потока сознания в поисках чего-то интересного для себя - вот краткое содержание:)
Абстрактный ресурс
Для меня самым интересным в этой фиче было то, что для её реализации пришлось ввести некие штуки с рабочим названием «Абстрактный ресурс».
Не знаю пока что с этим делать и надо ли что-то делать.
MockServers
Паттерн для организации WireMock-стабов
Fixtures
Паттерн для сетапа фикстур, состоящих из сложных графов объектов
Пример «простого» CRUD-приложения
Я в последнее время в канале несколько раз писал о «простых» CRUD-приложения — приложениях без сложной бизнес-логики или нефункциональных требований, но, тем не менее, которые назвать простыми не поворачивается язык. И всякий раз это порождало вопросы в комментариях, что конкретно я имею ввиду.
И вот у меня, наконец появился, хороший open source-ый пример — операция отображения страницы расписания терапевта.
Рефакторинг findCalendarItemsInInterval (уровни абстракции/стратификация)
Пример приведения метода к соответствию правилу "У функции должен быть один уровень абстракции"
SourceItem → URI
К своему стыду, должен признаться, что я только недавно до конца (чуть лучше?) осознал что такое URI. Но лучше поздно, чем никогда - правда же?
И вот теперь благодаря этим новым знаниям, мне удалось сделать работу с разными календарями в Trainer Advisor чуть более "production grade".
Как добыть OAuth2AuthorizedClient без того, чтобы перетереть Authorization в SecurityContext
Я хз. Но у меня есть рабочий код, на который можно ориентироваться
И этот код мало того, что рабочий — он ещё и тестами покрыт.
Тестирование интеграции с Google OAuth и Google Calendars
Вот оно:
- GoogleAuthorizationIntegrationTest;
- GoogleCalendarsServiceTest;
- GetGoogleCalendarsSettingsEndpointTest;
- SetCalendarShouldBeShownTest;
- Тест "Страница календаря должна рендериться корректно, даже если у терапевта есть подключенный Google-календарь и запрос событий из него приводит к ошибке";
- CreateAppointmentPageTest.createAppointmntWithGoogleEvnt;
- SchedulePageControllerTest;
Верификация приложения в Google
Это 7 кругов ада. Но без них ваши токены будут протухать раз в неделю и вам надо будет снова гнать юзеров на авторизацию в гугле
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #case@ergonomic_code
Я закончил большой 5-месячный долгострой на 43 коммита по интеграции Google Calendar в Trainer Advisor.
В реализации этой фичи довольно много интересных, на мой взгляд, аспектов, каждый из которых заслуживает отдельного поста. Но сейчас их писать настроения нет, поэтому я ограничился микропостом с обзором реализации. Ну как микро - 25 минут чтения по оценке ФФ:)
И чтобы вам не продираться сквозь 25 минут потока сознания в поисках чего-то интересного для себя - вот краткое содержание:)
Абстрактный ресурс
Для меня самым интересным в этой фиче было то, что для её реализации пришлось ввести некие штуки с рабочим названием «Абстрактный ресурс».
Не знаю пока что с этим делать и надо ли что-то делать.
MockServers
Паттерн для организации WireMock-стабов
Fixtures
Паттерн для сетапа фикстур, состоящих из сложных графов объектов
Пример «простого» CRUD-приложения
Я в последнее время в канале несколько раз писал о «простых» CRUD-приложения — приложениях без сложной бизнес-логики или нефункциональных требований, но, тем не менее, которые назвать простыми не поворачивается язык. И всякий раз это порождало вопросы в комментариях, что конкретно я имею ввиду.
И вот у меня, наконец появился, хороший open source-ый пример — операция отображения страницы расписания терапевта.
Рефакторинг findCalendarItemsInInterval (уровни абстракции/стратификация)
Пример приведения метода к соответствию правилу "У функции должен быть один уровень абстракции"
SourceItem → URI
К своему стыду, должен признаться, что я только недавно до конца (чуть лучше?) осознал что такое URI. Но лучше поздно, чем никогда - правда же?
И вот теперь благодаря этим новым знаниям, мне удалось сделать работу с разными календарями в Trainer Advisor чуть более "production grade".
Как добыть OAuth2AuthorizedClient без того, чтобы перетереть Authorization в SecurityContext
Я хз. Но у меня есть рабочий код, на который можно ориентироваться
И этот код мало того, что рабочий — он ещё и тестами покрыт.
Тестирование интеграции с Google OAuth и Google Calendars
Вот оно:
- GoogleAuthorizationIntegrationTest;
- GoogleCalendarsServiceTest;
- GetGoogleCalendarsSettingsEndpointTest;
- SetCalendarShouldBeShownTest;
- Тест "Страница календаря должна рендериться корректно, даже если у терапевта есть подключенный Google-календарь и запрос событий из него приводит к ошибке";
- CreateAppointmentPageTest.createAppointmntWithGoogleEvnt;
- SchedulePageControllerTest;
Верификация приложения в Google
Это 7 кругов ада. Но без них ваши токены будут протухать раз в неделю и вам надо будет снова гнать юзеров на авторизацию в гугле
#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #case@ergonomic_code
Алексей Жидков
Trainer Advisor — интеграция с Google Calendar - Алексей Жидков
https://azhidkov.pro/
❤10👍7
Привет!
Я всё ещё "гамак-дривеню" проекцию модели данных Эргономичной архитектуры и чтобы накинуть больше входных данных на обработку во сне своему большому мозолистому мозгу я начал читать Data Modeling Essentials. И там наткнулся на новую для себя концепцию в моделировании данных - предаваемость (transferability) отношения.
Отношение является передаваемым, если допустимо менять сущность на одной из сторон.
Например, отношение "Заказ такси" -> "Водитель" является передаваемым. К сожалению.
А вот "Заказ такси" -> "Заказчик" - нет.
И там прям в книге явно написано, что непередаваемость является обазятельным свойтвом связи между сущностью и её слабой/зависимой сущностью.
И в качестве примера такой связи приводят хрестоматийный пример "Заказ" -> "Позиция заказа".
Ну и т.к., имхо, ДДД Агрегаты и сущности+слабые сущности - это одни и те же яйца только в профиль, то можно брать на вооружение эту эвристику при проектировании агрегатов - включать в агрегат только то, что невозможно передать другому агрегату. Не то чтобы супер прорыв, но эврстик много не бывает, на мой взгляд.
NB: и на всякий случай - это необходимое, но недостаточное условие - ни Заказ, ни Заказчик не являются частью агрегата друг друга.
Но непередаваемые связи могут быть не только внутри агрегата, но и между ними. И это уже стало для меня откровением.
В качестве примера в книге приводят связь между страховым полисом и агентом - в их картине мира у полиса может не быть агента, но если он есть - изменить его нельзя.
Это тоже не сказать что прорывная идея, но она была за рамками моих шор. И, возможно, это поможет мне решить одну из проблем, над которыми я бьюсь.
Касательно книги - я пока ток начал её читать и скачу в ней поссылкам, а не читаю от корки до корки, но выглядит очень много обещающе - как актуальный и исчерпывающий источник информации по моделированию данных.
#ergo_arch@ergonomic_code #ergo_data_model@ergonomic_code #ergo_persistance@ergonomic_code #books@ergonomic_code #ddd@ergonomic_code
Я всё ещё "гамак-дривеню" проекцию модели данных Эргономичной архитектуры и чтобы накинуть больше входных данных на обработку во сне своему большому мозолистому мозгу я начал читать Data Modeling Essentials. И там наткнулся на новую для себя концепцию в моделировании данных - предаваемость (transferability) отношения.
Отношение является передаваемым, если допустимо менять сущность на одной из сторон.
Например, отношение "Заказ такси" -> "Водитель" является передаваемым. К сожалению.
А вот "Заказ такси" -> "Заказчик" - нет.
И там прям в книге явно написано, что непередаваемость является обазятельным свойтвом связи между сущностью и её слабой/зависимой сущностью.
И в качестве примера такой связи приводят хрестоматийный пример "Заказ" -> "Позиция заказа".
Ну и т.к., имхо, ДДД Агрегаты и сущности+слабые сущности - это одни и те же яйца только в профиль, то можно брать на вооружение эту эвристику при проектировании агрегатов - включать в агрегат только то, что невозможно передать другому агрегату. Не то чтобы супер прорыв, но эврстик много не бывает, на мой взгляд.
NB: и на всякий случай - это необходимое, но недостаточное условие - ни Заказ, ни Заказчик не являются частью агрегата друг друга.
Но непередаваемые связи могут быть не только внутри агрегата, но и между ними. И это уже стало для меня откровением.
В качестве примера в книге приводят связь между страховым полисом и агентом - в их картине мира у полиса может не быть агента, но если он есть - изменить его нельзя.
Это тоже не сказать что прорывная идея, но она была за рамками моих шор. И, возможно, это поможет мне решить одну из проблем, над которыми я бьюсь.
Касательно книги - я пока ток начал её читать и скачу в ней поссылкам, а не читаю от корки до корки, но выглядит очень много обещающе - как актуальный и исчерпывающий источник информации по моделированию данных.
#ergo_arch@ergonomic_code #ergo_data_model@ergonomic_code #ergo_persistance@ergonomic_code #books@ergonomic_code #ddd@ergonomic_code
Эргономичный подход
Эргономичная архитектура (v3.0.0)
Текущая версия статьи написана в режиме потока сознания и пока что я не проводил даже проверки правописания, не говоря уж о том, чтобы сопроводить идеи иллюстрациями и кодом.
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
❤5👍5🔥4
Привет!
Я недавно сделал Web Push уведомления в Trainer Advisor и попутно снова узнал и придумал пачку прикольных штук, о которых накатал очередной "микропост" на 30-40 минут чтения по оценке ФФ.
Ну и по традции вот вам сразу содержание, чтобы привлечь внимание мякоткой:
* Отправка пушей
* Архитектура
* Абстракция vs очевидность эффектов и разделение ввода и вывода
* И снова про уровни абстракции/стратификацию
* Пример №1: код открытия диплинка по клику
* Пример №2: фетч ресурсов с фолбэком на кэш и кастомную страницу «Сервис недоступен"
* Postgres GENERATED-колонки для ограничений целостности в JSONB
* TrainerAdvisorApis
* В Gradle-плагин GitProperties завезли поддержку git worktrees
* Отказ от Kotest Matchers в пользу shuold*-методов
#case@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #ergo_persistance@ergonomic_code
Я недавно сделал Web Push уведомления в Trainer Advisor и попутно снова узнал и придумал пачку прикольных штук, о которых накатал очередной "микропост" на 30-40 минут чтения по оценке ФФ.
Ну и по традции вот вам сразу содержание, чтобы привлечь внимание мякоткой:
* Отправка пушей
* Архитектура
* Абстракция vs очевидность эффектов и разделение ввода и вывода
* И снова про уровни абстракции/стратификацию
* Пример №1: код открытия диплинка по клику
* Пример №2: фетч ресурсов с фолбэком на кэш и кастомную страницу «Сервис недоступен"
* Postgres GENERATED-колонки для ограничений целостности в JSONB
* TrainerAdvisorApis
* В Gradle-плагин GitProperties завезли поддержку git worktrees
* Отказ от Kotest Matchers в пользу shuold*-методов
#case@ergonomic_code #ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #ergo_testing@ergonomic_code #trainer_advisor@ergonomic_code #ergo_persistance@ergonomic_code
Алексей Жидков
Trainer Advisor — WebPush-уведомления - Алексей Жидков
https://azhidkov.pro/
🔥4❤3👍2
Привет!
У меня в Эргономичной архитектуре есть ограничение на количество атрибутов сущностей и зависимостей операций (сервисов) с рекомендуемым значением "до 7 +/- 2".
И вот я в очередной раз наткнулся, на то, что это не я один такойумный сумасшедший, но есть и общепризнанные авторитеты, разделяющие ту же точку зрения:)
Я тут в рамках разработки Ergo AI Agent Framework пошёл снова ботанить понятия cohesion и coupling, и, в частности, пошёл читать Code Complete (aka Совершенный код).
И там на странице 143 английским по белому написано:
Возможно, вы, глядя на свою MyCoreEntity с 100+ полей и MyCoreEntityService с 80+ зависимостей, думаете, что мы с Макконнеллом теоретики, которые реального кода в глаза не видели.
Но это не так:)
Может быть, и не до 7 полей, но существенно упросить MyCoreEntity можно с помощью:
1. активного выделения Value Object-ов — например, завести класс PersonName(first, middle, last) и заменить три поля на одно;
2. активного выделения аспектов сущности в отдельные сущности — например, убрать из коренной сущности пользователя поле с его подписками, на веб-пуши.
А справиться с MyCoreEntityService поможет:
1. переход от сервисов к классам-операциям (ака юз-кейсам, интеракторам) — выделение каждого метода класса сервиса в отдельный класс с одним публичным методом. С непривычки это кажется дичью — по себе знаю, мне самому так казалось 2.5 года назад — но к этому быстро привыкаешь и назад уже не хочется;
2. повышение уровня абстракции ресурсов/гейтвеев/портов — например, если у вас агрегат включает в себя блоб (картинку), то можно заменить зависимость от UsersRepo и FilesStorage на сложный/составной ресурс/порт/гейтвей, которые внутри себя держит UsersDao для работы с РСУБД и FilesStorage для работы с хранилищем блобов.
#ergo_arch@ergonomic_code #books@ergonomic_code
У меня в Эргономичной архитектуре есть ограничение на количество атрибутов сущностей и зависимостей операций (сервисов) с рекомендуемым значением "до 7 +/- 2".
И вот я в очередной раз наткнулся, на то, что это не я один такой
Я тут в рамках разработки Ergo AI Agent Framework пошёл снова ботанить понятия cohesion и coupling, и, в частности, пошёл читать Code Complete (aka Совершенный код).
И там на странице 143 английским по белому написано:
Be critical of classes that contain more than about seven data members
The number “7±2” has been found to be a number of discrete items a person can remember while performing other tasks (Miller 1956). If a class contains more than about seven data members, consider whether the class should be decomposed into multiple smaller classes (Riel 1996). You might err more toward the high end of 7±2 if the data members are primitive data types like integers and strings, more toward the lower end of 7±2 if the data members are complex objects.
—
Критически относитесь к классам, содержащим более чем примерно семь полей данных.
Число «7±2» было выявлено как количество отдельных элементов, которое человек способен удерживать в памяти, выполняя при этом другие задачи (Miller, 1956). Если класс содержит более примерно семи полей данных, сто́ит задуматься о том, не следует ли разложить его на несколько более мелких классов (Riel, 1996).
Можно смещаться ближе к верхней границе диапазона 7±2, если поля представлены примитивными типами данных, такими как целые числа и строки; и ближе к нижней границе, если поля являются сложными объектами.
Возможно, вы, глядя на свою MyCoreEntity с 100+ полей и MyCoreEntityService с 80+ зависимостей, думаете, что мы с Макконнеллом теоретики, которые реального кода в глаза не видели.
Но это не так:)
Может быть, и не до 7 полей, но существенно упросить MyCoreEntity можно с помощью:
1. активного выделения Value Object-ов — например, завести класс PersonName(first, middle, last) и заменить три поля на одно;
2. активного выделения аспектов сущности в отдельные сущности — например, убрать из коренной сущности пользователя поле с его подписками, на веб-пуши.
А справиться с MyCoreEntityService поможет:
1. переход от сервисов к классам-операциям (ака юз-кейсам, интеракторам) — выделение каждого метода класса сервиса в отдельный класс с одним публичным методом. С непривычки это кажется дичью — по себе знаю, мне самому так казалось 2.5 года назад — но к этому быстро привыкаешь и назад уже не хочется;
2. повышение уровня абстракции ресурсов/гейтвеев/портов — например, если у вас агрегат включает в себя блоб (картинку), то можно заменить зависимость от UsersRepo и FilesStorage на сложный/составной ресурс/порт/гейтвей, которые внутри себя держит UsersDao для работы с РСУБД и FilesStorage для работы с хранилищем блобов.
#ergo_arch@ergonomic_code #books@ergonomic_code
Эргономичный подход
Эргономичная архитектура (v3.0.0)
Текущая версия статьи написана в режиме потока сознания и пока что я не проводил даже проверки правописания, не говоря уж о том, чтобы сопроводить идеи иллюстрациями и кодом.
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
Предыдущие черновики и диаграммы здесь.
Введение В своей книге The Problem with…
❤9👍5👀2