Traits в trunk PHP
26 августа 2010
Вот и traits попали в транк PHP.
Данная возможность была придумана как альтернатива множественному наследованию и mixin-ам. trait представляет собой набор PHP-кода (обычно это методы), который можно использовать в своём классе. Фактически trait — поддерживаемый на уровне языка умный copy-paste.
trait Dumper { public function dump($var){ echo '<pre>'.print_r($var, true).'</pre>'; } } class MyClass { use Dumper; } $myClass = new MyClass(); $myClass->dump('test');
MyClass в итоге будет выглядеть как:
class MyClass { public function dump($var){ echo '<pre>'.print_r($var, true).'</pre>'; } }
Это самый простой случай. Более сложные и интересные вещи, такие как подмена имени метода при подключении, разрешение конфликтов, trait-ы из trait-ов, требования к классу, описаны на английском в wiki.
Комментарии RSS по email OK
Сомнительное конечно нововведение, чтото не могу придумать зачем это реально может пригодиться.
То есть пример выше это на самом деле Dumper::dump(); и зачем trait реально сложно представить, там правда еще такие конструкции добавили
, где DB, Counter - классы, интересно что в данном случае происходит с переменными, они общими становятся?
Ох уж этот PHP - просто костыль на костыле .. Что мешало нормально реализовать множественное наследование раз уж задались такой идеей. По функционалу получилось похожим на C++ только с черезжопным синтаксисом как и для namespace'ов. :(
да синтаксис конечно вырви-глазный...
На любое нововведение всегда найдётся много хаятелей, которые просто не пытаются представить, что можно писать не только всеми принятым синтаксисом, но и альтернативным, и часто такие возможности оказываются полезными в неожиданных ситуациях.
Ни костылей, ни ужасного синтаксиса я тут не вижу, это исключительно расширение функциональности.
@Erlang, есть общепринятный синтаксис, реализованный одинаково в различных языках программирования. В данном случае: PHP изначально реализовал только одиночное наследование, а trait - это костыль для упрощения инкапсуляции. Лучше бы сразу делали множественное наследование, т.к. идея use, переопределения методов и т.п. полностью слизана с С++. Сдается мне, что разработчики PHP недавно открыли для себя его существоване и начали коряво передирать оттуда все что можно и не нужно ..
ЗЫ: Попробуйте писать справа-на-лево снизу-в-верх - это же так альтернативно и афигенно необходимо уметь! ;)
Вообще-то синтаксис вполне традиционнй для PHP, только новые ключевые слова. Если только наличие новых ключевых слов делает для кого-то синтаксис вырвиглазным, то возникает вопрос: почему он до этого не казался вам таковым?
Trait'ы - не костыль, а способ вторичного использования поведения, имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции. Ну с оговоркой о статических переменных, которые фактически добавляют состояния.
Далее, Graft'ы - это и есть множественное наследование с несколькими оговорками:
другой синтаксис, но похожий, например, на синтаксис объявление метода;
во включаемом классе не может быть конструкторов с аргументами;
имена членов должны быть разные, для этого ключевое слово 'from'.
Но тут же получаем преимущества:
включаемый класс моожет реализовать абстрактные методы расширяемого класса (и, конечно, наоборот тоже можно);
подключаем только то, что нужно.
Вторичное использование кода в обоих случаях (Traits, Grafts) - преимущество очевидное.
Насчет общих переменных: в расширяемом классе видно только то, что явно указано.
ОБЩЕЕ ПРАВИЛО ДЛЯ НЕДОВОЛЬНЫХ: НЕ НРАВИТСЯ - НЕ ЕШЬ!
stalker
С сями, скорее всего, разработчики PHP знакомы хорошо… всё-таки на них PHP и написан. С плюсами, скорее всего, тоже. По ссылке объясняется, почему не стали реализовывать множественное наследование и mixin.
@stalker
Покажите мне в плюсах traits или mixins на уровне синтаксиса.
А также:
Где тут инкапсуляция? Я уже написал, для чего нужен trait - для повторного использования поведения, т.е. методов. Как trait упрощает инкапсуляцию? Чем такой способ инкапсуляции ПРОЩЕ, чем включение тех же самых методов методов напрямую в класс? Для меня проще включить их в класс, если они используются только в нем - так ведь меньше кода писать. Другое дело - когда код используется многократно в разных классах - например, это функции профилирования или журналирования. Но чем это проще с точки зрения инкапсуляции?
Почитайте историю происхождения языка, поймете, почему автор об этом не подумал сразу.
А где они переопределяются? Я вижу, что нигде. Только переименовываются в некоторых случаях. Или вы говорите об абстрактных методах (они просто реализоваываются, но не переопределяются)?
Это получает что-то вроде реализации паттерна Prototype?
Вообще, мне очень понравилось, в отличе от других ООП фишек, вопрос только насколько данных синтаксис ухудшит архитектуру и понятность кода.
@Scriptin
Даже не знаю почему-то не казался. Зачем так бурно реагировать, такое ощущение что я кому то что-то запрещают или вы всю жизнь ждали что это включать в транк, а тут пришел злой дядя и все обругал.
Нововведения полезные спорю, но почему синтаксис настолько разный для use класса и use trait'са?
достаточно легко можно предстать, конструкции с > 20 методами * 5 классов, во всех переименованы функции, и другой класс, где те же самые функции но переименованы в другом порядке и так далее.
Про историю языка, уже 5 версия на дворе, с момента происхождения ох как много всего внедрили.
@Sam
Если Вы про это объяснение: "To circumvent this problems multiple inheritance and Mixins have been invented. But both of them are complex and hard to understand.", то как-то по-ламерски звучит .. "Не стали потому, что оно сложно для понимания" - Страуструпа видимо не читали. :)
@Scriptin
"почему он до этого не казался вам таковым?" - и раньше казался. Просто чем дальше, тем уродливее он становится. Ну не возможно в язык, изначально разрабатывавшийся как шаблонизатор для Perl, впихнуть все "вкусности" современных ЯП. И отказаться от этой кривизны из-за потери совместимости со старым кодом они уже не могут ..
"имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции" - я вижу только два отличия: 1. statless, 2. flattenable, no runtime impact.
"НЕ НРАВИТСЯ - НЕ ЕШЬ!" - именно по этому старые проекты остановили на PHP 5.2, а новые разрабатываем на Java/Ruby.
"Почитайте историю происхождения языка, поймете, почему автор об этом не подумал сразу." - ничего, что Я на нем с PHP3 проекты веду и сам не раз баги коммитил? ;)
"Покажите мне в плюсах traits или mixins на уровне синтаксиса." - простите, у меня есть более важные дела, чем кого-то в чем-то убеждать.
@Scriptin
"Trait'ы - не костыль, а способ вторичного использования поведения, имеющий мало общего с множественным наследованием, т.к. наследуется только поведение, т.е. функции." - для этого издавна используются классы со статическими методами. Теперь для этого закрепили синтаксис на уровне самого языка - ВСЕ.
А вообще White Shadow правильно говорит - зачем так бурно реагировать? Кому нравится - будет использовать, кому НЕ нравится - НЕ будет. Мир, дружба, жвачка :)
Я не имел целью никого обижать и оскорблять, просто КАЖДЫЙ раз, когда в каком-нибудь популярном (читай "широко используемом") языке появляется что-то новое, находятся хаятели. И складывается ощущение, что все они опытные архитекторы языков программирования и точно знают, как правильно и как неправильно (только почему-то никогда не говорят, как все-таки было бы правильно).
@White Shadow
Вот это хороший вопрос. Может, еще переделают.
@AmdY
По-моему этот шаблон только для клонирования объектов целиком, а не для повторного использования поведения.
Ооо, радует, что пхп пытается догнать руби)), очень этого не хватало!
Очень радуют такие фичи. Наконец нашел время почитать доки по Traits, и по-моему теперь нет смысла от интерфейсов, Traits включают полностью функционал интерфейсов, и добавляют новые возможности. Я думаю, интерфейсы должны исчезнуть, от них не будет никакого преимущества.
Как при использовании trait добиться подсветки кода в phpStorm? При использовании Singleton примеси уже нельзя в trait описать тип @var ClassName.