«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2021/12/15 21:11:38  №2238692 1
14464101896490.jpg (205, 1280x1024)
1024x1280
Как не тонуть в своём же коде на сложных проектах?

Да, я знаю, что существуют паттерны. Я могу объяснить на собеседовании, что такое синглтон и зачем он нужен. И про солид знаю. И "Чистый код" читал. Но когда пишу реальный код, то быстро в нём вязну. Когда ТЗ меняется в процессе и теперь нужно где-то в потрохах кода добавлять лишнюю проверку, и в зависимости от результата скорректировать работу ниже и выше(!) этого участка. Появляются какие-то магические числа, в параметры функций уходят уже по 6-8 переменных, и так далее. Код становится монструозным и его тяжело "загружать в мозг", чтобы погонять чисто там. Всё чаще приходится писать строчку и смотреть, чего будет. Хорошо - ну ок, пишем следующую. Не получилось? Ну, попробуем тут тип данных изменить, может в этом проблема? А, нет, проверка на ноль. Тоже нет. Так, что там вообще эта хуйня возвращает? Инт, но может и false. Или перехватить сразу эксепшен и стринг выдать... Таааак, падажжи, ёбана...
Ответы: >>2238785 >>2238999 >>2239025
Аноним 2021/12/16 02:39:07  №2238785 2
>>2238692
Поздравляю. Вот ты и добрался до дна пхп. Если ответить на твой вопрос коротко, то НИКАК.

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

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

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

Отсюда же растет раскладывание кода по папочкам. Своими глазами видел как два чела под сорок лет до хрипоты спорили в какую папочку класс положить - в домен или в инфраструктуру. А какая хуй разница если потом ни там ни там не найдешь его.

И это все еще покрывается тестами. Вайтбокс тестами на моках. Пернул в коде - двадцать тестов отвалилось. Не потому что в коде ошибка, а просто их теперь переписать надо. А без тестов проект не соберется и в прод не попадет. Все на серьезном ебале - безопасность ебать. Только баги по кд от ТП сыпятся. И нахуя эта тысяча тестов с их постоянными false positive нужна хуй его знает.

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

Ответы: >>2238999 >>2239158
Аноним 2021/12/16 09:34:46  №2238999 3
>>2238692
>ТЗ меняется в процессе и теперь нужно где-то в потрохах кода добавлять лишнюю проверку
Когда ТЗ меняется "на горячую", то запрашивай больше времени - тебе придётся делать дополнительный рефракторинг уже написанного под новые требования.

>Появляются какие-то магические числа
Все магические числа определяй константами класса к которому они относятся.

>в параметры функций уходят уже по 6-8 переменных
Если переменных уже больше 2-3, то где-то ты проебал создание класса. Скорее всего эта функция хорошо будет работать как метод класса или принимать объект.

>Код становится монструозным и его тяжело "загружать в мозг", чтобы погонять чисто там
Потому, что проёбываешь то самое создание класса и, скорее всего, пишешь процедурно большую часть кода. У тебя мало абстракций, а это именно они облегчают понимание системы.

>>2238785
>Причина в том что в пхп нет инструментов для создания абстракций более чем из одного класса. Нет возможности разделить код на более высоком уровне, на модули например
Ты чушь каку-то несёшь. В пхп классы универсальни и модули из них делаются очень легко - только определи нужные интерфесы которые нужны системе.
Ответы: >>2239450
Аноним 2021/12/16 18:58:43  №2239450 4
>>2238999
>В пхп классы универсальни и модули из них делаются очень легко - только определи нужные интерфесы которые нужны системе.
Это ты хуйню несешь. Ты композер пакет хоть раз писал? В пхп нет способа с помощью кода объяснить как им пользоваться. Только с помощью гайда можно понять какой класс что делает. Причем тут нахуй интерфейс, когда любой из твоих пятидесяти классов в либе может использоваться. И чтобы понять какой и как нужно нырнуть в этот унитаз головой. Тебе человек о том и пишет что когнитивно всю эту поеботу осилить нельзя. И я объяснил почему. Язык блядь такой. Многословный, без высокоуровневых абстракций. Все что ты можешь сделать это либо именовать классы как-то по особенному, либо раскладывать по папочкам в особом порядке. Пиздец джуны пошли, уже и читать нихуя не умеют.

>Значит, проблемы с архитектурой. Тесты нужны. Или ты считаешь, что ты уникальный и пишешь код без единой ошибки?
Нужны епта, нужны. А ты их писал? Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты. И напишешь дата провайдер этих объектов. Ты напишешь, Вася напишет, Коля напишет. А потом нужно будет в метод одного из этих сервисов параметр добавить. Или убрать. Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки? Ответ убил: а хуй его знает. Тебе придется проверить все тесты, в которых эти милые люди упоминали изменяемый сервис. Удачи сделать это даже с использованием шторма. А если это системный сервис, который дохуя где используется инфа стотка что ты какое-нибудь место проебешь. И будет у тебя тестироваться там какая-то поебень вместо актуального поведения. А уж если кто-то додумался контроллеры тестировать, интеграционно, то это вообще пизда. Там мокается даже небо, даже аллах.

>Ты берешь пример неудачного проекта и делаешь вывод, что все другие проекты такие же.
Я этих проектов видел за сотню. Везде одно и тоже, просто с разной степенью пиздеца. Были такие где был условный порядок, но в таких местах спартанская дисциплина, кросс ревью от пяти человек, солюшен ревью и отдел качества. И скорость разработки там крайне низкая (читай нехуй делать). Сейчас у меня вообще прям показательный пример. Было несколько команд, у каждой по пять-шесть пхп проектов. После того как ковид уебал их всех разогнали, а проекты остались. Люди разные, подходы разные. А проблемы у всех одинаковые. Хрупкие тесты, мессиво из классов и интерфейсов и полное отсутствие понимания как это должно работать. Кто-то свое мессиво раскладывал по ДДД как Эванс завещал, у кого-то чистая архетиктура по Мартину - порты ебут адаптеры, а адаптеры твой мозг. Но если в проекте было много конрибьютеров и туда много писали - готовь ебало к фейспалмам. И яне утверждаю что эти люди были какие-то говнокодеры, просто язык вот такой. Наступает момент когда мозг перестает усваивать объем кода и начинается неизбежная деградация.
Ответы: >>2239485
Аноним 2021/12/16 19:50:53  №2239485 5
>>2239450

> В пхп нет способа с помощью кода объяснить как им пользоваться.

Во многих других языках так же - например, Питон, JS.

> Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты.

Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Что он вызовет такой-то метод. И ты тестируешь непонятно что. Ты сервис написал, чтобы он вызывал методы или чтобы он сделал что-то полезное? Надо тестировать конечный результат работы сервиса, а не то, сколько раз он для этого вызовет какой-то метод.

Заглушки, конечно, нужны, но без фанатизма. Отправка писем, HTTP-запросы - это все, конечно, мокается. Но не с целью посчитать, сколько раз был вызван метод отправки письма и сколько в него передано аргументов, а с целью убедиться что письмо отправлено и содержит требуемые данные.

То, что ты описал, я бы писать не стал - лучше без тестов, чем с такими тестами. Но еще лучше поломать голову и придумать способ протестировать код нормально. Тестирование это довольно сложная штука и не всегда очевидно, как его делать.

> Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки?

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

Ну и еще, если ты в тестах копипастишь 100 раз вызов какого-то метода, то может быть стоит применить принцип DRY и сделать, чтобы этих вызовов было не 100, а меньше. Тогда и исправлять меньше придется. Нужны фабрики, которые позволяют без копипасты подготовить окружение для теста.

> А уж если кто-то додумался контроллеры тестировать, интеграционно,

Да, контроллеры это часть интерфейса и их наверно лучше тестировать через E2E тесты, из эмулятора браузера. Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.

То есть, что касается тестов, я не думаю, что тут PHP как-то виноват. Тесты везде пишутся одинаково.

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

Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
Ответы: >>2239599
Аноним 2021/12/16 23:13:29  №2239599 6
>>2239485
>Во многих других языках так же - например, Питон, JS.
В JS уже есть понятие модуля, сейчас в тайпскрипте добавляют области видимости для модулей. Когда сделают будет еще один смачный харчек в ебло пхп. Жаль что фронтендеры не понимают какую манну небесную им дали и пишут на тайпскрипте такую поебень что глаз дергается.

>Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Бла бла бла... нормально делай - нормально будет.
Никакой конкретики так и не выдавил. Вот тебе конкретный пример: https://3v4l.org/AD5bt простой сервис, наливает воду в чашки. Покрой тестами FillCupsWithWater, ну так примерно как чувствуешь должно быть правильно.

>Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.
Сразу видно что ты такое никогда не писал. Любой логгер где-то по пути может просто уронить к хуям тест когда ломанется наружу из тестового окружения. Придется его замокать. Шины сообщений придется замокать или перевести с реббита на что-то более локальное. Ебаться с доктриной - это подгрузи заранее, это наоборот очисти. Каждый тест будет как праздник с новыми подарками, только в подарках говно. А самое веселое это когда ты поменяешь код, а отвалится чужой тест. Ты его откроешь, а там сетап на два экрана. И ближайшие два часа пройдут незабываемо.

>Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
Про идеально читаемый код хуйня конечно, но выдать лучше чем на пхп изи.
TypeScript если писать будут бекендеры. На Go будет не идеальный код, но гораздо короче и понятнее че мна пхп. А чтобы вообще охуеть от зависти и боли в очке просто посмотри как вся эта многословная поебень исчезает в нормальном языке https://www.youtube.com/watch?v=PLFl95c-IiU . Система типов заменяет 90% тестов, никаких ебучих абстрактных фабрик интерфейсов, весь домен умещается на одной странице.