Заявка на услуги DST
Наш специалист свяжется с вами, обсудит оптимальную стратегию сотрудничества,
поможет сформировать бизнес требования и рассчитает стоимость услуг.
Разработчики играют решающую роль в современных компаниях. Узнайте от специалистов компании DST Global больше о необходимости подхода, ориентированного на разработчиков, и обеспечения наблюдаемости с первого дня.
Разработчики играют решающую роль в современных компаниях. Если мы хотим, чтобы наш продукт был успешным, нам необходимо использовать подход, ориентированный на разработчиков, и обеспечить возможность наблюдения с первого дня. Читайте дальше, чтобы понять, почему.
Мир изменился
За последнее десятилетие многое изменилось. В нашем стремлении к большей масштабируемости, устойчивости и гибкости в цифровой инфраструктуре нашей организации произошел стратегический поворот от традиционных монолитных архитектур приложений к использованию современных методов разработки программного обеспечения, таких как архитектура микросервисов в сочетании с облачными приложениями. Этот сдвиг подтверждает, что в сегодняшнем быстро меняющемся технологическом ландшафте создание изолированных и независимо развертываемых сервисов дает значительные преимущества по сравнению с наследием переплетенных кодовых баз, характерных для монолитных систем.
Более того, приняв облачные принципы, адаптированные для общедоступных или гибридных облачных сред, мы еще больше оптимизировали процесс разработки и доставки наших приложений, обеспечивая при этом оптимальное использование ресурсов с помощью инструментов оркестрации контейнеров, таких как Kubernetes, которые облегчают масштабируемые шаблоны развертывания, такие как горизонтальное масштабирование для соответствия колебания спроса. Этот сдвиг парадигмы не только позволяет нам более эффективно использовать облачные ресурсы, но также поддерживает культуру DevOps , создавая среду, в которой непрерывная интеграция и доставка становятся неотъемлемыми компонентами, ускоряющими вывод на рынок новых функций или усовершенствований, соответствующих нашим бизнес-целям.
Чтобы справиться с быстро меняющимся миром, мы изменили наш подход, чтобы уменьшить сложность развертывания; они стали частыми ежедневными задачами, а не редкими сложными событиями, благодаря переходу от трудоемких ручных процессов к оптимизированным конвейерам CI/CD и созданию инструментов развертывания инфраструктуры. Этот переход существенно усложнил системную архитектуру в различных аспектах, включая, помимо прочего, инфраструктуру, настройки конфигурации, протоколы безопасности, интеграцию машинного обучения и т. д., где мы приобрели навыки управления этими сложностями посредством наших развертываний.
Тем не менее, сложная сложность баз данных не была решена должным образом ; оно резко возросло, поскольку каждое приложение теперь использует несколько типов баз данных — от систем SQL и NoSQL до специализированных настроек для конкретных задач, таких как машинное обучение или расширенные операции векторного поиска, из-за регулярных частых развертываний. Поскольку эти изменения часто внедряются асинхронно, изменения в схеме баз данных или фоновых заданиях могут произойти в любое время без предупреждения, что оказывает каскадное влияние на проблемы с производительностью во всех наших взаимосвязанных системах.
Это не только напрямую влияет на бизнес, но и усложняет усилия разработчиков и DevOps-инженеров, которым не хватает опыта для устранения этих проблем, связанных с базами данных, в одиночку, что требует внешней помощи со стороны экспертов по эксплуатации или специализированных администраторов баз данных (администраторов баз данных). Отсутствие автоматизированных решений делает процесс уязвимым из-за зависимости от ручного вмешательства . Раньше мы возлагали бремя повышенной сложности на специализированные команды, такие как администраторы баз данных или операторы. К сожалению, это больше невозможно. Сложность развертываний и приложений значительно возросла из-за сотен баз данных и сервисов, которые мы развертываем каждый день. Сегодня мы сталкиваемся с мультитенантными архитектурами с сотнями баз данных, тысячами бессерверных приложений и миллионами изменений, проходящих через конвейеры каждый день. Даже если бы мы захотели справиться с этой сложностью с помощью специализированных команд администраторов баз данных или инженеров DevOps, это просто невозможно.
Думать, что это не имеет отношения к основным бизнес-приложениям, очень далеко от истины. Давайте читаем дальше, чтобы понять, почему.
Разработчики оценивают ваш бизнес
Многие компании осознали, что оптимизация работы разработчиков неизбежно приносит многочисленные выгоды всей компании. Это происходит в основном по двум причинам: улучшение производительности и новые домены.
Автоматизация в областях разработки может значительно сократить MTTR и повысить скорость. Все бизнес-проблемы современного мира должны решаться с помощью цифровых решений, которые в конечном итоге разрабатываются и поддерживаются разработчиками. Если разработчики останутся далеко от конца воронки, это приведет к более высокому MTTR, большему количеству ошибок и более длительному устранению неполадок. С другой стороны, если мы реорганизуем среду, чтобы позволить разработчикам работать быстрее, они могут напрямую повлиять на все организационные показатели. Поэтому наша цель — вовлечь разработчиков во все действия и максимально сместить влево. Ставя больше задач непосредственно командам разработчиков, мы влияем не только на технические показатели, но и на бизнес-KPI и OKR, ориентированные на клиентов.
Вторая причина — появление новых областей, особенно связанных с машинным обучением. Решения искусственного интеллекта существенно меняют наш сегодняшний мир. Благодаря большим языковым моделям, системам рекомендаций, распознаванию изображений и интеллектуальным устройствам мы можем создавать более качественные продукты и быстрее решать проблемы наших клиентов. Однако ИИ меняется настолько быстро, что только разработчики могут справиться с этой сложностью. Это требует от разработчиков понимания не только технической стороны решений искусственного интеллекта, но и знаний предметной области бизнеса, над которым они работают. Разработчикам необходимо знать, как создавать и обучать системы рекомендаций, а также почему эти системы рекомендуют конкретные продукты и как работают общества. Это превращает разработчиков в экспертов в области социологии, политики, экономики, финансов, коммуникации, психологии и любой другой области, где ИИ приносит пользу.
Обе эти причины приводят к тому, что разработчики играют решающую роль в управлении нашим бизнесом. Времена, когда разработчики просто брали свои задачи с доски Jira, давно прошли. Разработчики не только ведут бизнес от начала до конца, но и эффективность бизнеса во многом зависит от производительности разработчиков. Поэтому нам необходимо изменить наши решения, чтобы они были более ориентированы на разработчиков, чтобы снизить среднее время восстановления, повысить скорость и дать разработчикам возможность двигаться быстрее.
Разработчики все чаще выступают за экосистему, в которой каждый компонент, от изменений конфигурации до процессов развертывания, инкапсулирован в код — философия, известная как инфраструктура как код (IaC). Такой подход не только упрощает настройку, но и обеспечивает согласованность в различных средах. Переход к полной автоматизации еще больше подчеркивает эту тенденцию; Разработчики заинтересованы в реализации конвейеров непрерывной интеграции и доставки, которые автоматически создают, тестируют и развертывают программное обеспечение без вмешательства человека, когда это возможно. Они верят в необходимость устранения ручных действий, чтобы уменьшить количество ошибок, вызванных человеческим фактором или недосмотром, и ускорить общий цикл разработки. Более того, они стремятся к тому, чтобы эти автоматизированные процессы были настолько прозрачными и обратимыми, насколько это необходимо, позволяя разработчикам быстро получать обратную связь при возникновении проблем на этапах тестирования, а также гарантировать, что любой откат может произойти беспрепятственно, если это необходимо из-за неудачного развертывания или неожиданного поведения в производственных средах. В конечном счете, цель — эффективный, устойчивый к ошибкам рабочий процесс, в котором код не только определяет функциональность, но также управляет изменениями инфраструктуры и протоколами автоматизации — концепция разработки, в значительной степени зависящая от программного обеспечения для своих операционных нужд, а не от традиционных ручных процессов.
Разработчики критически оценивают каждый инструмент, находящийся в их компетенции — будь то платформы для управления инфраструктурой, такие как Puppet или Chef, системы непрерывной интеграции, такие как Jenkins, среды развертывания, включая Kubernetes, решения для мониторинга (возможно, Prometheus или Grafana) или даже приложения искусственного интеллекта и машинного обучения. Они исследуют, насколько удобен в обслуживании продукт: может ли он обрабатывать частые обновления без простоев? Позволяет ли его архитектура легко обновляться до более новых версий с минимальными изменениями конфигурации, требуемыми самими разработчиками? Уровень автоматизации, встроенный в эти продукты, становится в центре внимания: автоматически ли обновления или изменения запускают задачи, оптимизируя рабочие процессы и уменьшая необходимость ручного вмешательства в рутинные операции по техническому обслуживанию?
Помимо простой функциональности, насколько хорошо он интегрируется в существующие конвейеры? Легко ли доступны его API, чтобы разработчики могли при необходимости расширять возможности с помощью пользовательских сценариев? Например, интеграция инструментов мониторинга в процессы CI/CD для автоматического оповещения в случае сбоя или отката выпуска из-за критических проблем является важной функцией, которую оценивают опытные разработчики, которые понимают каскадные последствия простоев в современной взаимосвязанной цифровой инфраструктуре.
Их внимание сосредоточено не только на немедленной полезности, но и на перспективности: они ищут системы, конструкция которых предполагает рост, как с точки зрения сложности инфраструктуры, так и с точки зрения огромного объема данных, обрабатываемых инструментами мониторинга или приложениями искусственного интеллекта, развернутыми в их стеках, гарантируя, что то, что сегодня может быть передовым, остается жизнеспособным на долгие годы. Разработчики стремятся не только создавать продукты, но и курировать компоненты экосистемы, предназначенные для бесперебойного обслуживания с минимальным ручным вводом, необходимым для выполнения повседневных задач, и одновременно максимизируя производительность с помощью интеллектуальных встроенных механизмов, которые прогнозируют, предотвращают или быстро устраняют проблемы.
Разработчики играют важную роль в формировании технологий внутри организаций , сотрудничая с командами на разных уровнях — менеджментом, разработкой платформ и высшим руководством — чтобы представить свои выводы, предлагаемые улучшения или инновационные решения, направленные на повышение эффективности, безопасности, масштабируемости, удобства пользователей и т. д. или другие критические факторы. Такое сотрудничество имеет решающее значение для обеспечения тесного соответствия технологических стратегий бизнес-целям и одновременного использования опыта разработчиков в создании и обслуживании программного обеспечения. Активно обмениваясь своими идеями посредством структурированных встреч, таких как обзоры кода, ежедневные стендапы, ретроспективы или специальные стратегические сессии, они помогают принимать обоснованные решения на всех уровнях руководства для более надежной технологической экосистемы, которая способствует успеху бизнеса. Это говорит о том, что для достижения успеха системы должны помнить о разработчиках.
Ваша система должна быть прежде всего разработчиком
Компании все чаще переходят на платформенные решения, чтобы повысить скорость своей работы, что позволяет ускорить циклы разработки и сократить время выхода на рынок. Используя интегрированные инструменты и услуги, платформенные решения оптимизируют рабочие процессы, уменьшают сложность управления несколькими системами и способствуют более тесному сотрудничеству между командами. Такой консолидированный подход позволяет компаниям ускорять инновации, быстро реагировать на изменения рынка и более эффективно приносить пользу клиентам, в конечном итоге получая конкурентное преимущество в быстро меняющейся бизнес-среде. Однако для повышения скорости работы решения должны быть ориентированы на разработчиков .
Давайте посмотрим на несколько примеров продуктов, в которых приоритет отдается разработчикам. Первое — это облачные вычисления. Ручное развертывание осталось в прошлом .
Другим примером являются внутренние платформы разработчиков (IDP), которые позволяют разработчикам самостоятельно создавать и развертывать свои сервисы . Разработчикам больше не нужно координировать свои действия с другими командами для создания инфраструктуры и конвейеров. Вместо этого они могут автоматизировать свои задачи посредством самообслуживания, устраняя зависимость от других. Задачи, которые раньше требовали ручного ввода от нескольких команд, теперь автоматизированы и доступны через самообслуживание, что позволяет разработчикам работать более эффективно.
Еще один пример — инструменты искусственного интеллекта. Искусственный интеллект значительно повышает эффективность разработчиков за счет плавной интеграции с их инструментами и рабочими процессами. Автоматизируя повторяющиеся задачи, такие как генерация кода, отладка и тестирование, ИИ позволяет разработчикам больше сосредоточиться на творческом решении проблем и инновациях. Инструменты на базе искусственного интеллекта также могут предоставлять предложения в режиме реального времени, обнаруживать потенциальные проблемы до того, как они станут проблемами, и оптимизировать производительность кода — и все это в среде разработки. Такая интеграция не только ускоряет процесс разработки, но и повышает качество кода, что приводит к более быстрому и надежному развертыванию и, в конечном итоге, к более продуктивному и эффективному циклу разработки. Многие инструменты (особенно в Microsoft) теперь оснащены помощниками искусственного интеллекта, которые упрощают работу разработчиков.
Наблюдаемость 2.0 спешит на помощь
Мы увидели пару решений, учитывающих опыт разработчиков. Давайте теперь посмотрим на пример области, в которой отсутствует такой подход — мониторинг и базы данных.
Системы мониторинга часто отдают приоритет необработанным и общим метрикам, поскольку они легко доступны и применимы в различных системах и приложениях. Эти метрики обычно включают данные, которые можно измерить универсально, например использование ЦП или потребление памяти. Независимо от того, использует ли приложение много ресурсов ЦП или памяти, эти основные метрики всегда доступны. Аналогичным образом, такие показатели, как сетевая активность, количество открытых файлов, количество процессоров и время выполнения, можно последовательно отслеживать в различных средах.
Проблема с этими показателями заключается в том, что они слишком общие и не дают глубокого понимания. Например, может наблюдаться всплеск загрузки ЦП, но что это значит? Или, возможно, приложение потребляет много памяти — это указывает на проблему? Без более глубокого понимания приложения сложно интерпретировать эти показатели осмысленно.
Еще одним важным моментом является определение того, сколько метрик нужно собирать и как их группировать . Простого отслеживания «использования ЦП» недостаточно: нам необходимо классифицировать показатели на основе таких факторов, как тип узла, приложение, страна или другие соответствующие параметры. Однако этот подход может создать проблемы. Если мы объединим все показатели под одной меткой «ЦП», мы можем пропустить критические проблемы, затрагивающие только часть источников. Например, если у вас 100 хостов и только на одном из них наблюдается всплеск загрузки ЦП, это не будет заметно в агрегированных данных. Хотя такие показатели, как p99 или tm99, могут дать больше информации, чем средние значения, они все равно не соответствуют действительности. Если на каждом хосте в разное время наблюдается всплеск загрузки ЦП, эти метрики могут не обнаружить проблему. Когда мы осознаем эту проблему, мы можем попытаться собрать дополнительные измерения, создать больше информационных панелей для различных подмножеств и установить пороговые значения и сигналы тревоги для каждого из них индивидуально. Однако такой подход может быстро привести к получению огромного количества метрик.
Существует несоответствие между тем, чего хотят разработчики, и тем, что евангелисты или архитекторы считают правильным. Архитекторы и руководители высшего звена продвигают решения для мониторинга, которые разработчики просто терпеть не могут . Решения для мониторинга просто неправильны, потому что они заваливают пользователей необработанными данными вместо того, чтобы предоставлять тщательно подобранные агрегаты и действенные идеи. Чтобы улучшить ситуацию, решениям для мониторинга необходимо перейти на наблюдаемость 2.0 и защиту баз данных.
Прежде всего, разработчики стремятся вообще избежать проблем . Они ищут современные решения для наблюдения, которые могут предотвратить проблемы до того, как они возникнут. Это выходит за рамки простого мониторинга показателей: оно охватывает весь жизненный цикл разработки программного обеспечения (SDLC) и каждый этап разработки внутри организации. Производственные проблемы не начинаются с внезапного увеличения трафика; они возникают гораздо раньше, когда разработчики впервые реализуют свои решения. Проблемы начинают проявляться по мере того, как эти решения внедряются в производство и клиенты начинают их использовать. Решения для наблюдения должны перейти к мониторингу всех аспектов SDLC и всех действий, которые происходят на протяжении всего процесса разработки. Сюда входит производственный код и его работа, а также конвейер CI/CD, действия по разработке и каждый отдельный тест, выполняемый с базой данных.
Во-вторых, разработчики ежедневно имеют дело с сотнями приложений . Они не могут тратить время на настройку оповещений для каждого приложения отдельно. Решения для мониторинга должны автоматически обнаруживать аномалии, устранять проблемы до их возникновения и настраивать сигналы тревоги на основе реального трафика. Они не должны выдавать сигналы тревоги на основе жестких ограничений, таких как 80% загрузки ЦП. Вместо этого они должны понять, является ли высокая загрузка ЦП ненормальной или, возможно, она присуща домену приложения.
И последнее, но не менее важное: решения для мониторинга не могут просто отслеживать файлы . Им необходимо устранять проблемы по мере их появления. Многие проблемы, связанные с базами данных, можно решить автоматически путем введения индексов, обновления статистики или изменения конфигурации системы. Эти действия могут выполняться автоматически системами мониторинга. Разработчиков следует вызывать тогда и только тогда, когда необходимо принять бизнес-решения. И когда это произойдет, разработчикам должен быть предоставлен полный контекст того, что происходит, почему, где и какой выбор им нужно сделать. Им не следует ничего отлаживать, поскольку все устранение неполадок должно выполняться автоматически с помощью инструментов.
Оставайтесь в курсе событий, помня о разработчиках
За последнее десятилетие произошли существенные изменения. В стремлении повысить масштабируемость, отказоустойчивость и гибкость цифровой инфраструктуры нашей организации мы стратегически отошли от традиционных монолитных архитектур приложений. Вместо этого мы внедрили современные методы разработки программного обеспечения, такие как архитектура микросервисов и облачные приложения. Этот сдвиг отражает признание того, что в сегодняшней быстро развивающейся технологической среде создание изолированных, независимо развертываемых сервисов дает существенные преимущества по сравнению с тесно связанными базами кода, типичными для монолитных систем.
Чтобы завершить этот переход, нам необходимо сделать все наши системы ориентированными на разработчиков. Это смещает акцент на то, что мы создаем, и как учитывать разработчиков и интегрироваться с их средами. Вместо того, чтобы загружать их данными и заставлять выполнять тяжелую работу, нам нужно предлагать решения и ответы. Многие продукты уже перешли на этот подход. Ваш продукт не должен оставаться позади.
Наш специалист свяжется с вами, обсудит оптимальную стратегию сотрудничества,
поможет сформировать бизнес требования и рассчитает стоимость услуг.
Ижевск, ул. Воткинское шоссе, д. 170 Е, Технопарк Нобель, офис 1117
Задать вопрос по почте
— TDD — ну, это все знают, сначала пишем тесты, а потом остальной код.
— BDD — что-то знакомое, вроде как, тоже тесты, но особенные.
— TDD — снова? Так, стоп, тут речь уже не о тестах совсем. Но почему называется так же?
— DDD — bound contexts, ubiquitous language, domain…
— FDD — да сколько можно?
— MDD — cерьезно, на основе диаграмм?
— PDD —…
Подходы к разработке делятся по сложности, областям применения и целям. Думаю, хотелось бы разобраться, зачем же они нужны, почему их так много
TDD — это методология разработки ПО, которая основывается на повторении коротких циклов разработки: изначально пишется тест, покрывающий желаемое изменение, затем пишется программный код, который реализует желаемое поведение системы и позволит пройти написанный тест. Затем проводится рефакторинг написанного кода с постоянной проверкой прохождения тестов.
Звучит просто и понятно. Многим знаком такой подход к разработке и даже сам «Uncle Bob» активно его пропагандирует:
«TDD считается одной из форм правильного метода построения приложения. Философия разработки на основе тестов заключается в том, что ваши тесты являются спецификацией того, как ваша программа должна вести себя. Если вы рассматриваете свой набор тестов как обязательную часть процесса сборки, если ваши тесты не проходят, программа не собирается, потому что она неверна. Конечно, ограничение заключается в том, что правильность вашей программы определена только как полнота ваших тестов. Тем не менее, исследования показали, что разработка, основанная на тестировании, может привести к снижению ошибок на 40-80% в производстве.»
Начав использовать TDD, вы можете почувствовать, что работаете медленнее, чем обычно. Так происходит потому что вы будете работать вне «зоны комфорта», и это вполне нормально.
После того, как вы ощутите, что написание тестов стало простой и естественной частью рабочего процесса, что вам больше не нужно думать об использовании TDD при работе над проектом, вы осознаете, что TDD влилось в вашу работу.
Эта методология позволяет добиться создания пригодного для автоматического тестирования приложения и очень хорошего покрытия кода тестами, так как ТЗ переводится на язык автоматических тестов, то есть всё, что программа должна делать, проверяется. Также TDD часто упрощает программную реализацию: исключается избыточность реализации — если компонент проходит тест, то он считается готовым.
Архитектура программных продуктов, разрабатываемых таким образом, обычно лучше (в приложениях, которые пригодны для автоматического тестирования, обычно очень хорошо распределяется ответственность между компонентами, а выполняемые сложные процедуры декомпозированы на множество простых). Стабильность работы приложения, разработанного через тестирование, выше за счёт того, что все основные функциональные возможности программы покрыты тестами и их работоспособность постоянно проверяется. Сопровождаемость проектов, где тестируется всё или практически всё, очень высока — разработчики могут не бояться вносить изменения в код, если что-то пойдёт не так, то об этом сообщат результаты автоматического тестирования.
Подробнее с принципами TDD вы можете ознакомиться, прочитав книгу Кента Бека «Экстремальное программирование. Разработка через тестирование».
TDD — Type Driven Development
Type Driven Development сокращенно пишется также, как и разработка через тестирование, поэтому обычно пишут полное название.
При разработке на основе типов ваши типы данных и сигнатуры типов являются спецификацией программы. Типы также служат формой документации, которая гарантированно обновляется.
Типы представляют из себя небольшие контрольные точки, благодаря которым, мы получаем множество мини-тестов по всему нашему приложению. Причем затраты на создание типов минимальны и актуализировать их не требуется, так как они являются частью кодовой базы.
Разработка по типу — это еще один правильный метод построения приложения. Как и в случае разработки на основе тестирования, разработка на основе типов может повысить вашу уверенность в коде и сэкономить ваше время при внесении изменений в большую кодовую базу.
Из минусов только возрастающая сложность у языков с динамической типизацией. К примеру, для JavaScript этот подход тяжелее применить, чем для TypeScript.
BDD — Behaviour Driven Development
Из-за некоторого методологического сходства TDD (Test Driven Development) и BDD (Behaviour Driven Development) часто путают даже профессионалы. В чем же отличие? Концепции обоих подходов похожи, сначала идут тесты и только потом начинается разработка, но предназначение у них совершенно разное. TDD — это больше о программировании и тестировании на уровне технической реализации продукта, когда тесты создают сами разработчики.
BDD предполагает описание тестировщиком или аналитиком пользовательских сценариев на естественном языке — если можно так выразиться, на языке бизнеса. BDD — behaviour-driven development — это разработка, основанная на описании поведения. Определенный человек(или люди) пишет описания вида «я как пользователь хочу когда нажали кнопку пуск тогда показывалось меню как на картинке» (там есть специально выделенные ключевые слова). Программисты давно написали специальные инструменты, которые подобные описания переводят в тесты (иногда совсем прозрачно для программиста). А дальше классическая разработка с тестами.
Если записывать названия тестов в виде предложений и при записи имен методов использовать лексику бизнес-домена, созданная документация становится понятна заказчикам, аналитикам и тестировщикам.
Тексты сценариев записываются в определенной форме.
BDD подход совместно с инженерными практиками позволил нам отказаться от legacy-документации, содержащей неактуальную информацию, и получать новую документацию на лету, хранить ее вместе с проектом, что приблизило аналитиков и тестировщиков к коду.
BDD — скорее, процесс, целью которого является удешевление реализации новых фич. Еще на старте разработки мы получаем важные артефакты. Например, понятную для поддержки документацию. Эта документация дает возможность всем заинтересованным лицам сформировать свое представление о продукте и сценариях пользовательского поведения, которые должны быть реализованы в ходе итераций разработки. С BDD-подходом мы также снижаем порог входа в проект новых участников.
В чем преимущество BDD?
— Тесты читаемые для не программистов.
— Их легко изменять. Они часто пишутся почти на чистом английском.
— Их может писать product owner или другие заинтересованные лица.
— Результаты выполнения тестов более «человечные».
— Тесты не зависят от целевого языка программирования. Миграция на другой язык сильно упрощается.
Минусы:
Но у данного подхода есть и недостатки — это долго и дорого. BDD неудобен хотя бы тем, что требует привлечения специалистов тестирования уже на этапе проработки требований, а это удлиняет цикл разработки.
Выходом из этой ситуации может оказаться выбор подходящего BDD фреймворка и правильно выстроенных процессов разработки.
Подробнее о BDD можно прочитать тут.
Многие уже давно поняли, что тестирование — это своего рода панацея от всех болезней, но так ли это на самом деле? Безусловно, основательно протестированный код работает стабильнее и предсказуемее, но тесты не избавляют нас от проблем и ошибок на этапе проектирования и постановки задач. Следующие подходы к разработке могут помочь вам с этим.
DDD — Domain Driven Design
Предметно-ориентированное проектирование не является какой-либо конкретной технологией или методологией. DDD — это набор правил, которые позволяют принимать правильные проектные решения. Данный подход позволяет значительно ускорить процесс проектирования программного обеспечения в незнакомой предметной области.
Предметно-ориентированное проектирование (реже проблемно-ориентированное, англ. Domain-driven design, DDD) — это набор принципов и схем, направленных на создание оптимальных систем объектов. Процесс разработки сводится к созданию программных абстракций, которые называются моделями предметных областей. В эти модели входит бизнес-логика, устанавливающая связь между реальными условиями области применения продукта и кодом.
Подход DDD особо полезен в ситуациях, когда разработчик не является специалистом в области разрабатываемого продукта. К примеру: программист не может знать все области, в которых требуется создать ПО, но с помощью правильного представления структуры, посредством предметно-ориентированного подхода, может без труда спроектировать приложение, основываясь на ключевых моментах и знаниях рабочей области.
В этой статье я стараюсь передать суть каждого подхода к разработке ПО, но про DDD можно написать не одну статью и охватить все нюансы в нескольких абзацах у меня не выйдет. Поэтому при объяснении я буду приводить поясняющие ссылки на самые достойные источники.
Основная цель Domain-Driven Design — это борьба со сложностью бизнес-процессов, их автоматизации и реализации в коде. «Domain» переводится как «предметная область», и именно от предметной области отталкивается разработка и проектирование в рамках данного подхода.
Ключевым понятием в DDD является «единый язык» (ubiquitous language). Ubiquitous language способствует прозрачному общению между участниками проекта. Единый он не в том смысле, что он один на все случаи жизни. Как раз наоборот. Все участники общаются на нём, всё обсуждение происходит в терминах единого языка, и все артефакты максимально должны излагаться в терминах единого языка, то есть, начиная от ТЗ, и, заканчивая кодом.
Следующим понятием является «доменная модель». Данная модель представляет из себя словарь терминов из ubiquitous language. И доменная модель, и ubiquitous language ограничены контекстом, который в Domain-Driven Design называется bounded context. Он ограничивает доменную модель таким образом, чтобы все понятия внутри него были однозначными, и все понимали, о чём идёт речь.
Пример: возьмем сущность «человек» и поместим его в контекст «публичные выступления». В этом контексте, по DDD, он становится спикером или оратором. А в контексте «семья» — мужем или братом.
Теперь про код. Важно, чтобы ваш код читался как книга, был прост и понятен всем, кто владеет единым языком проекта. Что я имею в виду?
Если в языке проекта вы используете выражения «продукт был добавлен», то следующий вариант не по DDD:
Почему? В коде написано, что мы создали продукт странным образом и сохранили его. Как же все таки добавить продукт? Нужно его добавить. Вот DDD код:
Архитектура:
С точки зрения Domain-Driven Design абсолютно всё равно, какую архитектуру вы выберете. Domain-Driven Design не про это, Domain-Driven Design про язык и про общение.
Но DDD почти невозможен без чистой архитектуры проекта, так как при добавлении новой функциональности или изменении старой нужно стараться сохранять гибкость и прозрачность кодовой базы. Про порты, адаптеры и луковую архитектуру можно прочитать в отличной статье. Картинка сверху как раз из нее.
Про DDD также есть статьи, которые я очень советую прочитать внимательно — тут и тут.
Что же нам это дает в итоге:
— почти все участники команды могут читать код проекта;
— постановка задач становится более явной;
— баги бизнес логики становиться проще искать;
— QA специалистам намного легче просматривать код и находить логические ошибки и баги.
Минусы:
— требуется высокая квалификация разработчиков, особенно, на старте проекта;
— не все клиенты готовы пойти на такие затраты, DDD нужно учиться всем участникам процесса разработки.
FDD — Features Driven Development
FDD — Эта методология (кратко именуемая FDD) была разработана Джеффом Де Люка (Jeff De Luca) и признанным гуру в области объектно-ориентированных технологий Питером Коадом (Peter Coad). FDD представляет собой попытку объединить наиболее признанные в индустрии разработки программного обеспечения методики, принимающие за основу важную для заказчика функциональность (свойства) разрабатываемого программного обеспечения. Основной целью данной методологии является разработка реального, работающего программного обеспечения систематически, в поставленные сроки.
Как и остальные адаптивные методологии, она делает основной упор на коротких итерациях, каждая из которых служит для проработки определенной части функциональности системы. Согласно FDD, одна итерация длится две недели. FDD насчитывает пять процессов. Первые три из них относятся к началу проекта:
— разработка общей модели;
— составление списка требуемых свойств системы;
— планирование работы над каждым свойством;
— проектирование каждого свойства;
— конструирование каждого свойства.
Последние два шага необходимо делать во время каждой итерации. При этом каждый процесс разбивается на задачи и имеет критерии верификации.
Давайте поподробнее остановимся на каждом пункте.
Разработка общей модели
Разработка начинается c анализа широты имеющегося круга задач и контекста системы. Далее для каждой моделируемой области делается более детальный разбор. Предварительные описания составляются небольшими группами и выносятся на дальнейшее обсуждение и экспертную оценку. После одна из предлагаемых моделей или их совокупность становится моделью для конкретной области. Модели каждой области задач объединяются в общую итоговую модель, которая может изменяться в течение работы.
Составление списка функций
Информация, собранная при построении общей модели, используется для составления списка функций. Функции объединяются в так называемые «области» (англ. domain), а они же в свою очередь делятся на подобласти (англ. subject areas) по функциональному признаку.
Каждая подобласть соответствует определенному бизнес-процессу, а его шаги становятся списком функций (свойств). Функции представлены в виде «действие — результат — объект», например, «проверка пароля пользователя». Разработка каждой функции должна занимать не более 2 недель, иначе задачу необходимо декомпозировать на более мелкими итерации. Список свойств в FDD – то же самое, что и product backlog в SCRUM.
План по свойствам (функциям)
Далее идет этап распределения функций среди ведущих программистов или по командам.
Проектирование функций
Для каждого свойства создается проектировочный пакет. Ведущий программист выделяет небольшую группу свойств для разработки в течение двух недель. После оставляются подробные диаграммы последовательности для каждого свойства, уточняя общую модель. Далее пишутся «заглушки» классов и методов. В этот момент мы должны сфокусироваться на дизайне программного продукта.
Реализация функции
На пути к эффективному тестированию: выбираем лучшую TMS
Пишем код, убираем заглушки, тестируем.
После того, как свойство протестировано и ушло в продукт, берем следующее по приоритетам свойство, повторяем цикл дизайна/реализации.
Итого, в результате мы получаем:
— документация по свойствам системы;
— тщательное проектирование;
— проще оценивать небольшие задачи;
— тесты ориентированы на бизнес-задачи;
— проработанный процесс создания продукта;
— короткие итеративные циклы разработки позволяют быстрее наращивать функциональность и уменьшить количество ошибок.
Минусы:
— FDD больше подходит для больших проектов. Небольшие команды разработки не смогут прочувствовать все преимущества данного подхода;
— значительные затраты на внедрение и обучение.
MDD — Model Driven Development
В последнее время много внимания в публикациях отводится теме архитектуры и разработке на основе моделей MDA (Model Driven Architecture) и MDD (Model Driven Development). Не вдаваясь в подробности, выделим только ключевые моменты.
Разработка, управляемая моделями, (англ. model-driven development) — это стиль разработки программного обеспечения, когда модели становятся основными артефактами разработки, из которых генерируется код и другие артефакты.
Если говорить проще, то вся суть разработки сводится к построению необходимых диаграмм, из которых впоследствии мы генерируем рабочий код проекта.
Основная цель MDD — минимизация затрат, связанных с привязкой к конкретным системным платформам и программным инфраструктурам. Ведь основная бизнес-логика содержится в диаграммах и не сковывает нас рамками выбора языка программирования и инструментов разработки.
Давайте немного отвлечемся и вспомним про компилятор. Он преобразует язык программирования высокого уровня в эквивалентную реализацию на машинном языке. Моделью в этом случае является программа, написанная на языке высокого уровня, которая скрывает несущественные детали о ее реализации. В MDD наши диаграммы — это еще один уровень абстракции, который не позволяет нам увязнуть в деталях разработки, а посмотреть на картину в целом.
Диаграммы выступают в качестве своеобразных «чертежей», из которых различные автоматизированные и полуавтоматизированные процессы извлекают программы и соответствующие модели. Причем автоматическая генерация кода варьируется от извлечения простого скелета приложения до получения конечной кодовой базы (что сравнимо с традиционной компиляцией).
Идея MDD не нова ‑ она использовались с переменным успехом и раньше. Причиной возросшего внимания к ним в настоящее время является то, что автоматизации поддается значительно больше процессов, чем раньше. Это развитие отражается в появлении MDD-стандартов, что ведет к унификации соответствующих средств. Одним из таких стандартов является пересмотренная версия Unified Modeling Language – UML 2.0.
По стандартам Object Management Group (OMG) создание приложения состоит из следующих шагов:
— cначала разрабатывается модель предметной области проектируемого приложения, полностью независимая от имплементирующей технологии;
— затем она трансформируется специальным инструментом в платформо-зависимую модель;
— наконец, она переводится в исходный код на соответствующем языке программирования.
Классический пример применения MDD, который используется уже давно, — моделирование баз данных. На основе одной концептуальной модели данных вы можете поддерживать несколько связанных с ней физических моделей для различных СУБД.
Какие преимущества мы получаем:
— ускоряется вывод минимального жизнеспособного продукта (Minimum Viable Product) на рынок;
— сокращается время на: генерацию каркаса приложения, модели классов, базы данных;
— постоянно обновляемая документация;
— для участников проекта диаграммы намного нагляднее кода.
Минусы:
— для внедрение MMD потребуется использовать специальные программные решения, такие как Rational Software Architect, Simulink или Sirius;
— от программистов требуются внушительные знания проектирования диаграмм;
— значительные финансовые затраты на интеграцию данной методологии.
PDD — Panic Driven Development
Если вы пробовали методологии agile разработки, то вы наверняка пробовали и PDD. Давайте посмотрим более подробно, каковы принципы этой методологии.
Новые задачи приоритетнее старых
Всякий раз, когда в середине спринта появляется новая проблема, она имеет приоритет над любой запланированной работой. Новое всегда лучше и имеет более высокий приоритет. Странно, почему это не стало одним из принципов гибкой разработки? Нацеленность на обеспечение ценности для клиента требует, чтобы команда заботилась о новых фичах и откладывала ранее определенную работу.
Пишите столько кода, сколько нужно, чтобы решить проблему
Разработчики пишут код для жизни. Ошибки могут быть исправлены только кодом. Обсуждение дизайна и UX может только замедлить разработку. Но мы же не хотим терять драгоценное время? Сначала напишите решение, потом проверьте своё предположение по исправлению. Если исправление работает, проблема решена.
Тесты должны писаться в конце
После того, как исправление внедрено, тесты могут быть запланированы как задача, которая будет сделана в будущем. Тесты полезны, но не являются приоритетными. Вы можете позаботиться о них позже. Ручного тестирования должно быть достаточно, чтобы доказать работоспособность реализованного решения.
Доверьтесь своему инстинкту
Программирование — это искусство. Искусство имеет внутреннюю инстинктивную составляющую. Доверься своей интуиции. Напишите код. Разверните его. Только смелым улыбается удача.
Процесс гибок
Любой процесс, созданный для разработки, тестирования и выпуска программного обеспечения, — это просто набор соглашений и правил, которые не высечены в камне. Критические исправления требуют разных подходов. Ожидается, что вы согнёте процесс, чтобы выполнить задачу в срок, если этого требует бизнес.
Это процесс, управляемый менеджером
Как часть одной команды, менеджеры имеют право высказать свое мнение по вопросам развития. Рефакторинг или передовой опыт могут и должны быть отменены потребностями бизнеса. Инженеры могут высказать свое мнение, но они должны в конечном итоге принять любые потребности, которые приходят сверху.
Плюсы подхода:
— высокая скорость разработки;
— дешево;
— заказчики счастливы, что наконец-то нашли толковых разработчиков.
Минусы:
— все плюсы разобьются о технический долг и сложность проекта.
PDD своеобразный антипаттерн разработки, который, к сожалению, мы все время от времени практикуем.
В этом тексте приводится набор принципов, которые должен знать любой разработчик, и которые следует периодически освежать в памяти. Считайте их своим секретным оружием при программировании.
Последовательное применение этих принципов упростит ваш переход от миддла к сеньору. Вы можете обнаружить, что некоторые (вероятно) вы применяете интуитивно.
Принципов много. Мы остановимся на семи самых важных. Их использование поможет вам в развитии и позволит стать лучшим программистом.
1. YAGNI
You Aren’t Gonna Need It / Вам это не понадобится
Этот принцип прост и очевиден, но ему далеко не все следуют. Если пишете код, то будьте уверены, что он вам понадобится. Не пишите код, если думаете, что он пригодится позже.
Этот принцип применим при рефакторинге. Если вы занимаетесь рефакторингом метода, класса или файла, не бойтесь удалять лишние методы. Даже если раньше они были полезны – теперь они не нужны.
Может наступить день, когда они снова понадобятся – тогда вы сможете воспользоваться git-репозиторием, чтобы воскресить их из мертвых.
2. DRY
Don’t Repeat Yourself / Не повторяйтесь
Эта концепция была впервые сформулирована в книге Энди Ханта и Дэйва Томаса «Программист-прагматик: путь от подмастерья к мастеру».
Идея вращается вокруг единого источника правды (single source of truth — SSOT). Что это вообще такое?
В проектировании и теории информационных систем единый источник истины (SSOT) – это практика структурирования информационных моделей и схемы данных, которая подразумевает, что все фрагменты данных обрабатываются (или редактируются) только в одном месте… SSOT предоставляют достоверные, актуальные и пригодные к использованию данные.
Использование SSOT позволит создать более прочную и понятную кодовую базу.
Дублирование кода – пустая трата времени и ресурсов. Вам придется поддерживать одну и ту же логику и тестировать код сразу в двух местах, причем если вы измените код в одном месте, его нужно будет изменить и в другом.
В большинстве случаев дублирование кода происходит из-за незнания системы. Прежде чем что-либо писать, проявите прагматизм: осмотритесь. Возможно, эта функция где-то реализована. Возможно, эта бизнес-логика существует в другом месте. Повторное использование кода – всегда разумное решение.
3. KISS
Keep It Simple, Stupid / Будь проще
Этот принцип был разработан ВМС США в 1960 году. Этот принцип гласит, что простые системы будут работать лучше и надежнее.
У этого принципа много общего с переизобретением колеса, которым занимались в 1970-х. Тогда он звучал как деловая и рекламная метафора.
Применительно к разработке ПО он значит следующее – не придумывайте к задаче более сложного решения, чем ей требуется.
Иногда самое разумное решение оказывается и самым простым. Написание производительного, эффективного и простого кода – это прекрасно.
Одна из самых распространенных ошибок нашего времени – использование новых инструментов исключительно из-за того, что они блестят. Разработчиков следует мотивировать использовать новейшие технологии не потому, что они новые, а потому что они подходят для работы.
4. Big Design Up Front
Глобальное проектирование прежде всего
Этот подход к разработке программного обеспечения очень важен, и его часто игнорируют. Прежде чем переходить к реализации, убедитесь, что все хорошо продумано.
Зачастую продумывание решений избавляло нас от проблем при разработке… Внесение изменений в спецификации занимало час или два. Если бы мы вносили эти изменения в код, на это уходили бы недели. Я даже не могу выразить, насколько сильно я верю в важность проектирования перед реализацией, хотя адепты экстремального программирования предали эту практику анафеме. Я экономил время и делал свои продукты лучше, используя BDUF, и я горжусь этим фактом, чтобы там ни говорили фанатики экстремального программирования. Они просто ошибаются, иначе сказать не могу.
Многие разработчики считают, что если они не пишут код, то они не добиваются прогресса. Это неверный подход. Составив план, вы избавите себя от необходимости раз за разом начинать с нуля.
Иногда в недостатках и процессах разработки архитектуры должны быть замешаны и другие люди. Чем раньше вы все это обсудите, тем лучше будет для всех.
Очень распространенный контраргумент заключается в том, что стоимость решения проблем зачастую ниже стоимости времени планирования. Чем с меньшим количеством ошибок столкнется пользователь, тем лучше будет его опыт. У вас может не быть другого шанса справиться с этими ошибками.
5. SOLID
Это наиболее известный принцип разработки ПО. Solid — это аббревиатура от:
S) Single-responsibility principle /Принцип единственной ответственности
Его важность невозможно переоценить. Каждый объект, класс и метод должны отвечать только за что-то одно. Если ваш объект/класс/метод делает слишком много, вы получите спагетти-код. Вот пример:
Этот метод кажется безобидным, но на самом деле он делает слишком много:
— Сохраняет объект
— Обрабатывает уведомление в UI
— Выполняет навигацию
Еще один побочный эффект такого кода – проблемы с тестированием. Запутанный функционал тестировать сложно.
O) Open–closed principle / Принцип открытости-закрытости
Программные объекты должны быть открыты для расширения, но закрыты для модификации. Речь о том, что нельзя переопределять методы или классы, просто добавляя дополнительные функции по мере необходимости.
Хороший способ решения этой проблемы – использование наследования. В JavaScript эта проблема решается с помощью композиции.
Простое правило: если вы изменяете сущность, чтобы сделать ее расширяемой, вы впервые нарушили этот принцип.
L) Liskov substitution principle / Принцип подстановки Лисков
Этот принцип гласит, что объекты старших классов должны быть заменимы объектами подклассов, и приложение при такой замене должно работать так, как ожидается.
I) Interface segregation principle / Принцип разделения интерфейсов
Этот принцип был сформулирован Робертом Мартином, когда он консультировал Xerox, и он очевиден.
Объекты не должны зависеть от интерфейсов, которые они не используют
ПО должно разделяться на независимые части. Побочные эффекты необходимо сводить к минимуму, чтобы обеспечивать независимость.
Убедитесь, что вы не заставляете объекты реализовывать методы, которые им никогда не понадобятся. Вот пример:
Не все животные могут fly, walk или swim, поэтому эти методы не должны быть частью интерфейса или должны быть необязательными.
D) Dependency inversion principle / Принцип инверсии зависимостей
Этот принцип невозможно переоценить. Мы должны полагаться на абстракции, а не на конкретные реализации. Компоненты ПО должны иметь низкую связность и высокую согласованность.
Заботиться нужно не о том, как что-то устроено, а о том, как оно работает. Простой пример – использование дат в JavaScript. Вы можете написать для них свой слой абстракции. Тогда если у вас сменится источник получения дат, вам нужно будет внести изменения в одном месте, а не в тысяче.
Иногда добавление этого уровня абстракции требует усилий, но в конечном итоге они окупаются.
В качестве примера взгляните на date-io, в этой библиотеке создан тот уровень абстракции, который позволяет вам использовать её с разными источниками дат.
6. Avoid Premature Optimization
Избегайте преждевременной оптимизации
Эта практика побуждает разработчиков оптимизировать код до того, как необходимость этой оптимизации будет доказана. Думаю, что если вы следуете KISS или YAGNI, вы не попадетесь на этот крючок.
Поймите правильно, предвидеть, что произойдет что-то плохое – это хорошо. Но прежде чем вы погрузитесь в детали реализации, убедитесь, что эти оптимизации действительно полезны.
Очень простой пример – масштабирование. Вы не станете покупать 40 серверов из предположения, что ваше новое приложение станет очень популярным. Вы будете добавлять серверы по мере необходимости.
Преждевременная оптимизация может привести к задержкам в коде и, следовательно, увеличит затраты времени на вывод функций на рынок.
Многие считают преждевременную оптимизацию корнем всех зол.
7. Бритва Оккама
Бри́тва О́ккама (иногда ле́звие О́ккама) — методологический принцип, в кратком виде гласящий: «Не следует множить сущее без необходимости» (либо «Не следует привлекать новые сущности без крайней на то необходимости»).
Что это значит в мире программирования? Не создавайте ненужных сущностей без необходимости. Будьте прагматичны — подумайте, нужны ли они, поскольку они могут в конечном итоге усложнить вашу кодовую базу.
Эти принципы не очень сложны. На самом деле, именно простота делает их красивыми. Если вы сбиты с толку, не пытайтесь применять все их сразу. Просто постарайтесь работать осознанно и пробуйте постепенно включать эти принципы в свой рабочий процесс.
Использование базовых, но действенных принципов позволит вам стать лучшим программистом и иметь более четкое представление о том, почему вы что-то делаете.
Если вы применяете большую часть принципов интуитивно, стоит задумываться и осознавать почему вы делаете что-то определенным образом.
Вот это лютый бред и трешак, который привёл к монолитизации и колоссальному увеличению связанности и мешает людям подняться на ступень выше в написании качественного кода. С ним возятся до сих пор, хотя больше плохого, чем хорошего. Ну при условии что вы не мамкин сайт домашний пишите, а приложение миллионов на 5-7 строк кода. Он актуален исключительно в среде теоретиков и джунов, чтобы последние не копипастили один и тот же код в разных классах.
На практике, люди, упоротые этим принципом и не знающие других подходов с огромной болью живут в огромном монолитие с единой dll типа DAL единой dll типа DomainModel и т.д.
Всё это таскается из одного проекта в другой, шарится между десятками сервисов и апи и потом распилить такое на микро сервисы просто невозможно, точнее бизнес не хочет. Цена поддержки растёт кратно. Зато без копирования, ага.
Как нужно делать:
1. Не копировать код в рамках 1 класса и одной, при возможности одной dll.
2. Делать всё в рамках одной фичи. А ля микросервис. Это означает что нет никаких папок с кучей разных репозиотриев а ля Reposotories/AccountRepository и тут же Reposotories/OrdersRepository. А есть 2 фичи (Accounts/ Orders/) внутри которых есть такие репо (Accounts/AccountRepo, Accounts/AccountFactory, Orders/OrderRepo...). В будущем это позволит разделить контексты И если вдруг фиче про ордера нужен доступ к данным из аккаунта, то да, копипастится логика хоть полностью и делается свой репо (Orders/AcountForOrdersRepo… ). Менять её придётся разве что раз в 1000 лет. А вот поддерживать и менять в рамках одной фичи — сколько угодно раз. И нафига тогда нужен такая связанность с Account фичей? Нет уж.
3. По мере разрастания кода — разносить вообще в разные библиотеки (контексты) и репозитории.
А DRY на помойку.
Прежде чем переходить к реализации, убедитесь, что все хорошо продумано.
Это тоже теоретическая чушь, которая на практике сводится к:
1) мы уже делали такое и знаем что примерно нужно сделать ещё раз. Тогда проблемы нет.
2) мы ещё не делали такое и хз что нас ждёт. В этом случае ничего не поможет, ничего не угадать. Например мы на своём проекте несколько лет использовали singlar для для работы множества клиентов с сервером и сервер с очередью через RebbitMQ. В итоге отказались от подхода, как нестабильного, перешли на realtime запрос-ответ. Угадать заранее, фактически без прототипа в продакшене такое было невозможно.
Что же на самом деле лучше сделать в таком случае?
а) Изучить максимум инфы по данной технологии.
б) делать простые небольшие изолированные куски. Потом с увеличением их числа вовремя рефакторить и объединять в контексты. Постоянный рефакторинг — только он поможет избежать факапа. А рефакторинг подразумевает поднятие на уровень выше в архитектуре и её пересмотр в том числе. Когда время пришло.
SOLID
Вот это must have и за его нарушение (чаще всего S) увольнять к чертям. Оно хоть как-то спасает от связанности и роста проблем.
Не создавайте ненужных сущностей без необходимости.
Очередной теоретический бред для джунов, наверное. Сущности всегда создаются в зависимости от контекста и бизнеса. Если у тебя 5 вариантов работы с ордерами и в одном случае нужны одни поля, а в другом — другие и только id + name общие, то это разные сущности. И их нужно создавать. А не гонять одну God object по всему домену. Увеличивая связанность. Если тебе нужно вернуть объект в виде json то не нужно возвращать сущность из предметной области. Пусть она хоть 1 в 1 пока совпадает с DTO объектом. Ключевое слово тут «пока» совпадает.
Фаулер и Макконели верно говорят, что самое дорогое — поддержка. А поддержка дорожает с увеличением сложности. А сложность в том числе берётся и от связанность, из-за невозможности просто удалить и заново переписать кусок. А вдруг кому-то что-то сломает?!
Солид противоречит ягни, драй и кису. То есть конечно, иногда они успешно сосуществуют в некоторых местах. Но есть достаточно слуачев когда надо выбирать. И я агитирую за выбор солида.
не совсем так думаю про:
Не создавайте ненужных сущностей без необходимости.
мне всегда казалось это о другом
Например я работал как-то в одной команде с отличным матиматиком (притворяющимся программистом ;) очень не плохо в целом) который каждую маломальскую сущнусь стремился усложнить по максимому.
Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data
и так со всеми остальными, тоесть в среденм в его коде по сравнению со всеми остальными было почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно. Но я всегда впоминал именно этот принцип и его ужасное нарушение. Может я конечно что-то не так понял. ;)
Сложно угадать что вы имели введу, но возможно то, что математик пытался бежать впереди поровоза в духе «я знаю что это потом понадобиться». Не, это неправильно, это зло.
Но, если у нас предметная область различается хоть на 1 поле, тогда:
Сущность user уже с первых строк кода могла быть реализовнана как целая домення область из user-core, user-address, credentials, user audit, connected apps, payment data
Это правильно. Хороший контекст и домен превыше всего. Вообще всего. Потому что это залог:
1. минимизации ошибок в реализации
2. минимизации скрытых ошибок и сайд-эффектов
3. возможности передать код след. разработчику, и позволить ему разобраться в нём так, что тот выполнит п.1. и 2.
Можно жить с низкой производительностью — её можно улучшить. Можно жить с техническими багами реализации или недоделками (ну типа нет 100500 валидации на такое-то условие) — их можно исправить. Нельзя существовать с продуктом, которые делает не то, что нужно, да ещё и скрыто. И при этом не позволяет себя исправить ( например исправление только за счёт костылей, что вносит сумятицу и сайд-эффекты. разраб уволился, с ним и знание «а почему так», а код и контекст не говорят почему)
Но конечно, заготовки делать на случай просматривающегося контекста — это тоже зло. Разработка и развитие предметной области сродне лепки из пластилина или глины (обратное резьбе по камню): меся обрастает, потом переосмысление, рефакторинг всего. Если есть опыт, то рефакторинг проходит легко. Если говнокодили в начале, то с болью. Но нужно развивать доменную область, которая отображает фактическую модель систему — а не:
а) изначально запланированную, но которая оказалось избыточной\недоделанной
б) изначально незапланированную, но вылепленную без «развития», а потому таскающую за собой кучу легаси свойств и зависимостей из других контекстов, которые поленились создать\не поняли что надо создать.
почемуто раз в 5 больше ненужных усложнений в виде сущностей.
Слава Богу его можно было убедить словами и рефакторинг он не воспринимал болезненно.
Ну это и есть то самое развитие. Насоздавал. Понял что 5 из 8 сущностей лишние или дубли — удалил. Это норма.
Если рефакторинг перед началом каждой новой задачи, во время изменения куска кода или фикса бага то и нет проблем с поступательным развитием. А если рефакторинг — это плановая задача «вернуть тех. долг», то всё, считай нет и не будет его никогда.