Трейты в PHP


Оглавление (нажмите, чтобы открыть):

Трейты

Начиная с версии 5.4.0 в PHP есть возможность использования инструментария для повторного использования кода. Он называется — трейт.

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

Использование

Рассмотрим пример использования трейта на основе создания «Транслитератора» (суть: буквы кириллицы переводим в латиницу).

Интернет, компьютеры, софт и прочий Hi-Tech

Сервисы
Избранные доки
Метки (все метки)
Дополнительно

Краткое введение в трейты в PHP

Автор: andres, 14 января 2013

Идея трейтов довольно стара, так что до создания их PHP-версии было реализовано немало аналогичных подходов. Их истоки берут начало в 80-х, хотя это было и не совсем то, что мы сейчас называем трейтами. Эти подходы известны по таким документам, как Опыт применения трейтов в Xerox Star Workstation.

В последующие два десятилетия использовались различные близкие техники, такие как принципы языка Self и идея примесей. Позже, Группа программного обеспечения из Бернского университета усиленно разрабатывала идею трейтов, в результате чего возникла их первая реализация для Smalltalk. Она много раз была освещена на различных конференциях.

Мысль внедрить трейты в PHP родилась, похоже, в RFC за март 2008 года. Затем она была переосмыслена в новом RFC за октябрь того же года. Наконец, в марте 2012 года трейты увидели свет в релизе PHP 5.4.0.

Итак, что такое трейт?

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

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

Трейты могут решить эти проблемы, так как позволяют программисту группировать наборы поведений в новые концепции (трейты), которые могут потом «подключаться» к любым классам независимо от того, как они расположены в иерархии классов. Резюмируя, можно сказать, что трейт обладает следующими свойствами:

  • Он предоставляет готовое к использованию поведение в форме набора методов.
  • Трейт невозможно инстанцировать. Чтобы его использовать, его нужно включить в какой-нибудь класс, как его часть.
  • Чтобы предоставить какое-то специфическое поведение, трейт может нуждаться в содержащем его классе.

В некоторых реализациях (таких как Smalltalk) трейты являются простыми поведениями и не могут содержать внутреннего состояния. В других реализациях (таких как в PHP) — могут.

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

Модульная реализация слушателя

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

Перейдем к коду нашего примера. Настоящий простой слушатель может быть реализован так:

Как можно заметить, мы создали трейт, который содержит массив подписчиков, предоставляет метод для создания новой подписки и позволяет субъекту инициировать новое событие. Остановимся немного подробнее на этом коде:

  • В PHP трейты могут определять состояния (инстанцируемая переменная $subscribers ). Определенные в трейтах инстанцируемые переменные присоединяются к переменным целевого класса. В случае конфликта имен генерируется ошибка (смотрите раздел Свойства в Руководстве по трейтам в PHP).
  • Метод onEventSendTo() динамически создает функцию для посылки сообщения. Это делается с помощью PHP замыканий, о которых вы можете больше узнать из этого поста.
  • Метод trigger() перебирает заданные функции и выполняет их. Последнее делается в строке $function(); .

Получив это определение, мы можем теперь написать несколько классов для выполнения первого теста. Сначала мы определим класс, который будет выполнять роль target реализуемого паттерна:


Как вы можете заметить, новый протокол включается в класс действительно просто: вам всего лишь нужно добавить строку use Observable; . Удобно, что мы можем делать это на любом уровне иерархии классов, что делает трейты интересным способом горизонтального переиспользования кода.

Теперь мы создадим роль target, которая должна быть определена для observer-а:

А в завершение примера мы напишем тестовый пример для создания отношения наблюдения между объектами и, соответственно, для тестирования поведения нашего трейта:

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

Некоторые вещи, которые стоит упомянуть

Я планировал сделать короткий пост, опустив некоторые важные концепции трейтов вообще и их реализации в PHP в частности:

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

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

Автор: andres, 14.01.2013
Перевод с английского: Дмитрий Скоробогатов, специально для xBB.uz, 21.04.2014
Оригинальный текст может быть найден по адресу https://research.quanbit.com/2013/01/14/a-small-introduction-to-php-traits/

Последнее редактирование: 2014-04-21 06:21:44

Оставьте, пожалуйста, свой комментарий к публикации

© 2007-2020, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.

Мастер Йода рекомендует:  Сравнение быстродействия WordPress-проекта на PHP и на .NET

Трейты — множественное наследование PHP

trait [treɪt], [treɪ] — характерная черта, особенность, внезапно типаж.

Трейты — механизм повторного использования кода.

Трейты нужны для возможности реализации общего, однотипного функционала для нескольких классов. В PHP

class Test <
use A , B <
B :: a insteadof A ;
A :: b insteadof B ;
>
>

class TestAlias <
use A , B <
B :: a insteadof A ;
A :: b insteadof B ;
B :: b as c ;
>
>

$ta = new TestAlias ( ) ;

$ta -> a ( ) ;
$ta -> b ( ) ;
$ta -> c ( ) ;

Выведет на экран

Вызов $ta->c() отработает метод B::b, по указаному ранее алиасу «c» (синониму) оператором as.

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

b :: $s = 0 ;
c :: $s = 1 ;
echo b :: $s . ‘ — ‘ . c :: $s ;

Трейты, как и классы могут, использоваться в автозагрузчике

spl_autoload_register ( function ( $name ) <
echo «:: » . $name ;
> ) ;

class A <
use BTrait ;
>

$obj = new A ( ) ;
$obj -> hello ( ) ;


Fatal error: Trait ‘BTrait’ not found

Другие примеры по трейтам можно посмотреть в Куроводстве PHP.

Трейты в PHP

В php не поддерживается множественное наследование при работе с классами, то есть у класса может быть только один родительский класс. И поэтому дабы избежать множественного дублирования кода были введены , так называемые трейты.

Допустим нам нужно реализовать ряд общих методов для всех классов.

Рассмотрим на примере двух классов main и child которым мы с помощью трейта functions определим общий метод profit

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

Мы также в классе может использовать несколько трейтов перечислая их через запятую, use trait1, trait2 . ;

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

К счастью трейты можно использовать вместе с интерфейсами.

В этом примере мы определили метод трейта через интерфейс.

Также при использовании трейтов может возникнуть,так называемый конфликт имен.

К примеру у нас есть два трейта в которых определены методы с оодиноковыми названиями:

Следовательно в такой ситуации у нас возникнет ошибка , так как матод profit есть в этих трейтах. Для разрешения такой проблемы используется ключевое слово insteadof

Рассмотрим на конкретном примере:

Теперь давайте рассмотрим более подробно что мы здесь понаписали такого:

Во первых как видите ошибки у нас уже нет. Благодаря использованию ключевого слова insteadof.

Во вторых у нас выполнился метод трейта profit трейта main для того чтобы выполнился метод трейта functions нам необходимо записать так:

Как видите к объявлению наших трейтов с помощью ключевого слова use приписывается тело в котором указывается название трейта и через два двоеточия название его метода , а через ключевое слово insteadof название трейта в котором выполнение метода с таким же названием profit будет проигнорировано в пользу трейта main.

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

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

Метод из profit из трейта main мы инициализируем через ключевое слово insteadof ,а метод из functions через псевдоним которому мы через ключевое слово as присвоили имя functions_profit

Ну вот в общем то и все дорогие друзья, надеюсь я смог донести до вас полезную информацию. Желаю удачи!

PHP Profi

Квест → Как хакнуть форму

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

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

Исследуем один из таких нюансов и по возможности его усовершенствование на уровне языка. Посмотрим, как мы можем решить одну проблему во время выполнения, но было бы здорово иметь эту возможность в самом PHP.

Проблема:

Трэйты — отличное средство для вынесения общего поведения, когда мы выносим метод в трейт, то можем использовать его в разных классах без дублирования кода. Но эти методы зачастую могут зависеть от других методов (например из других трейтов). И тогда мы не можем быть уверены, что все они будут работать как надо.
Рассмотрим такой пример:


Казалось бы, такой трейт легко использовать, но есть проблема — этот метод использует getMarkup() и getWholeSale(), которых может и не быть в классе-потребителе (класс-потребитель — тот, в котором используется код трейта).

Решение:

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

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

Это простейший способ использования Reflection (имеется в виду класс Reflection), который когда-либо видел автор 🙂 Метод secureTraits() принимает экземпляр класса и создает для него reflection, откуда мы можем получить список реализованных интерфейсов класса и трейты, которые он использует. Из списка трейтов мы можем узнать, какие методы вызываются , они просто должны быть такими же (быть похожими на) interfacesForTraitName() . Сравниваем их со списком реализованных в классе интерфейсов и при несоответствии кидаем исключение. Можно использовать такой шаблончик:

ЗлостныйКодер

Программирование, Алгоритмы, С++, C#, Java, Python и другие вещи

пятница, 20 декабря 2013 г.

Типаж (traits) в PHP

Новая фича, которая появилась с бетой PHP 5.4, называется Трейт (Типаж).
Трейт — единица повторного использования кода.

Используется для реализации множественного наследования, так то можно и с помощью повторного кода это сделать, но это неправильно, так как идет усложнение кода, а здесь просто все делается в одну строчку.

Так то можно и с помощью интерфейсов реализовать множественное наследование, но трейты намного удобнее (лично для меня).

Совет для лучшего понимания и осмысления трейтов:
Это просто копипаст, то есть как будто в классе взяли и сделал include ‘some.php’ с каким то методом.

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

1. Синтаксис

Трейт похож на класс, его объявление начинается со слова trait:

2. Класс может также содержать неограниченное количество трейтов

3. Трейт может содержать другие трейты:

4. Трейты и порядок выполнения.

Не стоит забывать, что:

Мастер Йода рекомендует:  Платежная система Moneybookers – регистрация и использование

1)Сначала:
Методы трейта переписывают унаследованные методы родительского класса
2)Потом уже:
Методы определенные в текущем классе переписывают методы из трейта

Объяснение:
Мы имеем результат Hello World, так как у нас в текущем классе (производном) определен метод, который ПЕРЕКРЫВАЕТ метод из трейта.
Поэтому,если мы хотим, чтобы HelloWorld объект выводил также Base World, нам необходимо использовать ключевое слово ::parent.

5. Конфликт имен

Может возникнуть ситуация, что два трейта содержат функцию с одинаковым именем, тогда PHP выкинет fatal error ошибку

Решение:
Нужно использовать ключевое слово instead:

Категория отличие от обычного наследования:

6. Статические свойства в трейтах

Как мы помним, в наследовании, если наследуется класс со статическим свойством, то это статическое поле содержит одно и то же значение, в трейтах не так, класс в трейтах использует разные объекты;


Пример на родительских классах:
Пример с использованием трейта:

Трейты в PHP

Когда я стартовал кампанию на Patreon, то пообещал отвечать на вопросы. Первый вопрос задал Daniel и он о трейтах PHP:

Что думаете о трейтах в PHP? Зло ли они? Стоит ли их избегать? Если их использовать, какие особенности? Когда их лучше не использовать? Может был отрицательный или положительный опыт?

Что такое трейты?

В документации PHP трейты описываются так:

Трейт (англ. trait) — это механизм обеспечения повторного использования кода в языках с поддержкой единого наследования, таких как PHP. Трейт предназначен для уменьшения некоторых ограничений единого наследования, позволяя разработчику повторно использовать наборы методов свободно, в нескольких независимых классах и реализованных с использованием разных архитектур построения классов. Семантика комбинации трейтов и классов определена таким образом, чтобы снизить уровень сложности, а также избежать типичных проблем, связанных с множественным наследованием и смешиванием (mixins). > Трейт очень похож на класс, но предназначен для группирования функционала хорошо структурированым и последовательным образом. Невозможно создать самостоятельный экземпляр трейта. Это дополнение к обычному наследованию и позволяет сделать горизонтальную композицию поведения, то есть применение членов класса без необходимости наследования.

Описание длинное. Если по-простому, не затрагивая вопросы наследования, то трейты — такой умный копипаст.

Код выше будет работать так же, как и следующий код:

Трейты и Yii

Yii использует трейты для низкоуровневых штук и общего кода из слоя работы с базами данных. Трейты рассматривались как альтернатива поведениям в 2.0 и будут ещё раз рассматриваться для релиза 2.1.

Поведения

Я начал присматриваться к трейтам в августе 2010 когда их смёржили в trunk PHP (так зовётся master в CVS и SVN). К тому времени в Yii 1.x уже были поведения. Они похожи на mixin в Ruby и полезны для придания дополнительных возможностей, таких как SoftDeleteable или Versionable , существующим объектам или классам. Главное отличие в том, что у поведений есть своё состояние и они могут быть присоединены к объекту или отключены во время исполнения. У трейтов своего состояния нет.

Трейты ушли в релиз до выхода Yii 2.0, поэтому мы рассматривали их как альтернативу поведениям из Yii 1.1. Было решено оставить поведения. В то время не было хороших идей как сделать трейты настраиваемыми и как реализовать подключение и отключение их во время выполнения.

При формировании планов на версию 2.1 идея всплыла повторно. Мы нашли как реализовать настраиваемость трейта через использования абстрактных методов. Подключение и отключение во время выполнения оказалось невозможным, но нашёлся способ включать и выключать обработчики подписываясь на события или отписываясь от них. Финальное решение пока ещё не принято.

Низкоуровневая функциональность

Yii использует трейты для общей низкоуровневой функциональности: — ArrayableTrait — ArrayAccessTrait

Это самое очевидное и правильное использование трейтов.

Общий код слоя для работы с базами данных

Интерфейс этого слоя в Yii 2.0 одинаков как для реляционных баз, так и для noSQL. Общие части реализации вынесены в трейты для того, чтобы не раздувать дерево наследования и не перекрывать слишком много методов для noSQL, значительно отличающихся от методов для традиционных баз данных. Лично я не очень доволен этой реализацией, если смотреть только на верность ООП. Можно было использовать композицию и обычные классы. Код был бы более тестируемым и читать его было бы проще. Тем не менее, использование трейтов оправдано так как оно значительно сокращает количество вызываемых методов и делает слой работы с базами данных производительней. С тестированием мы также разобрались несмотря на то, что это было не тривиально.

Особенности

Если вы задумались об использовании трейтов, подумайте дважды.

Отсутствие инкапсуляции

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

Идеально использовать трейты для небольшого количества относительно простого кода.

Состояние

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

Приватные поля трейта копируются в класс, так что возможны как конфликты имён, так и случайная модификация полей. Так как во время выполнения всё копируется в класс, класс имеет доступ даже к приватным полям.

Использование static означает, что все объекты класса, использующие трейт, будут иметь общее состояние, что необходимо далеко не всегда.

Так зло ли трейты?


Зависит от того, как вы их используете.

Как и в случае с копи-пейстом, зло относительно. Нет ничего абсолютно злого или абсолютно хорошего.

Трейты полезны для повторного использования реализации инетерфейса без необходимости заводить базовый класс. Во всех остальных случаях лучше воспользоваться композицией объектов.

Почитать

Комментарии RSS по email OK

Поведения в YII полифункциональны — используются в качестве комплексных аттачей на события (в частности для АР), иногда добавляют доп. методы, иногда и то и то сразу. Если совсем от них отказываться то надо какую-то event-subscriber-dispatcher альтернативу.

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

Примеси в PHP (trait) // PHP

С версии 5.4 в PHP появился такой интересный механизм как примеси (trait), который по задумке разработчиков должен помочь разруливать ситуации когда уж очень хочется применить множественное наследование, но нельзя. Вот о некоторых подобных ситуациях я и расскажу далее.

Примеры не надуманные, а вполне рабочие из фреймворка Bluz 😉

Теория

Тут будет краткий пересказ официальной документации в моей интерпретации, если не интересно — промотайте чуть дальше…

Хотя нет, лучше останьтесь и прочитайте, ведь мне абсолютно не нравится подача этого материала в официальной документации, для понимания примесей надо разговор начинать с необходимости данного нововведения в PHP. Начну издалека, вот один из классических примеров ООП: есть следующие классы – абстрактный класс Мебель, который лишь знает что у мебели есть размеры, Стол с площадью столешницы и Стул с некой максимально-возможной нагрузкой, в довесок есть Диван, пока просто диван:

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

  1. Если нам нужно узнать объём занимаемый мебелью – создадим ещё один метод в классе предке Furniture , т.к. данный функционал будет общим для всей мебели.
  2. Если нам нужно узнать цвет и материал мебели – то нам тоже подойдёт класс Furniture , лишь с одной оговоркой, что цвет и материал однородные.
  3. Если же нам надо указать материал обивки мебели, то нам уже надо либо вносить данный функционал в оба класса Chair и Couch , но это копи-паст и совсем не ООП, либо должен появится новый класс Upholstered , от которого и будут унаследованы эти классы.
  4. Теперь вспомним, что некоторая мебель у нас может раскладываться, и нам надо добавить эту информацию для классов Table и Couch , можно было бы создать ещё один класс Folding и расширять его, но данное изменение будет конфликтовать с предыдущим решением, и получается, что есть единственный выход – копипаст методов между классами.
Мастер Йода рекомендует:  Что будет с анонимными электронными платежами

Давайте-ка распишем данный подход в коде:

Да тут невооруженным взглядом видно копипасту, и очень хотелось бы избавится от неё, хотелось бы реализацию требований 3 и 4 закинуть в отдельный класс, и наследовать его, но в PHP нет множественного наследования, может быть только один класс предок. И вот в PHP 5.4 на сцену выходят примеси (trait), чем-то они схожи на классы, но лишь издалека, примеси лишь группируют некий набор функционала под одной вывеской, но не более. Давайте таки опишем необходимый функционал в примесях:

Теперь данный примеси легко можно подключить в наших классах:

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

Реализация шаблона Singleton

Можно много спорить о данном шаблоне, есть у него и плюсы и минусы, но речь не об этом, а о его реализации, при чём так, в один use 😉

Чтобы это стало возможным следует реализовать вот такую примесь:

Полный листинг класса можно найти в репозитории – Bluz/Common/Singleton.php. Пример не претендует на универсальность, но он юзабелен и имеет право на жизнь.

Обратите внимание, реализация шаблона Singleton никоим образом не обязует вас на хоть какие-то объединения классов под одним предком, т.к. это выглядило бы очень странно, а вот для избавления от практики копирования функционала из класса в класс нам и нужен данный trait

Реализация интерфейса инициализации

Очень часто случалось мне встречать классы, у которых есть пачка «сетеров», да ещё и некий метод setSettings или setOptions , который принимает массив в качестве параметров и все эти «сетеры» дёргает, раньше для этого мы бы описывали некий интерфейс Options, который бы обязывал разработчика писать реализацию этого злополучного метода setOptions (а скорей всего его бы скопировали из аналогичного класса). Но подобный подход устарел, и для такого случая был создан trait Options:

Теперь попробуем заюзать данную примесь в простом шаблонизаторе:

А вот и пример использования:


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

Реализация помощников класса

О чём это я, да о достаточно популярном приёме, когда функционал одного класса разделяют по различным классам и функциям с ленивой инициализацией, самый наглядный пример — это помощники View в Zend Framework. В фреймворке Bluz данный подход реализован в одном trait:

Для примера будем использовать всё тот же шаблонизатор:

В качестве ленивого помощника у нас будет анонимная функция:

Теперь можно пользоваться:

Код сокращён и упрощён для наглядности

Выводы

Как можно заметить, trait’ы можно и нужно использовать, ведь таким образом мы сокращаем объём кода, который нам потребуется поддерживать, да и метод копи-пасты уже давно должен был кануть в лету, а с появлением примесей вам уж не будет оправдания 🙂

Если у вас есть примеры использования примесей, прошу — оставляйте ссылки.

Трейты (trait) зачем это нужно с точки зрения практического программирования?

18.02.2013, 21:31

Зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это нужно это 4 байта то есть int не может больше 4 байт весить?
Вот еще один вопрос зачем биты нужны это меньше байтов но int 32 бита но я не допер зачем это.

Linux с точки зрения пользования и программирования
Не могли бы, пожалуйста, растолковать новичку, почему Linux — это круто и, чем мне, начинающему.

дифференциальные уравнения с практической точки зрения это
ДУ это математические модели каких либо процессов. Так можно сказать ? Если говорить об их.

Если H2 задать маленький шрифт — это плохо с точки зрения ПС ?
Если H2 задать маленький размер шрифта (12px) — это плохо с точки зрения ПС ?

18.02.2013, 22:27 2

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

PHP Profi

Квест → Как хакнуть форму

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

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

Исследуем один из таких нюансов и по возможности его усовершенствование на уровне языка. Посмотрим, как мы можем решить одну проблему во время выполнения, но было бы здорово иметь эту возможность в самом PHP.

Проблема:

Трэйты — отличное средство для вынесения общего поведения, когда мы выносим метод в трейт, то можем использовать его в разных классах без дублирования кода. Но эти методы зачастую могут зависеть от других методов (например из других трейтов). И тогда мы не можем быть уверены, что все они будут работать как надо.
Рассмотрим такой пример:

Казалось бы, такой трейт легко использовать, но есть проблема — этот метод использует getMarkup() и getWholeSale(), которых может и не быть в классе-потребителе (класс-потребитель — тот, в котором используется код трейта).

Решение:

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

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

Это простейший способ использования Reflection (имеется в виду класс Reflection), который когда-либо видел автор 🙂 Метод secureTraits() принимает экземпляр класса и создает для него reflection, откуда мы можем получить список реализованных интерфейсов класса и трейты, которые он использует. Из списка трейтов мы можем узнать, какие методы вызываются , они просто должны быть такими же (быть похожими на) interfacesForTraitName() . Сравниваем их со списком реализованных в классе интерфейсов и при несоответствии кидаем исключение. Можно использовать такой шаблончик:

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