Как стать автором
Обновить

Теория программирования: пакетные принципы и метрики

Время на прочтение9 мин
Количество просмотров15K
Всего голосов 44: ↑42 и ↓2+40
Комментарии12

Комментарии 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 и пакетные принципы довольно расплывчаты на тему определений и их трактования. На данный момент я думаю что понял их правильно, но если нет — поправьте.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий