Comments 11
Если позволяет приложение, то создание собственного DSL для него решает множество проблем, обозначенных в статье. В моем случае это стало палочкой выручалочкой уже на лет 6, когда введение новых фич означало только доработку или создание новых примитивов на придуманном для этого DSL, что в общем не было слишком сложно и затратно. Ну и архитектура, которая позволяет протестить быстро, незатратно и независимо новые фичи.
Хотелось бы почитать про ваш опыт с dsl поподробнее. Интересно что за продукт и как он развивался со временем.
Вот прямо обратный опыт имею, сказал бы я... Всякий раз когда кто-то изобретает специфичный язык конфигурации или расширений - это каждый раз кончается тьюринг-полным языком программирования (с условиями, циклами, и т.д.) - но без нормальной инструментальной поддержки базового языка (ни тебе отладчика, ни тебе профайлера). Плюс порог для входа - нельзя просто нанять программиста на Java/C#/C++ - надо научить его синтаксису и идиомам нового встроенного языка. Потому что каждый из этих новоизобретенных языков уникален, и опыт работы с ним есть у пяти человек во всем мире...
Так необязательно писать интерпретатор нового языка. Можно использовать базовый язык, макрорасширяемый в DSL.
Тогда кто мешает сделать достаточно высокоуровневые абстракции (классы, функции, и т.д.), и ими выражать логику прямо на базовом языке ? Но в целом, это конечно лучше чем полностью отделенный DSL. Хотя в той же джаве макросов нет как класса...
Граница между DSL и высокоуровневой абстракцией базового языка вообще довольно условна. Но обычно за DSL берутся, когда для описания предметной области неудобна сама парадигма языка программирования (например, неочевиден порядок вычисления). Например, конструкции DSL часто бывают декларативными. Это требует какой-то обёртки для вызовов функций/методов.
Ну во первых не во всех областях разработки это имеет смысл и конкретно я думаю что в WEB это нереально. Мой опыт в разработке такой системы относится к специфической нишевой области создания MES систем в двухзвенной схеме. Я описал это в своей статье здесь на хабре, она доступна в моем профиле. Возможно такое можно и в других областях использовать. В моем случае это просто попадание в точку, так как одна система должна поддерживать свою область и быть легко расширяема в области программирования и операторов DSL. Отладка без проблем, когда поддерживается пошаговый режим работы + переход на произвольную строку. Но клиент в этом случае только интерпретатор с загрузкой программы DSL построчно и вся бизнес логика в хранимых процедурах на сервере.
нет смысла загадывать наперёд и усложнять дизайн под гипотетические требования. Лучше сделать минимальное работающее решение сегодня и улучшать его по мере поступления новых требований
Yagni вроде не про дизайн, а про функциональность? Не надо лишних функций не тождественно давайте будем считать, что сеть не падает, например.
Что не устраевает лично меня во всех этих драях и кисах, так это то, что рядом с ними всегда политиканство и беда) К примеру mvp - ок, но не тащите демо в прод под видом mvp, а если это реально mvp, то вы, большие начальники, не делайте больших глаз узнав, что там половина внутренностей лишь в проекте.
У нас один "большой" архитектор заложил "простое" решение в георедандаси, хотя его предупреждали, что нельзя так делать. Он воспользовался адм весом, продемонстрировал знание этих всех сокращений и выпустил это всё в продакшен. Когда совпали условия, продакшен лёг как никогда глобально, пару суток его чинили а потом делали патч.
Ну и ещё одна иллюстрация - допустим одну и ту же задачу решают девелоперы с разной экспертизой и оба руководствуются стремлением избежать оверинженеринга. Посчитает ли тот, у кого экспертиза меньше, код второго избыточным?)
Yagni вроде не про дизайн, а про функциональность?
Строго говоря да, но в реальной разработке граница размывается и я не отделяю их.
В целом, суть не в простоте кода, а в том, каких усилий будет стоить переделка и какие риски она повлечёт. Если кто-то заложил "простое" решение, а переделать его сложно, то они уже и не такое простое.
допустим одну и ту же задачу решают девелоперы с разной экспертизой
Они могут оба оказаться неправы, независимо от экспертизы.
В статье все по делу.
Единственное что - я бы добавил рядом с дублированием ещё один пункт - не бойтесь писать одноразовый код, и выбрасывать его при изменении логики.
Часто видел в проектах - где есть уже хорошая, устойчивая к изменениям, декомпозированы архитектура, ситуации - когда ради например экрана ошибки (цель которого вывести одну строку) - вместо "скинуть все в кучу в одном классе за 5 минут" - выстраиваются все слои абстракции, слабой связности и прочего (на что тратился целый день). А потом все это ржавело, а в худшем случае ещё и требовало поддержки, при том, что продуктовая логика никогда не менялась.
Я бы вообще добавил это как паттерн - пишешь класс, который не должен эволюционировать. Прямо быстро, прямо спагетти кодом с прямыми вызовами (задуман на выброс) - отмечаешь его аннотацией trash, и в регламенте запрещаешь вносить в этот код любые усложнения.
Зачастую написанный "говнокодом" класс может просуществовать весь цикл жизни приложения и так и не потребовать его прочитать.
В принципе это сходится с пунктом статьи про непредугадывание, но все же немного про другое.
Код, не боящийся изменений