Как научиться писать гибкий, грамотный, тестируемый код?

ilya12345

Новичок
Прочитал "Чистый код", "Совершенный код", почитал про патерны проектирования, начал писать тесты с помощью phpUnit и Codecept

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

Исходя из книг по совершенному коду:
1. На каждый класс должна быть возложена только одна обязанность.
- Не всегда получается разделить строго по обязанностям. К примеру не понятно как делать разделение на классы, если стоит задача - сделать оповещение пользователей по почте о новых сидках:

из 1 правила выходит что нужно создать 4 класса( я так это понимаю, возможно ошибаюсь)
1. Class Пользователь
2. Class Скидка
3. Class Oповещение -Email (возможно в будущем появятся и другие)
4. Class ОповещениеПользователейОСкидках -(где будут объединяться все предыдущие 3 класса)

Вопросы:
1. Стоит ли создавать целый класс если в нем будет только 1 метод?
2. Как я понял нужно избавляться от статичных методов, так как их сложно тестировать(не получится создать Mock,Stub), но тогда придется везде создавать объект с помощью new даже если мне нужен только один метод из объекта. Помоему это неудобно.
Что делать в таком случае? (как правильнее действовать)

2. Метод должен выполнять только одну операцию
в целом тут все понятно, но все равно не всегда удается следовать этому правилу, так как в любом случае получается в классе несколько методов, которые в себе объединяют другие методы (типо как метод Main в Java)
и имя у метода получается слишком длинное типо Class->МетодДелает1ЕщеДелает2ИДелает3()
(Пример с тем же оповещением пользователей. В любом случае придется писать метод, который внутри себя будет получать массив пользователей, список скидок, и делать оповещение (т.е. по сути будет делать минимум 3 действия))
Как можно разделить такой метод я не представляю.
Что делать в таком случае? (как правильнее действовать)

Тянусь к знаниям.Подскажите:

книги, статьи, курсы где смогу почерпнуть больше о том как проектировать классы и методы, разделять их по обязанностям, применять грамотно шаблоны проектирования, ООП

Хочу научиться писать гибкий, грамотный, тестируемый код, за который не будет стыдно и который легко можно будет поддерживать
 

Adelf

Administrator
Команда форума
1. Стоит ли создавать целый класс если в нем будет только 1 метод?
да
2. Как я понял нужно избавляться от статичных методов, так как их сложно тестировать(не получится создать Mock,Stub), но тогда придется везде создавать объект с помощью new даже если мне нужен только один метод из объекта. Помоему это неудобно.
Что делать в таком случае? (как правильнее действовать)
Тут очень кратко - https://habr.com/post/131993/ В php полно DI контейнеров. в каждом фреймворке есть. Отдельно тоже. например http://php-di.org/
(Пример с тем же оповещением пользователей. В любом случае придется писать метод, который внутри себя будет получать массив пользователей, список скидок, и делать оповещение (т.е. по сути будет делать минимум 3 действия))
Как можно разделить такой метод я не представляю.
Что делать в таком случае? (как правильнее действовать)
Это нормально. Главное чтобы получение юзеров и скидок было сделано в других классах.
Тянусь к знаниям.Подскажите:
книги, статьи, курсы где смогу почерпнуть больше о том как проектировать классы и методы, разделять их по обязанностям, применять грамотно шаблоны проектирования, ООП

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

Вурдалак

Продвинутый новичок
Очень тяжко рассказывать все нюансы, но в твоих рассуждениях есть некоторые заблуждения, которые бросаются в глаза.

«Обязанностью» не называют низкоуровневое техническое требование вида «один класс — один метод». Обязанность — это зона ответственности объекта. «Пользователь» может содержать много методов: ban(), changePassword(), etc.

Как я понял нужно избавляться от статичных методов
В самих по себе статических методах нет ничего плохого. Плохо, когда появляется, грубо говоря, статическая переменная, которая будет глобальным состоянием (но даже статическая переменная иногда может не нести никакого вреда архитектуре приложения). Но если речь по получение объекта-сервиса, то тебе действительно нужно обратить внимание на озвученные DI-контейнеры.
 

ilya12345

Новичок
да

Тут очень кратко - https://habr.com/post/131993/ В php полно DI контейнеров. в каждом фреймворке есть. Отдельно тоже. например http://php-di.org/

Это нормально. Главное чтобы получение юзеров и скидок было сделано в других классах.

Тебе пора начать что-то писать. Хватит теоретизировать.
Очень тяжко рассказывать все нюансы, но в твоих рассуждениях есть некоторые заблуждения, которые бросаются в глаза.

«Обязанностью» не называют низкоуровневое техническое требование вида «один класс — один метод». Обязанность — это зона ответственности объекта. «Пользователь» может содержать много методов: ban(), changePassword(), etc.


В самих по себе статических методах нет ничего плохого. Плохо, когда появляется, грубо говоря, статическая переменная, которая будет глобальным состоянием (но даже статическая переменная иногда может не нести никакого вреда архитектуре приложения). Но если речь по получение объекта-сервиса, то тебе действительно нужно обратить внимание на озвученные DI-контейнеры.
Большое вам спасибо. Пошел изучать и применять DI
 

AmdY

Пью пиво
Команда форума
@ilya12345 просто начни писать unit тесты и начнёт приходить осознание, а потом заново перечитаешь книги и уже будешь осознавать что читаешь и что пропустил в прошлый раз.
 
Сверху