Интерфейсы для трейтов

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

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

 

Собственно проблема…

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

Итак, посмотрим:

Этот трейт удобно использовать во множестве мест, но его главная особенность – метод getSalesPrice() зависит от наличия двух других методов getWholesalePrice() и getMarkup()

Как быть?

 

Runtime решение

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

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

Это довольно простая реализация, но secureTraits() позволяет отлично следить за порядком в трейтах и классе: он получает объект класса и с помощью Reflection-класса получает информацию об используемых трейтах и интерфейсах класса. Далее проверка – это всего лишь дело техники. В случае нестыковок выбрасываем LogicException.

Напоследок небольшая заготовка использования этого механизма:

 

Источник

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">