А потом люди начитаются что так стоит делать, и как раз так и лепят. Я видел очень много кода, где паттерны применены в простых местах и вообще нужны, а там где правда надо было подумать, разработчика уже не хватило, и там совсем странные дела происходят. Вообще кода, в котором паттерны применены адекватно задаче весьма мало, обычно их везде лепят, потому что это «круто» и «технологично».
Инфраструктура кода, которая обспечивает «красивую» поддержку кода обычно может занимать места больше чем сам эффективный код, а ведь ее тоже надо поддерживать. Применение современных модных паттернов порой приводит к несоразмерному раздуванию кода, а значит к повышению вероятности ошибок. Также больший объем кода требует больше тестирования, а если это юнит-тестирование, то дополнительного времени разработчиков. При том что юнит тесты ничего не гарантируют.
И возникает вопрос, что лучше: 100 строк простого кода без тестов или 1000 строк кода покрытого тестами. У меня нет однозначного ответа на этот вопрос, но лично мне приятнее первый вариант.
Также не стоит забывать о вопросах производительности, конечно это не всегда самое важное, но современные тенденции запуска хелоуворлда на кластерах несколько удивляют.
И поясню свое мнение, почему я так считаю.
Создание интерфейса избыточно, так код изначально проектируется под SMTP. То есть по факту добавляя интерфейс, мы не даем сильно больше возможностей для расширения (мы вообще тупо копируем интерфейс SMTP), но идеологически уже привязываемся к интерфейсу. Далее этот интерфейс пойдет дальше в код, и может возникнуть ситуация, когда появится какой то принципиально новый мессенджер, ну вот допустим телеграм, и мы захотим писать в него, а не в почту. Получится, что придется делать рефакторинг (а это бесполезная с точки зрения бизнеса работа) или отказаться от нового решения. С куском «говнокода» проще, его просто удалил и поставил что-то новое. Далее IoC и контейнеры это уже следствие неуместного применения интерфейсов.
Проблема в проектировании интерфейсов заключается в излишнем тщеславии программистов, которые считают, что смогут предусмотреть все на будущее, но чаще всего я вижу, как люди потом рвут волосы и делают рефакторинг всего проекта.
При «модульно-костыльной» архитектуре нет сильной привязки к уже существующему коду, и можно по идее написать нечто произвольное, что наиболее точно подойдет заказчику прямо полностью. И не будет проблем с тем, что либо что-то будет делаться урезано, чтобы влезть в интерфейс, или вообще завернуто на этапе принятия решения.
Предлагаемый Вами подход может иметь смысл, если рядом сидит человек, знающий будущее, который скажет что сразу предусмотреть в интерфейсе. Но я вот таких не видел…
По моему мнению код в самом начале статьи наиболее адекватен для решения поставленной задачи.
Введение интерфейсов, IoC и депенденси контейнера избыточны для конкретного случая
А юнит тест сможет ответить лишь на вопрос, сможет ли полностью изолированный класс дернуть команду мока почтового сервиса. На вопросы почему было дернуто слишком много и мало раз в боевом окружении он вряд ли ответит.
И такой подход с пиханием паттернов куда не попадя приводит к тому что приложение разрабатывается слишком долго, работает так-же. Но конечно у таких приложений бывают и преимущества, ведь хелло ворлд почти не тормозит, и ему хватит всего 86гб памяти.
А чем неуместное использование паттернов это не решение в лоб? Единственное что мне приходит на ум почему оно не в лоб, это потому что оно через ***у :)
А серьезный проект это какой? Когда пишется сложный продукт в сжатые сроки с реализацией всех бизнес потребностей и который в итоге работает как этого хочет клиент, или долгий проект у аутсорсера на несколько лет, где можно с умным видом ковырять в носу, переносить сроки и ленивенько писать юниттесты?
Клевая идея, совершенно честно. У нее есть только одна проблема: время, необходимое на то, чтобы проверить, что обработка заказа рассылает все 18 нужных писем в разных сценариях. Даже если это автоматизировать (включая работу с почтовым ящиком), все равно будет небыстро. А юнит-тест проверяет это за секунды, и каждый раз, при каждом билде.
А тут зависит от архитектуры. Если есть сервер приложений, то логично организовать заполнение им очереди на отправку и отдельного демона на саму задачу отправки. Протестировать заполнение очереди можно автоматизированно и комплексно, а то, что демон может отправить сообщение — это и так видно, в 3 строках кода сложно ошибиться.
Так мы получим нужное решение, которое кроме всего прочего декомпозировано (сервер приложений и демон), транзакционно (если приложение упадет, то почта не будет отмечена как отправленная и не потеряется) и простое (несколько модулей, которые может написать и поддерживать даже школьник).
Я не говорю, что код надо писать одной функцией на миллион строк. Или что паттерны это зло, их вообще использовать не стоит. Но придумывать синтетические ситуации для того, чтобы использовать паттерн, потому что это круто — вещь очень сомнительная. Стоит понимать, для чего пишется проект, какие у него, нужен ли он заказчику, или это «русский бизнес».
Но что я заметил для себя, что обычно если проект делается для того, чтобы он работал, то заказчику наиболее важны сроки, бюджет и адаптированность решения для него. Я не думаю, что он будет очень рад, если узнает, что за его деньги реализовали возможность отправки емейлов с дискеты, работы сразу со всеми существующими базами данных в ущерб специфическим фишкам конкретного решения и еще какой нибудь мокрой мечты гуру абстракции.
Насчет IoC это не плохо и не хорошо. Это один из инструментов, и если он будет использован уместно, а продукт делался с умом, то на выходе получится хороший результат. Так же как использование IoC ну никак не гарантирует то, что проект будет хоть сколько либо успешным. Это как говорить что раз стул был сделан молотком, значит он хороший, и если все остальное делать молотком, то это тоже хорошая практика. Но если использовать молоток вместо пилы, потому что пила это не модно, то результат может быть произвольным.
Насчет мира PHP, достаточно сложно говорить на его примере вообще о чем либо. Это достаточно неплохой язык, на котором можно при желании делать красивые, качественные и отличные решения. Но изначально этот язык проектировался как перл для домохозяек, и обладает крайне низким порогом для вхождения, что делает с одной стороны его простым и легким в изучении, а с другой стороны притягивает к себе начинающих программистов, не обладающих достаточным опытом и практикой для того, чтобы оценить адекватность и применимость подхода и решения. Поэтому они начинают бездумно использовать то, что сейчас модно и наиболее афишируется, то есть всякие иоки, юнит тесты и контейнеры, и в итоге не понимают, что делают не совсем то. Но опыта для sanity check своего решения у них пока еще нет, он будет позже
Запустить и проверить? Или Вы искренне считаете, что если сервис будет работать на моке, то он 100% заработает в реальном боевом окружении? Попробуйте мыслить чуть дальше, чем своим кодом. Не только программой, но еще и всем стеком, а также прилегающей инфраструктурой. И окажется, что написать такой юнит-тест, который все учтет, может оказаться очень проблематичным. А также это может вселить ложную уверенность в том, что раз код протестирован, то он работает. А на самом деле юнит тест будет проверять ту логику, которая предполагалсь. А то что программист упустил в своем коде, он упустит и в тесте, так как просто не думал об этом
Отличный пример, как из простого куска кода, который пишется за несколько минут, сделать огромную структуру, увеличить количество кода в разы, и тем самым снизить его надежность, поддерживаемость и простоту, а также повысить косты на разработку ПО.
Наглухо завязались на SMTP? Ужас то какой. А что, сейчас используется еще что-то? Что, в будущем появится еще какой-то протокол? У него будет точно такой же интерфейс? Уверены? Точно, точно не придется переделывать все приложение, потому что интерфейс мейлера просто не был предусмотрен для чего-то совсем нового?
Или может быть источник данных из БД вдруг надо будет заменить на лоулевел драйвер флоппика? Серьезно?
Все, что тут описано, это борьба очень средненького программиста с самим собой и получение им удовольствия от того, что он использовал паттерн, хоть и не к месту, сделал интерфейс, а интерфейсы повышают ЧСВ, это факт, ну и бахнул ИОК по приколу.
А может быть просто стоит написать простейший код без усложнений, а если он устареет, выкинуть его целиком и написать новый опять за несколько минут?
Так намного интереснее, я бы поставил этот ролик вообще первым делом.
На видео приведены примеры, как Лекси отвечает на сильно контекстно-зависимые вопросы: «какая у меня сегодня норма» и т.п. Как он понимает, в каком контексте нужно отвечать? Он правда *настолько* умный, что понимает, что с ним происходит, и что творится вокруг, как например, что девушка положила в еду один ингридиент, и следует положить следующий, или это все таки на видео показан небольшой «маркетинг»?
Рассказали бы немного в посте о том, что это вообще за проект и что он делает…
А то в посте есть только унылый получасовой видос о том, как оно устроено, и описание печенек на выставке. А по самому проекту вообще не понятно что это. Очень хотелось бы увидеть короткий «рекламный» видос о том, что же это все таки за робот
И возникает вопрос, что лучше: 100 строк простого кода без тестов или 1000 строк кода покрытого тестами. У меня нет однозначного ответа на этот вопрос, но лично мне приятнее первый вариант.
Также не стоит забывать о вопросах производительности, конечно это не всегда самое важное, но современные тенденции запуска хелоуворлда на кластерах несколько удивляют.
Создание интерфейса избыточно, так код изначально проектируется под SMTP. То есть по факту добавляя интерфейс, мы не даем сильно больше возможностей для расширения (мы вообще тупо копируем интерфейс SMTP), но идеологически уже привязываемся к интерфейсу. Далее этот интерфейс пойдет дальше в код, и может возникнуть ситуация, когда появится какой то принципиально новый мессенджер, ну вот допустим телеграм, и мы захотим писать в него, а не в почту. Получится, что придется делать рефакторинг (а это бесполезная с точки зрения бизнеса работа) или отказаться от нового решения. С куском «говнокода» проще, его просто удалил и поставил что-то новое. Далее IoC и контейнеры это уже следствие неуместного применения интерфейсов.
Проблема в проектировании интерфейсов заключается в излишнем тщеславии программистов, которые считают, что смогут предусмотреть все на будущее, но чаще всего я вижу, как люди потом рвут волосы и делают рефакторинг всего проекта.
При «модульно-костыльной» архитектуре нет сильной привязки к уже существующему коду, и можно по идее написать нечто произвольное, что наиболее точно подойдет заказчику прямо полностью. И не будет проблем с тем, что либо что-то будет делаться урезано, чтобы влезть в интерфейс, или вообще завернуто на этапе принятия решения.
Предлагаемый Вами подход может иметь смысл, если рядом сидит человек, знающий будущее, который скажет что сразу предусмотреть в интерфейсе. Но я вот таких не видел…
Введение интерфейсов, IoC и депенденси контейнера избыточны для конкретного случая
А тут зависит от архитектуры. Если есть сервер приложений, то логично организовать заполнение им очереди на отправку и отдельного демона на саму задачу отправки. Протестировать заполнение очереди можно автоматизированно и комплексно, а то, что демон может отправить сообщение — это и так видно, в 3 строках кода сложно ошибиться.
Так мы получим нужное решение, которое кроме всего прочего декомпозировано (сервер приложений и демон), транзакционно (если приложение упадет, то почта не будет отмечена как отправленная и не потеряется) и простое (несколько модулей, которые может написать и поддерживать даже школьник).
Но что я заметил для себя, что обычно если проект делается для того, чтобы он работал, то заказчику наиболее важны сроки, бюджет и адаптированность решения для него. Я не думаю, что он будет очень рад, если узнает, что за его деньги реализовали возможность отправки емейлов с дискеты, работы сразу со всеми существующими базами данных в ущерб специфическим фишкам конкретного решения и еще какой нибудь мокрой мечты гуру абстракции.
Насчет IoC это не плохо и не хорошо. Это один из инструментов, и если он будет использован уместно, а продукт делался с умом, то на выходе получится хороший результат. Так же как использование IoC ну никак не гарантирует то, что проект будет хоть сколько либо успешным. Это как говорить что раз стул был сделан молотком, значит он хороший, и если все остальное делать молотком, то это тоже хорошая практика. Но если использовать молоток вместо пилы, потому что пила это не модно, то результат может быть произвольным.
Насчет мира PHP, достаточно сложно говорить на его примере вообще о чем либо. Это достаточно неплохой язык, на котором можно при желании делать красивые, качественные и отличные решения. Но изначально этот язык проектировался как перл для домохозяек, и обладает крайне низким порогом для вхождения, что делает с одной стороны его простым и легким в изучении, а с другой стороны притягивает к себе начинающих программистов, не обладающих достаточным опытом и практикой для того, чтобы оценить адекватность и применимость подхода и решения. Поэтому они начинают бездумно использовать то, что сейчас модно и наиболее афишируется, то есть всякие иоки, юнит тесты и контейнеры, и в итоге не понимают, что делают не совсем то. Но опыта для sanity check своего решения у них пока еще нет, он будет позже
Наглухо завязались на SMTP? Ужас то какой. А что, сейчас используется еще что-то? Что, в будущем появится еще какой-то протокол? У него будет точно такой же интерфейс? Уверены? Точно, точно не придется переделывать все приложение, потому что интерфейс мейлера просто не был предусмотрен для чего-то совсем нового?
Или может быть источник данных из БД вдруг надо будет заменить на лоулевел драйвер флоппика? Серьезно?
Все, что тут описано, это борьба очень средненького программиста с самим собой и получение им удовольствия от того, что он использовал паттерн, хоть и не к месту, сделал интерфейс, а интерфейсы повышают ЧСВ, это факт, ну и бахнул ИОК по приколу.
А может быть просто стоит написать простейший код без усложнений, а если он устареет, выкинуть его целиком и написать новый опять за несколько минут?
На видео приведены примеры, как Лекси отвечает на сильно контекстно-зависимые вопросы: «какая у меня сегодня норма» и т.п. Как он понимает, в каком контексте нужно отвечать? Он правда *настолько* умный, что понимает, что с ним происходит, и что творится вокруг, как например, что девушка положила в еду один ингридиент, и следует положить следующий, или это все таки на видео показан небольшой «маркетинг»?
А то в посте есть только унылый получасовой видос о том, как оно устроено, и описание печенек на выставке. А по самому проекту вообще не понятно что это. Очень хотелось бы увидеть короткий «рекламный» видос о том, что же это все таки за робот