Pull to refresh

Comments 12

Переводом на русский сейчас никто не занимается. Ранее я это делал, но потом начал больше заниматься Yii 2, позже Yii 3 и времени на сам перевод не осталось. То есть перевод нормальный, но, вероятно, несколько устарел по-сравнению с оригиналом.

Хороший повод подтянуть английский чтобы читать cookbook не ожидая перевода
скобки потерялись в формуле расчета абстрактности
Как-то все очень сложно описано. Примерно понимаю о чем написано, но человеку, который пока пишет код на уровне Yii2 эта статья, как мне кажется, никак не поможет научиться писать код лучше.

А что поможет? Мне сильно помог такой вариант:

1. Берем, и начинаем писать в свое свободное время какой-то большой проект-монолит. В свободное время — чтобы вас никто не подгонял со сроками, монолит — потому что только в монолите с сотнями моделей и сложной логикой хорошее ООП становится обязательным, а не желаемым. Что-то небольшое (микросервис) можно написать тяп-ляп и готово. Разработка большого монолита по принципам тяп-ляп быстро приводит к тому, что развивать его становится невозможно (думаю все с таким сталкивались на рабочих проектах)

2. Пишем проект как вам хочется. Это очень важно — писать не так, как кто-то в интернете написал, или в книжке, а как вам хочется. Хочется без SOLID и тестов — пишите. Здесь важно именно наступить на грабли и получить по лбу в тех моментах, в которых вы по лбу еще не получали. Чтобы прийти к тому же SOLID или тестам не по тому, что об этом Вася в интернете написал, а потому что вы сами, на личном опыте, к этому пришли.

3. Через какое-то время наступает момент, когда дальше разрабатывать проект становится невыносимо. Костыль на костыле и тому подобное. В этот момент берем, и пишем все с нуля. Переписываем на более лучший (по вашему мнению) вариант существующий функционал, и продолжаем добавлять новый. В моем опыте первое переписывание с нуля произошло через пол года. Второе — где-то через два года.

4. В процессе переписывания вы на личном опыте доходите до таких вещей, которые умные дяди пишут в умных книжках — например, хорошо бы какой-то функционал выносить в полностью независимый модуль (привет DDD), чтобы в следующем переписывании можно было просто взять его, и скопировать в новый проект (в новое «переписывание с нуля»). В этом же процессе вы обязательно придете к авто-тестам, и не только к ним, а ощутите те приятные моменты, когда возвращаясь к проекту через пол года, уже забыв что там как работает, и работает ли вообще, вы выполняете тесты, они проходят, и вы себе говорите «о, все работает, супер».

5. И так далее — новый функционал, новые переписывания, новый опыт — процесс бесконечный.

Конечно, чтобы годами писать какой-то домашний сложный проект нужно любить программирование. Ну и быть без детей, наверное :) Так что кто еще молодой и без семьи — ловите момент.
Как правильно формировать пакеты

Ничего не сказано про такой важный, на мой взгляд, аспект формирования пакетов, как использование не классического паттерна Единая точка входа

Потому что использовать интерфейсы вида:
$response = $object->handle($request) // handle(RequestInterface $request): ResponseInterface

Сильно удобнее, чем что-нибудь вроде:

$object->setParam1(...)
$object->setParam2(...)
$object->setParam3(...)
$result = $objcet->getResult()

В популярных пакетах такое редко встретишь, а вот во внутренних модулях компаний — постоянно. До банального указания обязательных зависимостей не через конструктор, а через отдельный метод.

P.S.
И это гораздо хуже, чем спагетти — потому что спагетти мы можем отрефакторить и что-то нормальное в результате получить. А чтобы получить что-то нормальное из такой лазаньи, её надо сначала растерзать и превратить в понятные и очевидные спагетти, а потом заново собирать лазанью, только уже правильную.

Еще раз убеждаюсь, как же сложно написано. Моя аналогия, которая, мне кажется, намного понятнее:

  • Ситуация №1: Неопытный программист пишет код как получается: получаем лапша-код, объекты, которые не объекты, а просто классы по которым как-то распиханы данные и методы для работы с этими данными. Его код плохой, но понятно как его рефакторить (потому что все когда-то так писали, и переписывали свой код)
  • Ситуация №2: Неопытный программист начитался умных книжек про паттерны, DDD и прочее, и начинает внедрять их на рабочем проекте. В результате его код получается сильно хуже, и намного более переусложненным, чем в ситуации с первым программистом.


Мораль проста: все новое лучше вначале проверять «на кошках» — на каких-то небольших и неважных проектах (например, на домашних), и только после обкатки (которая может занять и год и больше), и когда уже набился шаблон и этот шаблон проверен временем — уже внедрять в рабочих проектах.

P.S. И как хорошо где-то сказано: задача тимлида не в том, чтобы говнокода в проекте не было, а в том, чтобы этот говнокод не растекался — т.е. создать такие условия, чтобы говнокод каждого конкретного рядового программиста был как-то изолирован в себе (через вынесение в микросервис, или в модуль с отдельным неймспейсом, с указанным тимлидом интерфейсом использования, или как-то по другому — уже не суть)
  1. Не совсем понял, при чём тут front controller.
  2. Ваша аналогия неплохая, но она не про количество слоёв. Я хотел указать именно на это.
«Classes that change together are packaged together — изменение в пакете должно затрагивать весь пакет»

Что считается изменением?
Фикс бага в одном классе:
— выносим класс в отдельный пакет?
— вносим незначимые правки в остальные классы?
— третий вариант?

Не очень корректно, на мой взгляд, расшифрована идея

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


На самом деле SOLID и пакетные принципы довольно расплывчаты на тему определений и их трактования. На данный момент я думаю что понял их правильно, но если нет — поправьте.

Sign up to leave a comment.