Меня зовут Эмиль Карапетян. Свою карьеру я начинал как системный администратор, с 1С 7.7 познакомился в районе 2006-2007 года. В 2012 году начал кодить на 1С – подрабатывал на фрилансе. Далее руководил проектами, командами и даже отделом. На данный момент являюсь техническим архитектором в компании «Сигма».
Расскажу небольшую предысторию – как я вышел на тропу DDD и начал интересоваться модульной архитектурой.
-
Все началось с того, что меня привлекли к проекту по разработке коробочного продукта на платформе 1С.
-
Затем передо мной встал вопрос о том, как быстро и просто выпускать новые релизы и новые фичи.
-
Потом мне понадобилось дорабатывать ERP на одном из проектов внедрения.
-
Затем встал вопрос, каким образом наладить взаимодействие нескольких команд. Я на проекте был тимлидом команды, и необходимо было так взаимодействовать со второй командой, чтобы не было конфликтов и не были нарушены сроки выпуска релиза. Команда А должна была разрабатывать интеграцию с одним сервисом, а команда Б должна была разрабатывать интеграцию с другим сервисом. Но для работы второго сервиса нужно было получать данные от первого сервиса, поэтому вторая команда была связана с нами по рукам и ногам. Нужно было разделить наши процессы разработки и пустить их параллельно, а не последовательно.
-
В результате всего этого нужно было подготовить почву для создания технической и пользовательской документации.
Что такое DDD?
Разработка любого программного обеспечения похожа на строительство дома. И мы как разработчики бизнес-приложений в целом схожи со строителями.
Как у нас архитектор подготавливает проект – так же и инженеры в строительстве: чертят чертеж; накидывают, что и как должно быть; выбирают материалы; выбирают место; готовят инструменты; собирают команду. Они делают практически то же, что и мы. Только мы сидим за компьютером, а они нет.
Так же, как и мы, строители могут по-разному увидеть результат.
-
К примеру, если мы начертим чертеж в неправильном масштабе, у нас вместо складского помещения получится гараж.
-
Если мы добавим на чертеж окна, у нас уже будет частный дом.
Казалось бы, все начинается с чертежа, но нет – все начинается с вопроса: Для чего это здание? Как мы будем его использовать?
-
Мы будем там что-то хранить?
-
Туда будут приезжать газели или фуры?
-
Мы будем хранить там транспортное средство или ночевать?
DDD как раз-таки отвечает на вопрос: «Для чего это сделано». Эти три буквы расшифровываются, как Domain-Driven Design, предметно-ориентированное проектирование – прежде чем что-то проектировать, мы должны знать, для какой предметной области мы это проектируем.
Казалось бы, мы как 1С-ники это все понимаем, но при этом казусы происходят.
Немного истории.
Стандартно процесс разработки программного приложения можно представить как три кольца, движение через которые направлено к предметной области, к Domain (в переводе с английского – предметная область).
-
Сначала мы разрабатываем некий сервис.
-
Далее придумываем, как он будет выглядеть.
-
И уже потом мы решаем, для какой области это все будет реализовано.
Но когда сформулировали подход DDD, процесс разработки стал направлен в обратную сторону – от предметной области к конкретному сервису.
Когда подход DDD сформулировали, его разделили на две основных части: тактическое проектирование и стратегическое проектирование. Условно, если у нас проект по разработке 1С:Бухгалтерии 4.0 для какого-нибудь Уралмаша, эти уровни будут выглядеть так:
-
Тактическое проектирование – мы открываем конфигуратор и сразу же накидываем туда объекты метаданных.
-
Стратегическое проектирование – мы исследуем предметную область: «А в Уралмаше будет МСФО? А сколько планов счетов? А какие планы счетов? А какие документы? Какие еще операции и бизнес-процессы будут выполняться в Уралмаше?»
DDD сформулировал Эрик Эванс в 2004 году. Сначала был доклад, позже Эрик Эванс написал книгу «Domain-Driven Design» – ее в простонародье называют просто Blue Book или «Синяя книга». Гуглится нормально: вбиваете «Blue Book, Eric Evans» и сразу найдете.
Основная идея книги Эрика Эванса заключается в том, что сложные системы должны разрабатываться на основе понимания предметной области, в которой работает бизнес. По мнению Эрика Эванса, чтобы разработать систему:
-
Сначала нам необходимо узнать предметную область.
-
Потом мы накидываем под нее объекты метаданных.
-
И затем подстраиваем эти объекты под бизнес-процессы – строим бизнес модель.
Но чуть позже труд и книгу Эрика Эванса переосмыслили. И Вон Вернон выпустил «Красную книгу» – об имплементации подхода Domain-Driven Design.
Вон Вернон сказал, что предметная область – это хорошо, но в основе всего должна быть бизнес модель, мы должны моделировать.
По мнению Вона Вернона:
-
Исследуя предметную область, мы сначала должны понять, как будет выполняться бизнес-процесс.
-
А затем уже придумать, как накидывать объекты метаданных, и как они должны быть между собой связаны.
И поскольку бизнес-моделирование нам близко, я решил, что если бы DDD придумали в России, это были бы эти два человека.
Почему DDD – это про 1С?
Я думаю, что те, кто участвовал в проектах внедрения, знают, что перед тем, как произвести оценку проекта, нужно пообщаться с бизнес-пользователями и собрать с них нужную для проекта информацию.
Весь DDD укладывается в три основных принципа – правда, Эрик Эванс и Вон Вернон выделяют больше, но все остальные принципы тоже можно сгруппировать в эти три:
-
Единый язык.
-
Ограниченный контекст.
-
Агрегация.
Единый язык. Мы, как разработчики на 1С, отплевываемся от наших заказчиков-бухгалтеров, а представители других языков программирования, наоборот, даже собирают словарь, чтобы общаться с бизнес-пользователями на одном языке.
Все же разработчики знают, что такое «крыжить»? Если вы разрабатываете 1С:Бухгалтерию, но не знаете этого слова, значит, вы не находитесь на одной волне с бухгалтерами.
Чтобы собрать этот единый язык, нужны эксперты предметной области – эксперты домена. Это должны быть компетентные люди, и они должны сформулировать и собрать вместе с разработчиками единый язык.
Ограниченный контекст. Звонит Мария Ивановна из бухгалтерии, говорит: «У меня тут на рабочем столе какая-то ошибка, не пойму, что это». Мы ей отвечаем: «Закрой окно». Ну она и пошла, закрыла то окно, что дует. Весь смысл в контексте.
К примеру, мы разрабатываем какой-то личный кабинет для электронной коммерции. Пользователями нашей будущей системы будут:
-
клиенты;
-
продавцы – возможно, они наш непосредственный заказчик;
-
поставщики, которые должны оформить у нас в системе, что что-то нам собираются отгрузить.
У каждой группы пользователей свой контекст, у всех абсолютно разные операции и абсолютно разные бизнес-процессы.
-
У клиента результатом работы с системой будет расходный кассовый ордер.
-
Для продавца нужен отчет по остаткам.
-
Для поставщика – какой-нибудь приходный ордер или сверка заказа поставщику.
После того как мы сформулируем для каждой группы пользователей свой ограниченный контекст, мы должны сформулировать агрегаты связи между этими контекстами и между сущностями (ядрами контекста). Мы должны связать сущности и продумать:
-
Каким образом клиент будет связан с поставщиком и с продавцом?
-
Как все эти связи ложатся в контекст каждой из групп пользователей?
-
Как мы будем делить все эти бизнес-процессы?
Примерно такие вопросы волновали меня, когда задался вопросом о разработке коробочного продукта.
Результатом агрегации и формулирования связей между контекстами и сущностями должен стать бизнес-процесс. Мы должны смоделировать бизнес-процесс в любой нотации, хотя бы в самой элементарной – через блок-схемы.
Модульная архитектура – как это?
Теперь о том, что такое модульная архитектура.
В модульной архитектуре каждая отдельная часть программного комплекса связана другими частями минимально – ее отключение или удаление не приведет к какой-то аварийной ситуации.
В качестве примера возьмем один из показанных здесь гексагонов – пусть это будет мессенджер. Если мы этот мессенджер в системе отключаем, у нас все еще должна оставаться возможность открыть настройки и посмотреть уже полученные обращения от пользователей. Это очень важно – отключение модуля не должно повлечь ошибки всей системы.
Есть три важных принципа модульности:
-
Инкапсуляция;
-
Слабая связанность;
-
Динамичность.
Инкапсуляция – это когда мы выделяем части системы в отдельные модули так, чтобы их сущности и методы не соотносились между собой. Например, все, что связано с продажами, не может находиться в закупках. И наоборот.
Слабая связанность. Обратите внимание, мы говорим именно о слабой связанности, а не об отсутствии связанности в принципе, потому что модули должны быть связаны между собой – полного отсутствия связей быть не может. Но эта связанность должна быть минимизирована – настолько, насколько это возможно.
Динамичность. Ее смысл в том, что каждый модуль нашей системы должен безболезненно обновляться, и после этих изменений не должно происходить ошибок при работе системы в целом.
Где в 1С модульная архитектура?
Как же в 1С связать разные куски между собой, обновить их, и система после этого не упала?
Попробуем зайти в модульность через подсистемы – выделим какую-то часть объектов метаданных и общих модулей и свяжем их в подсистему.
Вроде бы выделили, но модульности не получилось – при обновлении подсистемы мы все равно должны анализировать конфигурацию в целом. Конечно, некоторую легкость при сравнении-объединении мы получаем, но это не то, что хотелось бы.
Попробуем подойти к модульности через расширения.
На мой взгляд, расширения – это одна из лучших фич, которые придуманы 1С. Потому что через эти расширения можно много чего сделать.
Но есть один нюанс. Когда я слышу: «Расширения? Нет», я сразу вспоминаю сериал из 90-х годов – «Альф». Там Альфу объясняли, что кошек есть нельзя, и он отвечал: «Вы просто их не умеете готовить».
С расширениями можно много чего реализовать, просто нужно их правильно уметь готовить. Само собой, их не нужно пихать туда, куда их не нужно пихать. В принципе, наверное, везде так.
DDD + модули + 1С = ?
Как связать DDD, модульность и 1С вместе?
Когда мне потребовалось применить некоторые знания о DDD и модульной архитектуре, я сделал следующее:
-
Собрал в кучу одну предметную область заказчика, выделил внутри поддомены, подобласти, и каждую отдельную подобласть запихнул в отдельное расширение.
-
А основная конфигурация у меня стала ядром этой системы.
Выглядит это примерно так – здесь показана конфигурация по автоматизации курьерской службы, которая родилась как раз при попытке реализовать такой подход. Обратите внимание, здесь каждая подобласть и и все, что связано с этой подобластью, выделены в отдельное расширение. К примеру:
-
APIManagementDPO – это расширение, содержащее API для связи с центральной системой.
-
InterfaceOperators – в это расширение я выделил графический интерфейс, с которым будет работать пользователь. Потому что когда мы разрабатываем систему в виде MVP, мы над интерфейсом можем не заморачиваться. Но мы понимаем, что в дальнейшем интерфейс будет меняться. Нам нужно повышать его удобство, чтобы даже простой сотрудник курьерской службы совершал в программе минимум действий – чтобы он мог быстро принимать посылки, быстро их отгружать клиентам. Мы изначально знаем, что интерфейс будет меняться, поэтому сразу же выносим его в отдельное расширение, чтобы удобнее его развивать.
-
DataSendingInterface – интерфейс отправки каких-то данных.
Хорошие примеры модульности в 1С:
-
Конфигурация INFOSTART ERP community edition. Она полностью модульная. Идея точно такая же: есть основная конфигурация, являющаяся ядром и много модулей в виде расширений. Классная вещь. Нигде еще не внедрил, но следить за ней интересно.
-
И БСП – почти модульная. Это как раз тот вариант, когда модульность организована за счет подсистем.
Выводы
Какие можно сделать выводы? Признаться честно, некоторые выводы – гипотетические, а некоторые – практические.
-
Удобство при внедрениях – гипотетическое, но только потому, что полностью на практике мне в конце концов не удалось реализовать этот подход, я в какой-то момент просто из компании уволился, так звезды сошлись.
-
Легкость доработок типовых конфигураций. Это практический вывод, потому что легкость доработок типовых конфигураций через расширение действительно присутствует. Но возможности расширений нужно использовать правильно – если мы замещаем что-то, откидывайте это в отдельное расширение. Не нужно валить в кучу в одно расширение замещаемые объекты и новые общие модули, обработки или формы. Изменения нужно разделять и контролировать внутренними правилами.
-
Сразу, как только мы внедрили модульную архитектуру, нам удалось решить проблемы взаимодействия и обеспечить простоту коммуникации между командами. Казалось бы, модульная архитектура – это что-то техническое, но нет. Коммуникации между командами улучшились, конфликты исчезли, а всего лишь прикрутили что-то техническое. Обычное человеческое взаимодействие было также решено с помощью технического паттерна.
-
С помощью DDD удалось выделить часть функциональности коробочной конфигурации в отдельные модули и решить проблемы с ее оперативной доработкой под конкретного заказчика. Мы сформулировали с бизнес-заказчиками единый язык. Конечно, были некоторые накладки, но взаимодействуя с непосредственным руководителем направления, мы в какой-то момент начали с ним разговаривать на одном языке, быть на одной волне, и пару раз даже четко выдержали сроки.
-
Сопровождение перестает быть мукой. Когда всей команде понятны принципы, по которым сформулированы доработки, их получается развивать быстрее. Логически, исходя из знаний о DDD, мы просто понимаем, где какая ошибка, и как ее быстро исправить.
Полезные материалы
-
Репозиторий перевода Domain-Driven Design quickly – это книга, которая была написана после выхода Blue Book Эрика Эванса. Она в сжатом варианте. Я ее взялся сам переводить и изучать как раз английский язык. Поэтому если кто-то вдруг захочет, то welcome на репозитории и вместе со мной переводить и изучать DDD.
-
Сайт всё про DDD domaindrivendesign.org – сайт на английском языке, но там очень много информации.
-
Серия статей о монолитно-модульной архитектуре из блога Камиля Гржибека. Это другой вид архитектуры, на него очень похожа архитектура большинства конфигураций 1С. Советую почитать статьи Камиля Гржибека. Это поляк, очень классные статьи, и все очень интересно раскладывает. И после его статей к 1С проникаешься такой гордостью. Чуваки на других языках программирования о таких вещах рассуждают, на которые мы, по сути, плюемся. Я даже когда случайно по GitHub лазил, нашел репозиторий на C#, который написан согласно подходу DDD, и в нем переменные функции называются на русском языке. То есть кто-то где-то плюется, что мы пишем в 1С на русском языке, а там чуваки на C# пишут на русском языке. Я был удивлен.
-
И советую telegram-канал про DDD https://t.me/dddevotion Я на них подписан, у них часто выходят вебинары.
*************
Статья написана по итогам доклада (видео), прочитанного на конференции Infostart Event 2022 Saint Petersburg.