Черты были одним из самых больших дополнений для PHP 5.4. Я знаю синтаксис и понимаю идею, лежащую в основе таких черт, как повторное использование горизонтального кода для таких общих вещей, как ведение журнала, безопасность, кэширование и т. Д.
Тем не менее, я до сих пор не знаю, как использовать черты в моих проектах.
Есть ли проекты с открытым исходным кодом, которые уже используют черты? Любые хорошие статьи / материалы для чтения о том, как структурировать архитектуры с использованием черт?
Ответы:
Мое личное мнение таково, что на самом деле очень мало приложений для черт при написании чистого кода.
Вместо использования признаков для взлома кода в классе лучше передать зависимости через конструктор или через сеттеры:
Основная причина, по которой я нахожу это лучше, чем использование черт, заключается в том, что ваш код становится намного более гибким, устраняя жесткую связь с чертой. Например, вы можете просто передать другой класс логгера сейчас. Это делает ваш код многоразовым и тестируемым.
источник
Я полагаю, что в течение некоторого времени нужно искать языки, которые имеют черты, чтобы выучить принятые хорошие / лучшие практики. Мое текущее мнение о Trait состоит в том, что вы должны использовать их только для кода, который вам придется дублировать в других классах, которые имеют те же функции.
Пример для черты Logger:
И тогда вы делаете ( демо )
Я предполагаю, что при использовании черт важно учитывать, что они на самом деле являются просто частями кода, которые копируются в класс. Это может легко привести к конфликтам, например, когда вы пытаетесь изменить видимость методов, например
Вышеуказанное приведет к ошибке ( демо ). Аналогично, любые методы, объявленные в признаке, которые также уже объявлены в классе using, не будут скопированы в класс, например
напечатает 2 ( демо ). Это те вещи, которые вы захотите избежать, поскольку они затрудняют поиск ошибок. Вы также захотите избегать помещения вещей в свойства, которые оперируют свойствами или методами класса, который его использует, например
работает ( демо ), но теперь черта тесно связана с А, и вся идея горизонтального повторного использования теряется.
Когда вы будете следовать принципу разделения интерфейсов, у вас будет много небольших классов и интерфейсов. Это делает Traits идеальным кандидатом для упомянутых вами вещей, например сквозных задач , но не для создания объектов (в структурном смысле). В приведенном выше примере с Logger эта черта полностью изолирована. У него нет зависимости от конкретных классов.
Мы могли бы использовать агрегацию / композицию (как показано в другом месте на этой странице) для достижения того же результирующего класса, но недостатком использования агрегации / композиции является то, что нам придется вручную добавлять методы прокси / делегатора к каждому классу, тогда это должно быть в состоянии войти. Черты решают эту проблему, позволяя мне хранить шаблон в одном месте и выборочно применять его там, где это необходимо.
Примечание: учитывая, что черты являются новой концепцией в PHP, все высказанные выше мнения могут быть изменены. У меня еще не было времени самому оценить концепцию. Но я надеюсь, что это достаточно хорошо, чтобы дать вам о чем подумать.
источник
:) Я не люблю теоретизировать и спорить о том, что нужно делать с чем-то. В этом случае черты. Я покажу вам, какие черты полезны для меня, и вы можете либо поучиться на них, либо проигнорировать их.
Черты - они отлично подходят для применения стратегий . Короче говоря, шаблоны разработки стратегии полезны, когда вы хотите, чтобы одни и те же данные обрабатывались (фильтровались, сортировались и т. Д.) По-разному.
Например, у вас есть список продуктов, которые вы хотите отфильтровать на основе некоторых критериев (бренды, характеристики, что угодно) или отсортировать по-разному (цена, ярлык, что угодно). Вы можете создать черту сортировки, которая содержит различные функции для разных типов сортировки (числовая, строковая, дата и т. Д.). Затем вы можете использовать эту черту не только в своем классе продукта (как показано в примере), но также и в других классах, которые нуждаются в аналогичных стратегиях (для применения числовой сортировки к некоторым данным и т. Д.).
Попытайся:
В заключение я думаю о таких чертах, как аксессуары (которые я могу использовать для изменения моих данных). Подобные методы и свойства, которые могут быть вырезаны из моих классов и помещены в одно место, для простоты обслуживания, более короткого и чистого кода.
источник
strategies
.Я рад за черты, потому что они решают общую проблему при разработке расширений для платформы электронной коммерции Magento. Проблема возникает, когда расширения добавляют функциональность к базовому классу (например, модели User), расширяя его. Это делается путем указания автозагрузчику Zend (через файл конфигурации XML) использовать модель User из расширения, и эта новая модель расширяет базовую модель. ( пример ) Но что, если два расширения перекрывают одну и ту же модель? Вы получаете «состояние гонки», и загружается только одно.
В настоящее время решение состоит в том, чтобы отредактировать расширения таким образом, чтобы один расширял класс переопределения модели другого в цепочке, а затем настраивал конфигурацию расширения для загрузки их в правильном порядке, чтобы цепочка наследования работала.
Эта система часто вызывает ошибки, и при установке новых расширений необходимо проверять наличие конфликтов и редактировать расширения. Это боль и нарушает процесс обновления.
Я думаю, что использование Черт было бы хорошим способом выполнить то же самое без этой раздражающей модели, переопределяющей «состояние гонки». Конечно, могут быть конфликты, если несколько Traits реализуют методы с одинаковыми именами, но я думаю, что нечто вроде простого соглашения о пространстве имен может решить эту проблему по большей части.
TL; DR Я думаю, что Traits могут быть полезны для создания расширений / модулей / плагинов для больших программных пакетов PHP, таких как Magento.
источник
Вы могли бы иметь черту для объекта только для чтения, как это:
Вы можете определить, используется ли эта черта, и определить, стоит ли записывать этот объект в базу данных, файл и т. Д.
источник
use
иметь эту черту, будет называтьсяif($this -> getReadonly($value))
; но это приведет к ошибке, если вы не сделалиuse
эту черту. Поэтому этот пример ошибочен.