Всем привет, меня зовут Артемий, я работаю старшим Android-разработчиком в core-команде RuStore. Мой опыт в индустрии уже 8 лет. За это время я успел поработать в разных проектах и компаниях. У меня был опыт работы на проекте, в котором было свыше 300 модулей и больше 60 Android-разработчиков. Такие условия заставляют задуматься о масштабируемости на принципиально ином уровне.

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

Цена и ценность. Немного теории

В одном из докладов, да и в жизни, часто слышал мнение, что ЧА дорогая, но стоящая. От одного человека, наоборот, слышал слова, что она того не стоит. А вы считаете ЧА дорогой?

Давайте вспомним начало книги Роберта Мартина, которая так и называется — «Чистая Архитектура». В ней автор рассказывал про период своей жизни, когда он работал над проектом в команде беспринципных разработчиков, то есть ещё не было выработано основных принципов, о которых впоследствии и рассказывается в книге. Без долгих предисловий, проект умер оказался в том состоянии, когда для выпуска фич с той же скоростью увеличивали численность разработчиков. Автор даже привёл графики, которые хорошо характеризуют положение проекта:

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

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

  • ЧА должна соответствовать определённому набору критериев.

  • Дорого поддерживать принципы, указанные в книге.

  • Сложность поддержки слоёв.

  • Много компонентов.

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

Непонимание терминологии

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

Но это не ЧА, это лишь один из вариантов представления её структуры.

Получается, что многие путают причину и следствие. ЧА не выводится из этой схемы. Это схема была выведена в результате применения принципов ЧА. Но выведена на основе опыта конкретного человека в определённом проекте для определённой платформы. Можно, конечно, попробовать вывести определение ЧА из вариантов её реализации, но для этого нам нужно больше вариантов, иначе мы будем иметь однобокое представление о ней.

Я не смог найти ни одной статьи, в которой рассказывалось бы о других вариантах реализации ЧА, и не считаю правильным давать определение ЧА, основываясь лишь на одном результате. Нужно возвращаться к истокам и искать ответ в книге. Сам автор не дал нам чёткого определения, но я могу предложить способ вывести его. Для этого нам понадобится ответить на вопрос: «Для чего нужен SOLID?».

Тема SOLID ещё более избитая, чем тема ЧА, но насколько часто вы видите в статьях о SOLID ответ на вопрос: «А зачем он нужен?». Думаю, что немало ошибок можно было бы избежать, если бы авторы этих статей сначала задавались вопросом о целях.

Почему для определения важен именно SOLID?

Первая половина книги Дяди Боба рассказывает нам про 11 принципов. Среди них есть 6 принципов организации компонентов (которые, в свою очередь, делятся на принципы сочетаемости и связности компонентов), а также 5 принципов SOLID. Казалось бы, SOLID занимает меньше половины, но на самом деле всё немного сложнее.

Вот схема зависимостей принципов, в зависимости от которых мы формируем наши зависимости (иначе говоря - принципы ЧА):

Все привыкли рассуждать только про 5 принципов, но цели применения остальных принципов ничуть не отличаются.

Чтобы ответить на вопрос: «Для чего нужен SOLID?», далеко ходить не надо, обратимся к Википедии и узнаем ответ:

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

  2. Для улучшения ПО.

Если ЧА основана на принципах, которые имеют чёткие цели, то можно заложить эти цели в определение ЧА:

Чистая Архитектура — это архитектура, которую можно будет легко поддерживать, расширять и улучшать в течение долгого времени.

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

Важно понимать, что  «лёгкость» – это не какое-то абстрактное чувство, а сохранение основного показателя – TTM (Time to market). Я мог бы сказать, что также важны время на Onboarding новичков, Build Time проекта и т.п., но всё это входит в TTM.

Противопоставление ЧА другим архитектурам

Отлично, определение выведено. Но если в нём вас смущает наличие слова «архитектура», то вы ещё не пришли к полному пониманию. Одна из проблем в понимании ЧА заключается в том, что её могут ошибочно противопоставлять другим архитектурами. Все же мы слышали, что есть и другие архитектуры? Луковичная (слоистая), гексагональная, может, кто-то вспомнит и другие. Но ЧА не может им противопоставляться.

Когда мы начали считать ЧА полноценной архитектурой? Думаю, всё начинается со статей по этой теме. Когда я только начинал изучать её, мне понравилась схема ЧА, пропущенная через призму мобильной разработки с указанием компонентов, которые характерны для нас:

C:\Users\klimenko\Desktop\ЧА\MicrosoftTeams-image (17).png

Хоть схема и пропущена через призму мобильной разработки, но по структуре своей не отличается от книжной. От статьи к статье мы видим одну и ту же привычную для нас структуру: везде между строк выводят огромный знак равенства между термином и схемой. В итоге схема считается конечной формой реализации ЧА. Но нельзя винить в этом авторов статей, ведь Дядя Боб сам подписал эту схему, как ЧА.

Согласно выведенному нами определению можно понять, что «чистота» — это свойство. Оно означает, что любая архитектура, которой мы пытались противопоставляться, может быть «чистой». Достаточно лишь руководствоваться определёнными принципами.

Что делает ЧА дорогой?

Лишние интерфейсы

Эту проблему я покажу на примере монолитной структуры, в которой модули нарезаны по слоям.

Важный момент: на схеме я не указываю зависимости от Entity, потому что любой компонент может зависеть от неё и использовать её. С указанием всех зависимостей от неё схема воспринималась бы тяжелее.

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

Для Domain:

  • Entity — сущности, характерные для нашего проекта.

  • UseCase — компонент бизнес-логики.

  • Интерфейс Repository — компонент, необходимый для применения инверсии зависимости и направления оной с data-слоя на domain-слой.

Для Presentation:

  • Presenter — компонент презентационной логики.

  • Интерфейс View — компонент, необходимый для применения инверсии зависимости и направления оной с UI-слоя на presentation-слой.

Для UI:

  • Screen компонент UI (для Android это могут быть Activity, Fragment-ы или непосредственно компоненты Screen в Compose).

Для Data:

  • Model (или DTO) — сущности data-слоя, полученные в сыром виде и ещё не прошедшие конвертацию в доменные сущности.

  • Repository — компонент, управляющий источниками и конвертерами для формирования данных в сущности domain слоя.

  • Converter — компонент, конвертирующий модели в сущности domain слоя.

  • DataSource — компонент источника данных.

  • Интерфейс API — компонент, с помощью которого мы получаем модели (DTO) через сеть.

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

Что можно сделать?

Для начала предлагаю убрать лишние интерфейсы:

Мы убрали интерфейсы для DataSource и Converter

Убрать лишние интерфейсы из проекта бывает тяжело, потому что в любом проекте могут оказаться «правозащитники интерфейсов». Сразу отмечу, что Роберт Мартин не был таким. Если кто-то будет ссылаться на его книгу, говоря, что по принципу подмены Барбары Лисков нам необходимы интерфейсы, то знайте, что Дядя Боб в книге использует или описывает интерфейсы как необходимые только в двух случаях:

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

  2. Для инверсии зависимостей.

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

Но если рассуждать о принципе подмены на уровне компонентов, то какие аргументы могли бы быть в защиту интерфейсов? Буду приводить на примере DataSource.

Пример 1: подмена между собой локальных и удалённых источников данных

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

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

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

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

Пример 2: разные реализации локальных источников

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

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

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

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

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

Подмена между собой источников данных, работающих с файлом и БД

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

Подмена между собой разных реализаций БД или инструментов, работающих с БД

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

Пример 3: модульные тесты

Считаю, что это действительно важная причина использовать интерфейсы, если у вас нет другой возможности mock-ать финализированные классы, чтобы определять поведение агрегированных полей в тестируемом классе. Но у нас в мобильной разработке под Android такая возможность есть, и мне остаётся только надеяться, что на других платформах с этим всё тоже хорошо. Если нет — поздравляю, интерфейсы для вас оправданы, и сочувствую этой неизбежности.

Пример 4: динамическая подмена

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

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

Лишние инверсии

Эту проблему я покажу на примере многомодульной структуры, в которой модули будут нарезаться по фичам на основной модуль feature и её расшариваемую часть shared, которую могут использовать и другие feature-модули.

Рассмотрим несколько примеров такой структуры:

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

Давайте попробуем понять, что такое принцип инверсии зависимостей (DIP) и для чего он нужен на самом деле. В книге про ЧА сказано, что DIP основан на SAP (Stable Abstractions Principle) и SDP (Stable Dependencies Principle).

SDP, или принцип устойчивых зависимостей.

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

В своей книге Дядя Боб определил Entities как самый устойчивый слой. За ним уже слой бизнес-логики и т. д.:

На практике, для feature-shared структуры изменения в data-слое всегда приведут к пересборке всех зависимых модулей.

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

Как бы мы могли обеспечить эту устойчивость на практике? В случае с shared-частью от data-слоя мы могли бы выделить дополнительный модуль:

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

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

SAP, или принцип устойчивости абстракций

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

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

И только теперь можно говорить про DIP

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

DIP буквально вторит определениям SDP и SAP. Сам автор говорит, что DIP невозможен без SDP и SAP. Как нам увязать эти принципы между собой? SDP — это цель. SAP — это средство. DIP — это результат. Если всё вместе, то DIP — это использование SAP для обеспечения SDP.

А если проще, то мы используем абстракции, чтобы развернуть зависимости в сторону устойчивости. Если это понимать именно так, то DIP перестаёт быть принципом вовсе. Настоящий принцип тот, что лежит в его основе и к которому мы стремимся — это SDP.

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

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

Оставайтесь на связи, и до встречи в следующей части :)

Комментарии (47)


  1. zubrbonasus
    20.03.2024 11:20
    +2

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

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


    1. remixoff
      20.03.2024 11:20
      +8

      и ключевое здесь, как мне кажется,

      а через год стартап уже был популярен

      ибо нет смысла стараться делать мёд, если потребители продукта - мухи.


      1. Kill_Voice
        20.03.2024 11:20
        +4

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


        1. mwSUE
          20.03.2024 11:20
          +2

          С одной стороны согласен конечно

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

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

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


    1. funca
      20.03.2024 11:20
      +14

      Кстати, часто эту байку рассказывают разработчики, не умеющие ни в одну из best practices. Стартапа через 3 месяца правда у них тоже не выходит, ровно по тем же причинам.


      1. zubrbonasus
        20.03.2024 11:20
        +2

        Это история из книг американских менеджеров. Но она в основе ИТ стартапов.

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


        1. KasperGreen
          20.03.2024 11:20
          +4

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

          Потом правда выясняется, что программисты плохие и сразу всё хорошо не сделали. Но это уже другая история.


          1. zubrbonasus
            20.03.2024 11:20
            +2

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

            Если приложение RuStore было популярным ещё на этапе идеи и была железобетонная уверенность, что приложение "взлетит". Для других стартапов нет уверенности в успехе и вкладываться в большую команду синиоров это дорого и может быть неэффективно. А если идея пролетит то подарок синиором будет значителен.

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


            1. funca
              20.03.2024 11:20

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

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


    1. anton_sinitcin
      20.03.2024 11:20
      +6

      Я был в стартапе где говнокодили, это привело:

      1) Куча багов из-за которых завалили презентации инвесторам и не получили инвестиции и потеряли доверие как инвесторов так и клиентов

      2) Не продуманность проекта, нам срочно нужно привлекать клиентов какой-нибудь акцией через неделю, а фич для промо нет и их пилить 3 недели

      3) Отсутствие гибкости в проекте - мы добавили поле в БД, у нас отвалилась половина запросов. У нас был платежный сервис, внезапно про бухгалтерию вспомнили через полтора года существования стартапа и именно когда нужно было отчитаться по всем транзакциям

      4) У нас не было продуктолога и прожекта, в итоге, что делать и как делать и вообще виденья продукта не было. Была только куча обещаний инвесторам от CEO. О некоторых, мы даже и не слышали до момента, когда нам начинали говорить, что мы могли бы и сами догадаться, что что-то надо было сделать раньше.

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


      1. Keirichs
        20.03.2024 11:20
        +2

        Так у вас что не пункт, так проблема менеджмента, кроме первого.


        1. whoisking
          20.03.2024 11:20

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


    1. Prikalel
      20.03.2024 11:20
      +2

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


    1. SergejSh
      20.03.2024 11:20
      +1

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


    1. MyraJKee
      20.03.2024 11:20

      Анекдот же такой есть.


    1. Didimus
      20.03.2024 11:20
      +1

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


      1. whoisking
        20.03.2024 11:20
        +1

        Архитектура в software engineering и архитектура зданий это абсолютно разные вещи. Во втором случае к вам не придут после заложенного фундамента и не скажут, что дом то должен быть на самом деле круглый, а не квадратный. После десяти построенных этажей вам не скажут, что надо сейчас сделать пять, а верхние пока отрезать. Или сделать так, чтоб каждый чётный этаж пока что не был виден жильцам и тд


        1. Didimus
          20.03.2024 11:20
          +1

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


  1. Kill_Voice
    20.03.2024 11:20
    +16

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


    1. Mes
      20.03.2024 11:20
      +1

      Исходники движка Doom?


      1. Kill_Voice
        20.03.2024 11:20
        +2

        тут я все же про итерпрайз, c играми ситуация немного иная


        1. SadOcean
          20.03.2024 11:20
          +2

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


      1. Newbilius
        20.03.2024 11:20
        +4

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


  1. SadOcean
    20.03.2024 11:20
    +4

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

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


  1. NineNineOne
    20.03.2024 11:20

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


  1. funca
    20.03.2024 11:20
    +5

    Дядя Боб является так же автором SOLID. Поэтому обосновать одно из его творений через другое это тавтология.

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

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


    1. tonx92
      20.03.2024 11:20
      +3

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

      2. Архитектура заранее известна в любом нормальном фреймворке.

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

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


      1. funca
        20.03.2024 11:20

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


  1. werevolff
    20.03.2024 11:20
    +2

    Это не ЧА дорогая - это кодеры, которые вообще не шарят в архитектуре - дешëвые. Проблема проработки архитектуры состоит в том, что если почти вся команда этого не умеет, то один человек, читавший Мартина или Нила Форда, особо ничего не сделает. Вся команда будет клепать фекальный код без тестов и разделения на слои. С другой стороны, аналогичная команда, владеющая навыками TDD, пишущая чистый код много лет, прорабатывающая архитектуру, будет справляться с аналогичной работой за примерно такое же время. Просто представителей первого типа команд - большинство. И они упорно будут доказывать, что ЧА - это долго, дорого и своих денег не стоит.

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

    Роберт Мартин находится на вершине пищевой цепи современного программирования. Ввиду развития скриптовых и сверхвысокоуровневых языков, код может писать почти любой человек, и внизу этой цепочки есть множество кодеров, готовых работать за низкую зарплату. А спрос на автоматизацию сейчас охватывает все сферы жизнедеятельности человека. Поэтому, стоит понимать, что ЧА - это, всë-таки, инструмент более сложной автоматизации, чем сайт-визитка или простенький стартап. Я бы условно разделил спрос на написание скриптов и, непосредственно, программирование. Когда вам нужно написать скрипт для продажи чего-либо, парсер, или что-то в этом духе, то мы имеем дело со скриптами. Когда перед нами стоит комплексная задача автоматизации, то мы говорим о программировании.


    1. MikeEshva
      20.03.2024 11:20
      +1

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

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

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

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

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

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

      • Feature rush, но это свойственно любому бизнесу и было сказано про стартапы. Но в случае кровавого энетерпрайза это накладывается на все прочие проблемы.

      • Множество ограничений по доступным технологиям. "Я понимаю, что здесь лучше подойдёт MongoDB, но у нас можно только MS SQL Server или Oracle". Подставьте любые другие технологии.

      • Часто проблемы с инфраструктурой. Она большая, множество legacy оборудования, которое нужно подружить с более новым. Что-то постоянно падает.

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

      • И как альфа и омега всего этого звездеца — всё те же эффективные менеджеры. Они повсюду и у каждого из них свой глюк.


      1. werevolff
        20.03.2024 11:20

        Ну, формально описание проблем больше напоминает IT отдел, нежели Энтерпрайз разработку. Я бы, в рамках своего мнения и опыта, не стал бы называть Энтерпрайзом комплекс работ по автоматизации бизнес-процессов предприятия. Энтерпрайз, в моëм понимании, подразумевает продукт собственной разработки, который требует обслуживания и нуждается в развитии (включая изменение). Интеграция сторонних решений и работа с ПО, закрытым для изменения кода - это не просто не Энтерпрайз - это вообще не разработка.

        Однако, на старте карьеры я сталкивался именно с Энтерпрайзом, который страдал от менеджмента. Но это очень редкое явление. Поверьте, на рынке можно на одну такую вакансию со страдающим проектом, найти 99 продуктовых компаний с нормальным вовлечением бизнеса в продукт и приятным процессом. Могу сказать, что в моëм опыте не только менеджмент был виновен в страданиях продукта. Зачастую, проблема была в том, что на обслуживание нанимали человека с минимальным опытом (то есть, в тот момент - меня). Ни мой опыт, ни мой доход не позволяли мне тогда изменить ситуацию с продуктом. Поэтому, людям, которые столкнулись с описываемыми вами ощущениями, я могу посоветовать только найти другое место работы с нормальным сеньором во главе команды, чтобы получить опыт. Поскольку, если у человека нет опыта и возможности продавливать полезные изменения, он не будет расти.


        1. MikeEshva
          20.03.2024 11:20

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


          1. werevolff
            20.03.2024 11:20

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


            1. MikeEshva
              20.03.2024 11:20

              Эм, а это куда? :) Если серьёзно, что Вы под "инди" понимаете? Инди-игры я знаю, но их разработка, это скорее стартап на коленке в нерабочее время. Или иначе pet-project.


              1. werevolff
                20.03.2024 11:20

                Инди (индюшатники) - это проекты, за счëт которых живëт компания, при условии, что они не доросли до стадии портала/платформы. Например, Авито трудно назвать инди-проектом, но с него он начинал. Хотя, думаю, Авито, Озон, WB сохраняют тенденции инди-энтерпрайза с большой свободой команд. Слышал от коллег, что в X5 group много проектов в режиме Энтерпрайз-стартапов. Самолëт, некоторые проекты Сбера типа Дом клик или Звук.


                1. MikeEshva
                  20.03.2024 11:20

                  Я бы, скорее, у названных проектов выделил общую черту, что это чисто коммерческие проекты/продукты/сервисы без особого внимания регуляторов, как у банков и мобильных провайдеров. К сожалению, WB и X5 мне точно не подходят, так как знаю их подноготную от бывших своих подчинённых. Сбер тоже к таким компаниям относится весьма двойственно. Ни плюшек материнской компании, ни свободы действий, и "давай-давай-давай". Да и в принципе я не ищу сейчас работу, меня устраивает место, где я работаю.

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


                  1. werevolff
                    20.03.2024 11:20

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


                    1. MikeEshva
                      20.03.2024 11:20

                      Нет. Тем более, что это обобщённый опыт за последние 10-15 лет и несколько компаний. Да, разумеется вещи вроде сервера БД покупаются, а не разрабатываются самостоятельно, но софт, например, система автоматизации кредитования крупных компаний, разрабатывается самостоятельно, а не покупается коробкой/сервисом, хотя переговоры с подобными поставщиками ведутся в познавательных интересах.

                      У нас с Вами, видимо, просто разный опыт и понимание терминов. Для меня энетерпрайз это, например, Сбер, X5, Билайн, РБК, любой коммерческий банк, Касперский и т.д. Это не инди, не стартап, не Рога и копыта со своей конфигурацией 1С и т.п.

                      Какие примеры энетерпрайза в Вашем понимании этого термина Вы можете назвать?


                      1. werevolff
                        20.03.2024 11:20

                        Хороший вопрос. Полагаю, для Энтерпрайз разработки нужен центр в виде продукта, который полностью покрывает свои расходы на сопровождение. А также, важно соблюдение стандартов качества, которые ограничивают разработчиков и побуждают их идти по пути эволюционного развития продукта. И, ещë, важна команда, которая имеет определëнную свободу принятия решений. Поскольку, без этого разработка превращается в конвейер. Поэтому, всë перечисленное вами, кроме 1С.

                        Но, опять же, не все продукты банков самоокупаемые. Не все дают свободу команде разработки (самоуправление), не все продукты имеют вектор расширения в эволюционном масштабе. Давайте говорить откровенно: язык C вышел из недр коммуникационной компании в виде эволюции языка B, который облегчал написание кода. Сейчас это стандартный язык для написания компиляторов и интерпретаторов новых ЯП. Это как динозавр, чьи потомки стали голубями, накидывающимися на семечки. При том, что AT&T были связаны с военными в США, и их логотип присутствует на некоторых объектах времëн холодной войны. Но, когда разработчикам дали свободу самоуправления, они создали нечто большее, чем просто скрипт запуска ракеты. По сути, на языке C написаны компиляторы и интерпретаторы языков, на которых функционируют сайты продажи корма для собак или карбоновых удочек. Это эволюция, это продукт. Но, что ещë более важно: это исследовательская работа. Программирование - это исследовательский научный процесс (по мнению Роберта Мартина, как минимум). Поэтому, я бы сказал, что Энтерпрайз разработка - это исследовательский процесс. Например, он может исследовать рынок. Так, разработка продукта кикшеринга превратилась в настоящий бум проката электросаиокатов. Переросла в каршеринг. Исследование рынка доставки сделала возможным существование сервисов Яндекс еды и маркетплейсов типа озона.

                        А вот, например, платëжные системы эволюционируют медленно. Исключение - блокчейн, который навëл шороху в консервативной банковской системе. Поэтому, допустим, разработку и обслуживание платëжных систем банков я за Энтерпрайз не считаю. У неë нет потенциала развития и свободы для действий команды. А вот то же Альфа Страхование я бы назвал Энтерпрайзом, поскольку это один из первых страховых онлайн продуктов на рынке.


                      1. MikeEshva
                        20.03.2024 11:20

                        Вас понял, но у нас, действительно, разное понимание этого термина Э. Вы о продукте, я о размере организации и принципах управления такими организациями, а также количестве денег и возможностях, которые эти ресурсы дают ей. В Э-организациях есть разные продукты и проекты. Последние 10-20 лет, например, стали популярны внутренние стартапы. Э-организации разные бывают. Я работал в тех, которые "наелись" коробками и аутсорсом, проблемами и большими расходами, которые с ними связаны, и, в итоге, пришли к экономической целесообразности внутренней разработки. Однако, поскольку это их непрофильная деятельность, в них есть масса проблем, которые я описал в первом своём ответе. С другой стороны, Касперский, например, изначально создавался на написание коробок, но также представляет собой Э-организацию в силу своего размера и мирового масштаба. Хочешь не хочешь, а приходится внедрять иерархию и привлекать сторонних менеджеров, что даёт те же "болезни", что и, скажем, в МТС или ВТБ. В Яндексе и Озоне пока не работал, сказать точно, что там внутри творится не могу, но могу точно сказать, что HR-ы и процесс отбора там отстойный, поскольку многолетний опыт эпизодического общения с ними я уже имею.


                      1. funca
                        20.03.2024 11:20

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

                        Enterprise Architecture это история про архитектуру бизнесов. Информационные системы и приложения лежат уровнем ниже. А в самом низу находятся различные технологии.


                      1. werevolff
                        20.03.2024 11:20

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


  1. alexandrustinov
    20.03.2024 11:20
    +10

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

    Когда тебе сначала показывают всякие слайды с кнопочками Next> Next> Next>

    а потом аналогично делают опросник вида A[ ], B[ ], C[ ], D[ ] или A( ), B( ), C( ), D( ) и опять Next> Next>

    Проект на десяток страниц строк кода, даже если с комментами. Любой первокурсник на PHP за пару вечеров напишет.

    И ни в одном проекте вроде даже уровня "магазин онлайн заказов с отгрузкой со склада по типу 1Ски" он в реальности никогда в своей жизни толком потом и не участвовал, сразу после успеха обучалки-экзаминалки рванул писать чумовые книги с Откровениями О Том Как Надо Правильно Архитектуры и Код, и вот это вот все.

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

    И все теперь сидят в лужах из пафоса и глупости, и мучаются с этими вашими MVVM. И никого же не смущает же, почему Model и View по аж два раза в Model-View-ViewModel, а почему? Явная же избыточность и непродуманность прямо на старте.

    Но нет, только так и НАДО, ибо строго по заветам Ильича, Клары Цеткин и Барбары Лискофф!


    1. funca
      20.03.2024 11:20
      +1

      Барбара кстати сама говорила, что немного в шоке от того, к чему пришла индустрия с подачи Дяди Боба - она в своей, в общем-то проходной, работе ни на какие такие откровения не претендовала, а сам принцип это просто цитата из более ранней работы её коллеги. Она использовала его скорее как гипотезу, нежели аксиому. В следующей публикации несколькими годами позже, с подачи своего науч.рука, принцип был оспорен. Но Мартина это ни сколько не смутило. Что их всех объединяло? - общая тусовка.


      1. Ivan22
        20.03.2024 11:20
        +1

        "история стала легендой, легенда фарсом, а потом уже и анекдотов насочиняли" (с)


    1. MikeEshva
      20.03.2024 11:20

      Ну, фиг его знает, у меня на проекте вполне себе чистая архитектура, привнесённая в запущенный проект мной. Новая часть кода сделана по ЧиА, а старая постепенно переносится из дремучего легаси в новую парадигму. Да, получилось много классов, но они маленькие, сконцентрированные на своей задаче, разбитые по слоям. Но в чём проблема? Так или иначе этот код должен был где-то быть, его было бы не меньше, но без ЧиА в легаси это большие классы на несколько сотен строк, а в новом коде это много классов до сотни строк каждый. Сборок тоже много, но это уже шаблон для новых модулей и разработчики привыкли подглядывать, в имеющиеся модули, чтобы понимать, какие сборки им сделать в новом модуле, что в них помещать, а что нет. То есть система работает, код писать и поддерживать проще, так как есть предсказуемость и системный подход. Да, мне пришлось поработать сверхурочно 2-3 месяца, но мне было интересно. Да, это модульный монолит, но это было сознательное решение и желательное изменение.

      Смысл MVVM тоже прекрасно понятен, хотя в последних нескольких проектах я его не использую, так как разработка у меня серверная, а не desktop/mobile, как было раньше. Очень удобный шаблон, когда у вас есть возможность навесить bindings, как это, например, в WPF. И Ильичи, будь то Владимиры или Леониды, тут ни при чём. Или вы предлагает использовать подходы RAD времён Delphi и WinForms?


    1. gal_may
      20.03.2024 11:20
      +1

      Clean Architecture, SOLID и святой Uncle Bob. Так и есть. Основной бизнес Дядюшки Боба - чтение лекций на тему CA, а не создание всяких систем. Об этом надо всегда помнить, когда читаешь его опусы :)
      В защиту MVVM скажу, что название, действительно, не слишком удачное, но разделение обязанностей в ней вполне адекватное.