В программировании есть принцип под названием СУХОЙ или Не повторяйся. Как правило, если вы повторяете части своей логики, у вас появляется больше мест, которые нужно исправить в случае обнаружения проблемы, и вероятность появления несоответствий в вашем приложении по мере того, как будущие требования увеличивают сложность приложения.

Один из подходов к поиску СУХОГО кода, о котором я хотел бы поговорить, - это функция PHP, называемая traits, которая позволяет повторно использовать код в любом классе в кодовой базе.

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

Во-первых, нам нужно определить черту, как если бы мы определяли класс:

Затем в классе мы можем импортировать эту черту:

Теперь мы можем вызвать метод baz для экземпляра MyClass, например. echo $myClass->baz(‘hello’);

Но подождите, мы можем пойти глубже. Черты могут импортировать другие черты. 🤯

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

Что, если мы попробуем импортировать две характеристики в наш класс, и обе они будут определять один и тот же метод? Если мы не разрешим этот конфликт явным образом при импорте признаков, мы получим фатальную ошибку. Чтобы указать, какой из двух методов использовать, у нас есть оператор insteadof, который мы можем использовать:

Итак, теперь мы знаем, как использовать черты характера, и когда мы можем их использовать? В одном из наших проектов здесь, в BuildEmpire, мы используем LMS Totara. У нас есть несколько настраиваемых действий, которые мы создали для клиента. Эти действия должны быть организованы в рамках курса особым образом, но мы не хотим строго придерживаться этой структуры. Мы просто хотим предупредить администратора о новой форме действия, если он собирается добавить действие в раздел, которого мы не ожидаем.

Таким образом, нам не нужно переписывать эту логику для каждого действия, у нас есть признак, содержащий логику, а затем просто «использовать» этот признак в каждом настраиваемом действии:

Теперь, если нам нужно изменить это сообщение, либо условия, при которых оно отображается, либо само сообщение, нам нужно обновить код только в одном единственном признаке, и все наши настраиваемые действия унаследуют это изменение. 👍

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