Traits for specified class/interface

Adelf

Administrator
Команда форума
Вам не кажется, что было бы приятно в PHP добавить к трейту условия на класс, который может этот трейт юзать? Т.е. либо поддерживать какой-то интерфейс или базовый класс. Тогда они стали бы гораздо приятнее и автокомплитнее. Нет таких планов там в internals?
А то возникают подобные вопросы - https://youtrack.jetbrains.com/issue/WI-16368 и стандартная отмазка, что это нет ни в phpDoc, ни в PHP. Хотя это два года назад было... Просто думаю, это правильнее в язык вводить, чем просто в IDE.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Ну вцелом было бы неплохо иметь возможность написать что-то в виде:

PHP:
trait FormDBHelper for SomeClass {
    #...
}
 

Adelf

Administrator
Команда форума
Ну это я и хочу.
Или ты имеешь ввиду, чтобы оно само без use туда добавилось? в PHP не получится :) в C# такое есть, но там все компилится.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Я хочу, чтобы это было указанием, что трейт для класса SomeClass и при use его в каком-то другом классе выпихивалось бы Exception.
 

Adelf

Administrator
Команда форума
@c0dex, ну да. Базовый класс или интерфейс. Т.е. обычная проверка как instanceof
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
есть подозрение, что эта фича нужна единицам в мире
 

Adelf

Administrator
Команда форума
@grigori, да на любой трейт глянь - его пишут изначально для работы в каком-то определенном классе или интерфейсе. Судя по нововведениям, от duck typing PHP потихоньку уходит... ну либо мне так кажется.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Пытаюсь осмыслить.
Реализация части методов одного интерфейса - это абстрактный класс.
В трейты выносится общий код нескольких классов, когда его нельзя вынести в родительский класс.
Это методы с общим служебным алгоритмом.
Обычно общие служебные методы выносят в служебные объекты, иногда с декоратором. "Композиция вместо наследования"(С)
Трейты позволяют схитрить - код из классов вынести, а методы объектов оставить.
Причем, трейт - это не monkey patch, декларация трейта должна содержаться в коде класса, в runtime трейт не прицепишь.
Вопрос 1: Какие причины оставлять общие служебные методы в объектах моделей? Ответ для меня не очевиден.

Сигнатура методов, которые включаются в объекты из трейта - это API подключаемой библиотеки.
Ограничить возможность использования трейта - по сути, ограничение видимости методов.
Тебе нужны защищенные методы.
Вопрос 2: зачем ты выносишь их в библиотеку с публичным API?

Мой ответ на твой вопрос классический: суп надо есть ложкой.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Мне кажется, ты на самом деле хочешь interface default methods :)

Trait for class - это какая-то жесть, это примерно как в абстрактном классе знать о конкретных реализациях.

Trait for interface - мейби, но это будут те же default methods.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
чем трейт с указанием допустимого интерфейса отличается от добавления абстрактного класса над классами, реализующими интерфейс?
чтобы добавить трейт - надо так же править декларацию класса
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
с interface default methods как раз-тыки править не надо, плюс это решает проблему зависимости трейта от реализации методов класса - в интерфейсе ж и описаны.

от абстрактного класса отличается наличием множественного наследования

хотя необходимость что в трейтах, что в default methods это признак непродуманной архитектуры :) Я вот посмотрел, где у меня трейты написаны - везде какое-то срезание углов
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
множественное наследование ни при чем, ТС хочет добавить трейт в объект лишь одного интерфейса

классический вопрос про отличие интерфейса от абстрактного класса, @Adelf ;)

P.S. или м'сье знает толк в извращениях, реализуя по несколько интерфейсов в разных комбинациях ...
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
не вижу противоречия ;)

trait TA for interface IA
trait TB for interface IB

class C implements IA, IB use TA, TB
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
да на любой трейт глянь - его пишут изначально для работы в каком-то определенном классе или интерфейсе
противоречие в постановке задачи - ему не бывает нужен трейт для множества интерфейсов
 

AnrDaemon

Продвинутый новичок
Вам не кажется, что было бы приятно в PHP добавить к трейту условия на класс, который может этот трейт юзать?
А вам не кажется, что трейты лучше не юзать? Что это опять PHP3 и сбор проекта из тысяч никак не связанных файлов?
 

Adelf

Administrator
Команда форума
Во-первых, у меня все ок работает :) Мне только автокомплита не хватает. Если я точно знаю, что трэйт будет юзаться только в нужных мне классах, то хотелось бы по $this->... получать список методов того класса.
Возможно у меня laravel головного мозга. Я просто часто свыкаюсь со средой, где работаю и перенимаю привычки оттуда. в ларавель много где трэйты используются.
В данном конкретном случае, я их юзаю для моделей. У меня бывают модели, где поддерживается вывод разных данных для разных локалей. Т.е. русский или английский вариант. Я сначала сделал abstract class MultiLanguageModel extends EloquentModel где реализовал нужные методы и классы наследовал от него. А еще есть другая функциональность(EventBased скажем), тоже для моделей. И тоже хотел абстрактный класс для них... потом понял, что в паре классов нужна и та и другая функциональность. В итоге сделал трэйты MultiLanguage, EventBased и заюзал их в нужных моделях. Все работает как надо, а кода минимум. Не хватает только автокомплита, когда пишешь трэйты.
 
Сверху