Pull to refresh

Comments 57

Архитектура начинается с анализа функциональных и не функциональных требований, и поиск баланса в -abilities, а не GOF/SOLID/GRASP

Не обязательно.

Точнее, архитектор вообще на конкретные ФТ и НФТ мало обращает внимание. Но НФТ по производительности и доступности это его хлеб.

  • Стратегическое видение

  • Структура комплект и их взаимодействие, в частности потоки данных

  • Представления 4+1

  • Выбор технологий и инструментов, как средство для достижения целей

  • Компромиссы требований и архитектурные решения, искусство баланса

Детализации до классов это дело аналитика. Да и то не надо... Лучше API, потоки данных. Лучше лид сделает top down design with stubs а остальные побегут делать детали. Это я тонко намекаю что ООП часто вообще плохой инструмент и для проектирования и для реализации.

В общем, описать контракты и следить чтобы разработчик их не нарушал, следовал архитектуре

Причем, автор называет себя CTO, architect

Бггг

Спасибо за мысль — действительно, часто архитектура ассоциируется именно с high-level проектированием: потоки, API, FT/NFT, масштабирование, доступность. И там GRASP может казаться "мелочью".

Но в работе с предметной логикой, в попытке удержать смысл на уровне кода — как раз такие паттерны оказываются полезны. Они помогают не просто "писать код", а раскладывать ответственность и поведение осознанно.

В итоге и high-level, и low-level архитектура нужны — просто на разных уровнях зрелости проекта и команды. Иногда и "раскладывание по папочкам" — это именно архитектура, если это поддерживает масштаб и смысл кода.

Абсолютно согласен, что -abilities и компромиссы между ними — краеугольный камень архитектуры. Это фундамент на уровне системного проектирования. Но в какой-то момент все это неизбежно превращается в код и модели — и вот там уже нужен другой инструмент. GRASP работает на этом уровне: он не первым идет в бой, но он точно появится, когда начинаешь проектировать глубоко и предметно.

Когда прочитал про проблему выявления сущностей предметной области в контексте DDD, подумал, что дальше будет про event storming или что-то аналогичное... но нет, опять те же принципы структурирования предметной области (уже как-то описанной), только под другим углом, - а не то, как мы получили то, что собственно, структурируем.

Да, вы абсолютно правы. Я, кажется, действительно скатился до уровня Эванса:-D — начал с того, что модель у нас уже как будто есть, и сразу перешел к GRASP и тактическому проектированию.

А ведь Ларман в первой части как раз строит мост от требований к модели — через use-case'ы, анализ, event storming, выявление концептов. Всё то, что я в тексте умолчал, хотя в практике оно, конечно, присутствует.

Спасибо за точное замечание. Теперь понимаю, что это отдельная тема, достойная системного изложения. Думаю, это и будет логичным продолжением — как мы вообще приходим к модели, которую потом начинаем "GRASP-ить".

Меня от всех этих книжек подташнивает. Какая-то куча абстрактных терминов наваливается, замки в облаках строятся. А потом начинаешь делать приложение, и непонятно как эту красоту применить.

Есть у кого пример приложения, которое за счет этих всех DDD и прочих SOLID, на размере хотя-бы в сотню таблиц, не превращается лапшу?

По моему 18ти-летнему опыту, в т.ч. как SA, все эти SOLID и паттерны - приводят абсолютно к такой же лапше, как без них, только с большим количеством ООП-обмазки. Я видел проекты, где 3 из 4 классов не содержат никакой логики вообще - только прокидывают что-то куда-то дальше.

Вот и не пользуйтесь ООП

Так никто и не пользуется давно. В том же вебе - контроллеры и DTO-шки - хоть оба и классы, но это не ООП.

А кто же тогда топит за ООП? Надо поспрашивать... А, да, это же автор!

ООП как раз для веб и прочего UI придумали популяризировали. Но сейчас есть способы лучше, да

Согласен, в простом вебе контроллеры и DTO действительно могут покрыть 80% задач. Но как только логика начинает выходить за рамки CRUD — начинается боль.

Условные ветвления, повторение, разрастание сервисов. И вот тогда появляется ощущение:
«А хорошо бы это поведение кому-то отдать... а что если сам объект будет за это отвечать?»

То есть ООП не ради философии, а ради локализации поведения и смысла.

А в остальном — не спорю. Кому-то подойдет фреймворк + контроллеры. Кому-то — модель. Все зависит от задачи.

То есть ООП не ради философии, а ради локализации поведения и смысла.

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

Так паттерны же - это рекомендации "если что, то можно ещё вот так", а не императивное требование их все-все-все запихать в каждый проект :) У того же Эванса есть крайне здравые идеи, которые вообще к ООП не имеют никакой привязки, тот же ubiquitous language (уж на что вроде банальная штука, но на практике столько проблем из-за разного понимания терминов). Берите что нужно, а что не нужно - не берите.

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

Но вот тут, как мне кажется, и появляется практическая ценность DDD: вместо одного монолита — выделить ограниченные контексты, где логика и модель сфокусированы.

И ни в одном из этих контекстов уже нет сотен таблиц. Там может быть 5–10 — но очень четких и связанных.

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

А как foreighn key?

В договорной подсистеме accountId, в расчетной подсистеме accountId. Таблицы УЖЕ связаны. При удалении (условно говоря) account надо удалять все bill.

Где ограниченность, где отсутствие связности?

вместо одного монолита — выделить ограниченные контексты, где логика и модель сфокусированы.

А вы уверены, что вы действительно сможете выделить ограниченные контексты, да так, чтобы они были устойчивы к изменениям, требуемым бизнесом?

Простой пример. Допустим, у вас есть магазин. С одной стороны - товары, их характеристики, наличие на складе, цена. С другой - оплата закупленного товара - всякие там клиенты, сохраненные данные их карт и т.д. То есть, Вроде как, есть два стулаограниченных контекста: в одном товары с их свойствами и наличием на складе, а в другом, а клиенты с их платежами и историями покупок. Логично, да?
А потом бизнес ставит вам задачу, добавить, например, рекомендательную систему. В какой контекст её добавишь?

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

Так что проектирование информационной системы в реальной жизни - это, во многом, искусство. Все эти теоретические принципы его не заменят (IMHO, конечно).

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

Я не против DDD, и вообще декомпозиции. Но, опять же, почему-то в книжках - все по-умному, а на практике - делается один Data Access Layer на всю БД из сотен таблиц, и дальше весь код в кишки завязывается на всё вокруг. И, хотя "бизнес-логика" - разложена аккуратно по папочкам, если каждая папочка ходит по всей БД - хрен ты это дело распилишь, если потребуется.

Мне кажется это всё потому, что все эти DDD - не выходят за рамки гуманитарных измышлений и изысканий. Читаешь - всё правильно. Закрываешь книжку, берешь лопату, и идёшь копать, то прямо от входа непонятно как построить эти границы между контекстами, если надо делать join товаров, склада, цен, людей, и коней.

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

У нас проект у него больше 1000 таблиц уже, но у нас тонкий сервер и толстый клиент вся логика там, Вот на клиенте и ООП и SOLID и все прелести. А на беке да все просто принеси подай да запиши в базу. Если что проект эта игра.

Помню году в 2000 если спрашивали как спроектировать приложение и победить сложность, правильным ответом было "начать с юзкейзов" и соответственно uml считался стандартом де-факто, а методика проектирования от юзкейзов и дальше по uml по крайней мере выглядела как план. Потом лет через 5 прочитал про DDD и тоже не понял как теперь проектировать.

Очень узнаваемое ощущение. UML + use-case'ы хотя бы давали ощущение “плана”: начни с акторов, сценариев — и что-то получится.

DDD действительно как будто вырубает лестницу и говорит:

«Вот вершина, на нее надо подняться… А как — ну, нащупаешь по дороге».

Именно поэтому мне и захотелось вернуться к Ларману — он как раз дает методику от сценариев к модели.
GRASP — это как продолжение: когда модель уже появилась, пора распределить ответственность, ввести принципы поведения.

Возможно, стоит написать вторую статью — как раз про путь от use-case’ов к концептуальной модели.

Юзкейсы и DDD - это про разное. Не представляю, как они могут мешать друг другу.

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

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

Складывалось ощущение, что мы это уже откуда‑то должны были знать.
А откуда — остаётся загадкой.

Простите если что, никого не хочу оскорбить, но.

При чтении любой темы о DDD меня не покидало это же ощущение — тебе говорят примерно так:

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

И да, я не врубался.
Или это я тупой, или мне зачем-то прививают комплекс вины.

Но если разобраться вырисовывается следующее.

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

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

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

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

Но если бы все было так, то инженеров бы не было, а были бы одни менеджеры... То есть буквально: продавать было бы нечего, но продавцов на земле было бы 8 миллиардов.

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

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

Простите великодушно, никого не хотел оскорбить.

DDD больше для аналитиков, а не для инженеров

Оно не про изделия а про бизнес процессы

И если вы не аналитик, то может и не нужно это вам. Достаточно луковой или чистой архитектуры.

Это как раз не про противостояние, а про снятие взаимных непоняток на возможно раннем этапе. DDD говорит о том, что чтобы понять, какую задачу поставил перед инженером бизнес, инженер должен найти с этим бизнесом общий язык в первую очередь на уровне понятийного аппарата. Потому как инженеру совершенно не очевидно, что значит какой-нибудь "счёт" в понимании бухгалтера или "требование" в понимании юриста, а им, в свою очередь, неочевидно, что эти базовые для них понятия надо кому-то расшифровывать. Хуже того, бизнес-пользователи в разных подразделениях могут использовать один и тот же термин для обозначения совершенно разных вещей.

Пример из своей практики. Разрабатывали систему управления активами для крупной корпорации. В процессе выяснилось, что один и тот же объект недвижимости (а это основная сущность для проекта) мог быть под одним кадастровым номером у юристов (которые его регистрировали и т.п.), но числиться как несколько разных объектов основных средств по бухгалтерии. Все клялись, что уж обратной ситуации точно не бывает никогда, пока я не разослал опросник по дочкам в регионы и выяснилось-таки, что бывает :) В итоге договорились про термины "инвентарный объект" и "кадастровый объект", установили, что в модели данных между ними бывает связь many-to-many - и очень порадовались, что проявили въедливость и выяснили это на этапе проектирования, не взяв на веру заверения заказчика.

Врёт как заказчик )

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

"да это очевидно, тут нечего обсуждать" )))

Пример с инвентарным и кадастровым — просто огонь. Именно о таких ситуациях и хочется говорить, когда упоминаешь DDD: не абстрактные конструкции, а попытка услышать, что на самом деле имеет в виду бизнес. Спасибо за качественный комментарий — он очень точно ловит суть.

Спасибо за мощный и честный комментарий. Очень откликнулось.

Действительно, во многих материалах про DDD — как у Эванса, так и в статьях — есть это ощущение “вот тебе бизнес-модель, а как ты к ней пришёл — ну это ты должен уже понимать”.

Я сам проходил через это: читаешь и не понимаешь, где начало. А ощущение “ну ты что, не въехал?” — добивает.

Согласен и с тем, что крайности вредны. DDD не должен противопоставлять инженеров и менеджеров. И уж точно не должен говорить, что твоя техническая экспертиза вдруг стала вторичной. Суть как раз в объединении — построении моста, а не стены.

Ты верно заметил: инженер тоже мыслит в терминах использования — "как устройство будет работать", и это ведь тоже язык предметной области. Просто у бизнеса и у техники — разный фокус. В идеале они сходятся.

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

Можно-ли с помощью DDD проектировать софт уровня MS Excel или ядра Linux?

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

DDD — это не инструмент для проектирования любого ПО. Он хорошо ложится на бизнес-приложения с богатыми предметными моделями — CRM, ERP, финтех, логистика и т.д.

Ядро Linux и даже Excel — это больше технологические продукты, а не бизнес-модели в чистом виде. Хотя и в них могут быть области, где DDD-подход может пригодиться — например, управление лицензиями, или создание сценариев автоматизации для пользователей.

Но в целом — нет, DDD не про системное ПО, и это нормально.

Есть хороший разбор книг Эванса и Вернона https://vaadin.com/blog/ddd-part-1-strategic-domain-driven-design в трех частях. Мне он помог разложить по полочкам абстрактные моменты, которые теряются при чтении книг за обилием букв. Нет, DDD это не обязательно про бизнес в смысле коммерции.

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

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

Сабдомены можно пометить ролями: core, support и generic. Это даст понимание, где от вас будет польза, а где лишь технические издержки. Но это не принципиально. Интересно, что в зависимости от домена одни и те же сабдомены могут иметь разные роли. В случае линукса файловые системы это core, в то время как для телекомов это generic.

У любой проблемы всегда есть либо ноль, либо больше одного частного решения (иначе бы это не называлось проблемой). Например, существует тьма файловых систем: fat, vfat, ntfs, btrfs, pohmelfs, etc. - которые по сути решают одну и ту же проблему (но с разными нюансами). Частное решение проблемы в DDD называют Bounded Context. В принципе это все ещё не код, а слова - но уже близко к решению. Представление в виде кода в него тоже станет прорастать, со временем. Нынче вездесущие LLM-ассистенты по-моему дали вполне осязаемую метафору, предлагая накидывать всю связанную информацию в контекст, чтобы из этого на выходе сложилось нужное решение.

Дальше идёт дизайн решения внутри Bounded Context - то что называется тактическим DDD. Эта часть уже имеет непосредственное отношение к кодингу. Оригинальные идеи авторов потом вылились в Hexagonal Architecture. Но на этом уровне дизайн в большей степени определяется нефункциональными требованиями, поэтому вариантов как кодить у нас на самом деле масса.

Ядро - точно нет (хгтя отдельные приёмы, наверное, и тут применимы), Excel - в серьёзной степени пригодится, но с огромными нюансами. Но это не из-за сложности, а из-за отсутствия привязки к конкретной предметной области. Для замены условной 1С или какого-нибудь архитектурного/промышленного/пр. софта, которые так же сложны, DDD Ваш лучший друг. Главное не делать никакую методику (а особенно - прикладную её часть) непогрешимой истиной, от которой нельзя отступить ни на букву. В этом плане как раз лучше читать именно Эванса и именно сначала, где он достаточно подробно и на примерах объясняет, зачем вот это всё и ещё не переходит к деталям реализации, которые специфичны для парадигмы программирования, исторического момента и субъективных предпочтений автора.

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

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

А упомянутые задачи "как отправить данные, как их получить, в какую именно таблицу сохранить и вот это вот всё" - это уровень слесаря сборщика.

Плюсую. Но на самом деле сначала пишется техническое задание. Заказчик (министерство, минобороны) разрабатывает совместно с генеральным конструктором.

ГОСТ 34.602-89, ГОСТ Р 2.114-2016, ГОСТ 19.201-78

Потом уже, когда параметры изделия определены, определены финансы, сроки, исполнители, это ТЗ передается проектировщикам.

И я бы да, поугарал бы, когда слесарь-сборщик (это, если что, сеньор-разработчик в нашем контексте, начал бы звонить в минобороны и убеждать, что надо вот так деталь выточить, уж он-то лучше знает).

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

Большая часть известных книг по архитектуре и паттернам устарела. Их нужно переработать и переосмыслить в текущих реалиях и с современными языками и фреймворками. И я не отрицаю то, что там написано, я лишь указываю на неактуальность части сведений. Тот же принцип High Cohesion очень важен и про него мало кто знает. Но вот тот же Creator, существует только потому, что когда-то ООП не допускало создавать DTO. В современном мире почти никто не наследует классы, а только интерфейсы и во всю практикуются принципы функционального программирования.

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

Ну книжек по всякой реактивной / функциональной / микросервисной / прочей модной архитектуре тоже вагон. Даже классики подтянулись, у Вернона есть книжка про reactive messaging и actor model на примере Akka. По паттернам есть Р. Кун, К. Ричардсон (оба даже переведены на русский) и т.п.

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

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

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

Или заказчику нужна SCADA, в итоге вы пишете графический движок, графический редактор, всю обработку данных реального времени и ещё свой ORM в придачу. И все это должно где нибудь в течение года сложиться и взлететь на очень слабом железе.

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

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

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

Поэтому методики проектирования 90-х они скорее оверкил в современных реалиях, почему они и не выглядят сильно полезными.

Похоже, пора выкинуть эти старые книжки

Не стоит выбрасывать старые книги – лучше подарить им вторую жизнь, адаптируя и дополняя под современные реалии. Когда я читал классический «Clean Code» в 2018 году, уже тогда многие примеры написанные на Java, решались бы средствами языка C# образца 2018 года, а многие проблемы решаются линтером. Я предлагаю составить детальный список правил линтера с пояснениями, почему каждое правило введено. Те моменты, которые невозможно формализовать через линтер – стоит описать отдельно.

Пересмотреть так же стоит ООП. Сейчас многие используют data-объекты, а в C# добавили record для удобной работы с ними. И это все не смотря на то, что data-объекты противоречат идеалогии ООП.

Также полезно привязывать паттерны к конкретным языкам программирования и фреймворкам, а в вопросах архитектуры систем – формулировать основные принципы и сопоставлять их с реальными технологиями, например, сравнивая Kafka с RabbitMQ или DynamoDB с CosmosDB. Еще важна поддержка проверенных шаблонов проектов.

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

data-объекты противоречат идеалогии ООП

Если не изменяемые, то нет.

Объекты защищают свои изменяемые данные от некорректного воздействия. А если не изменяемые то за них отвечает только создатель

Единые понятия это круто!

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

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

можно ли найти универсальный способ описания предметной области? ДА. можно ли найти универсальный способ проектирования архитектуры? ДА.

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

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

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

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

В больших сложных проектах нужны системный аналитик и UX-дизайнер. Это их задача - моделировать бизнес-процессы.

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

Не надо проектирование архитектуры и системы смешивать с реализацией. SOLID, GOF, ООП - это реализация. Проектирование систем - это отдельно.

Вы работаете или проектировщиком, либо работаете разработчиком. Соответственно, и инструменты разные, и мышление, и примемы. Всё разное.

В современном мире (точнее, уже в прошлом веке) одни люди проектируют ракету, другие - изготавливают её.

Естественно, у вас возникает ощущение "мы откуда-то сверху должны знать". Ну и прочие "показывают, как писать".

Естественно. У вас, как разработчика, задача - реализовать УЖЕ СПРОЕКТИРОВАННУЮ систему.

От этой порочной практики современного ИТ, когда сеньор и придумывает систему, и разговаривает с заказчиками, и проектирует систему, и реализовывает ее в коде - надо отходить, в сторону специализации.

Вы описываете идеальный случай. В реальности, если новый проект маленький, на него выделяют 1-2 разработчиков, которые должны уметь делать всё. Ну за исключением финального тестирования и написания документации.

Совершенно верно. В маленьких шаражках, мастерских и гаражных кооперативах, варящих оградки и решетки на окна, например, один и тот-же человек и "проектирует" оградку, и считает материалы, и режет и варит, и красит.

А когда стоит задача построить ракету и запустить ее в космос (с прошедшим, кстати!), такая система недопустима.

А в ИТ (по крайней мере, у нас) нормально, когда стартап на три человека вырастает до пятисот разработчиков, а методы разработки остаются на уровне стартапа, точнее, средневекового цеха с "фуллстек" мастерами.

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

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

Во введении вы говорите о DDD, архитектуре, принципах, но при этом никак не уточняете те детали, которые вас действительно интересуют. Поэтому в какой-то момент получаем следующее:

При этом стоит отметить, что и SOLID‑принципы не дают внятных ответов на вопрос: как именно проектировать предметную область?

Вы пишете статью с позиции разобравшегося человека. Иными словами может показаться, что есть SOLID-принципы и вам было непонятно как их применять к "требованиям, сценариям, реальной жизни", что бы получить "модель". Но теперь вы это знаете?

И у меня сразу вопрос, а причем тут "требования, сценарии" и SOLID принципы?

Если вы хотели сказать как вы заблуждались, то, на мой взгляд, лучше это было сделать явно. Т.е. так и сказать, я не знал какое место принципы Солид занимают в разработке ПО. Потому что дальше это незнание вы будете просто другими словами объяснять.

Со временем начинаешь приходить к одной странной мысли: все говорят про ООП, все пишут на объектно‑ориентированных языках — но писать и понимать, что ты пишешь, оказывается не одно и то же.

Иными словами, программист должен решать задачи, а не просто составлять рандомные программы?

И со временем приходит странное ощущение. Будто вся архитектурная зрелость современного инженера сводится к SOLID, Чистому коду, и, максимум, — паттернам GoF.

Может стоило рассказать, что такое архитектура? Потому что к данному моменту уже накидана куча терминов, и становится непонятно что современный инженер может, а чего не может. Т.е. где на карте ваших целей статьи находится то неизведанное пятно, которые вы хотите раскрыть.

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

Тут опять столько всего намешено. Вообще, Солид отвечат на вопросы какие по форме и связям должны быть объекты. И поведение и ответственность - про это тоже Солид. Но!

У вас где-то за кадром до сих пор собственно описание того о чем вообще идет речь. Чуть выше у вас была такая фигура речи: "прийти к модели". Теперь у вас такая фигура речи: " как должна выглядеть модель предметной области" Не говоря уже о какой-то "смысловой части архитектуры", а что есть какая-то бессмысленная часть архитектуры?

И в этом кроется одна из главных ловушек: Но потом сталкиваешься с реальной сложной системой — и вдруг осознаешь: тех инструментов, которые ты знал, просто не хватает. Они говорят о коде — но не о модели. О принципах оформления — но не о сути конструкции.

Тут, по моему, уже вода пошла. Потому что выше вы сказали ровно тоже самое, но другими словами. Я про то, что написание программы - это решение задачи, а не создание "какого-то" кода.

Все держится «на чувстве» и годах практики, но нет системы, нет понимания, нет архитектуры движения. Можно ехать. Но ты не знаешь — почему именно так.

Хотел похвалить за хорошую аналогию, но вы и сюда зафигачили "архитектуру", которую объяснять не стали.

Но если ты просто создаешь Hibernate-сущности с геттерами и сеттерами и меняешь их состояние в сервисах — это еще не объектно-ориентированное проектирование.

Это код на ООП-языке. Но не ООП как мышление.

И вот опять. Накидано терминов ракрывать, которые вы не стали. Что значит "просто создаешь..."? Человек решает конкретную задачу. Решает ее в терминах выбранной технологии. Это ООП мышление, если все его строительные блоки это объекты. Он может не заниматься ООП-проектированием, но при этом мыслить решение задачи объектами.

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

На мой взгляд, что бы читателю любого уровня было интересно, вам стоило все эти вопросы тезисно одним списком обозначить. И показать, что ни Solid, ни Kiss and DRY не помогали вам их тогда решить.

Он начинает с текста требований и use-case'ов, анализирует сценарии — и на их основе формирует концептуальную модель.

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

Так может стоило с этого и начать? Что бы было понятно, почему Солид принципы вам не помогали с концептуальной моделью? И какие еще бывают модели и к каким моделям как раз и нужно применять принципы Солид.

Ларман дает процесс — от анализа требований до концептуального проектирования. Он показывает, как из пользовательских сценариев прийти к модели, выявить сущности, роли и поведение.

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

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

Да неужели? Вот ваше устойчивое желание не давать никаких определений и приводит вот к таким вот казусам.

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

Совсем недавно тут была статья: https://habr.com/ru/companies/sravni/articles/896894/ - в которой как раз подробно описываются модели уровня реализации по DDD.

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

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

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

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

Спасибо и за ссылку на статью.

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

Настоящая архитектура начинается с уроков рисунка и композиции

"Архитектура" в контесте прикладной бекенд-разработки отвечает на вопросы примерно такого рода:

  1. на какие модули/сервисы/микросервисы разбить систему?

  2. по каким протоколам они будут взаимодействовать (синхронные, асинхронные)?

  3. какое хранилище данных выбрать (реляционное, нереляционное, несколько разных)?

  4. что и где надо кешировать?

  5. и т.п.

Архитектура очень важна, она определяет ключевые характеристики системы. Но она имеет мало отношения к ООП. Да, в готовой архитектуре можно найти вещи, напоминающие паттерны GoF, принципы SOLID или GRASP. Но сами по себе они не приведут вас к готовой архитектуре с нуля. Гораздо лучше работает банальный опыт и знание best practices.

Организация конкретных классов и методов обычно называется словом "дизайн". В контесте прикладной бекенд-разработки дизайн как правило диктуется фреймворками, которые вы используете. Причем чем больше ваша свобода ограничена фреймворками и практиками, принятыми на проекте, тем легче вашим коллегам разбираться в вашем коде, а вам - в их коде. На типовом Java-стеке Spring/Hibernate (который вы упомянули) можно успешно написать десятки проектов и ни разу не потренироваться в "ООП-мышлении" - все было продумано до нас.

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

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

Системы баз данных. Полный курс
Гарсиа-Молина Г., Ульман Дж. Д., Уидом Дж.

Первые главы этой книги исчерпывающее объясняют, где взять модель предметной области.

Это знание можно подпереть методологией описания бизнес-процессов и будет полный фарш.

Методология структурного анализа и проектирования SADT. Дэвид А. Марка, Клемент МакГоуэн

Мы все бежим куда-то в ооп сразу, забывая, что база закладывается в структурных подхода. И в практика ооп уже никто ничего не разжевывает.

Но многие мои знакомые коллеги, все это считает старье, не заслуживающим внимания и остаётся без базы.

Sign up to leave a comment.

Articles