Расширение класса внешними методами и переменными

WMix

герр M:)ller
Партнер клуба
Здесь очень емко описана суть вопроса:
PHP:
// обьяви interface
interface ModuleUser{
  function init();
  function getRecords();
}

// тут сторонние разработчики вольны делать что хотят
class First implements ModuleUser{
 // bla bla
}

// пользуй
function x(ModuleUser $mu){}
x(new First);
x(new Second);
 

StalkerClasses

Новичок
PHP:
// обьяви interface
interface ModuleUser{
  function init();
  function getRecords();
}

// тут сторонние разработчики вольны делать что хотят
class First implements ModuleUser{
// bla bla
}

// пользуй
function x(ModuleUser $mu){}
x(new First);
x(new Second);
Интерфейсы не предполагают методы и переменные.
 

grigori

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

Yoskaldyr

"Спамер"
Партнер клуба
не пойму в чем проблема - всему миру, миллиону разработчиков на java и php хватает интерфейсов и обычного наследования,
@grigori, небольшой оффтоп, не имеющий прямого отношения к ТС. Я понимаю что для обычного приложения всякие извращения не нужны. Но если есть коробочный продукт, который необходимо чтобы была возможность расширить сторонними модулями как угодно. Я понимаю что сверхгибкость, которая вообще не нужна для 99% обычных приложений и понимаю насколько это хрупкий будет код. Но как еще сделать возможность такого расширения, кроме как использовать подход как реализовано в xenforo, magento (и судя по всему практику переняли другие коробочные решения учитывая ссылки ТС-а) или использовать aop?
 

StalkerClasses

Новичок
Мне не горит. Но хотелось бы все таки реализовать нечно подобное. Как понял есть class_alias и это можно реализовать. Хотелось бы несколько примеров как реализовать. aop это это? http://aop-php.github.io/
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@grigori, небольшой оффтоп, не имеющий прямого отношения к ТС. Я понимаю что для обычного приложения всякие извращения не нужны. Но если есть коробочный продукт, который необходимо чтобы была возможность расширить сторонними модулями как угодно. Я понимаю что сверхгибкость, которая вообще не нужна для 99% обычных приложений и понимаю насколько это хрупкий будет код. Но как еще сделать возможность такого расширения, кроме как использовать подход как реализовано в xenforo, magento (и судя по всему практику переняли другие коробочные решения учитывая ссылки ТС-а) или использовать aop?
лучше псевдокодом напиши пример где именно нужна сверхгибкость,
из статьи по ссылке я вижу то же самое, что сделано в yii, а в laravel это реализовано цепочкой ответственности и называется middleware
какая еще гибкость тут нужна и при чем тут вообще наследование?
 

Yoskaldyr

"Спамер"
Партнер клуба
из статьи по ссылке я вижу то же самое, что сделано в yii
Что-то не помню чтобы в yii были промежуточные прокси классы при наследовании... Может пропустил, можно ссылку на код?

в laravel это реализовано цепочкой ответственности и называется middleware
с мидлварями все понятно, когда надо управлять на уровне больших логических блоков или при переходах между слоями приложения (но это и событиями можно разрулить) или коммандбас . А если брать какой-то конкретный класс из больше чем одного метода и если внутри эти методы взаимосвязаны и надо немного изменить поведение одного из методов, то мидлварями уже не обойтись.

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

25517

Новичок
лучше псевдокодом напиши пример где именно нужна сверхгибкость,
из статьи по ссылке я вижу то же самое, что сделано в yii, а в laravel это реализовано цепочкой ответственности и называется middleware
какая еще гибкость тут нужна и при чем тут вообще наследование?
Всегда вызывается метод dateNow() класса "А", который выводит дату в timestamp.

Я как разработчик стороннего плагина хочу чтобы вместо таймстампа мне выводилась дата в формате Y-m-d.
Собственно, хуков в этом месте нет. Как мне переопределить этот метод? Правильно расширить тот самый класс "А".
Но, все кто вызывает этот метод, они обращаются к родительскому классу. Менять название родительского класса везде где он встречается ? Бред.
Тут на помощь и приходит такая система расширения.

Пы.Сы. Работал с xenForo2 и знаю, что такая система в принципе необходима для коробочного продукта.
 

Yoskaldyr

"Спамер"
Партнер клуба
@25517 Не совсем верно. Запрашивается не класс A, а запрашивается через контейнер - что-то подходящее по сигнатуре под класс А.
А это или сам этот класс или правильный динамически отнаследованный класс-наследник.
Если какой-то дибил запрашивает напрямую объект A (а такого треша у разработчиков дополнений хоть отбавляй), то тут без черной магии типа go-aop или softmocks - никак. Т.е. контейнер выдает правильную конкретную реализацию, как и любой другой контейнер любого фреймворка.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
это что, заразная болезнь - "классово-ориентированное программирование" головного мозга?
PHP Объектно-Ориентированный, запрашивают не "объект A", а метод $a::foo()
Если уж я могу расширить "тот самый класс "А", я спокойно передам декоратор и обойдусь без наследования.
 

Yoskaldyr

"Спамер"
Партнер клуба
@grigori Я уже писал насчет декораторов, они хороши, но не всегда.
Когда надо единократно расширить/изменить - без проблем. А если будет 20-30 различных дополнений которые будут декорировать одно и тоже - вот веселый багодром будет.
Очень часто в декораторы добавляют __call __get магию и скорость работы всего это ну очень веселая и магическая тогда.
 

Yoskaldyr

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

fixxxer

К.О.
Партнер клуба
Вы оба два не тот язык выбрали.
Берите Ruby с его include-ами.
В тех же Рельсах все живет на миксинах и прочем манкипатчинге, все как вы любите.
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer я привет пример только одного конкретного юзкейса где данный костыль имеет смысл - все остальные костыли еще более костыльные. Все остальные варианты которые предложили здесь или значительно менее поддерживаемые или тормознутые при большом количестве расширений (и да все перечисленное уже пробовал за последние 10 лет) или вариант просто не решает поставленной задачи многократного независимого расширения или исходит из предположения что разработчик расширения должен заранее знать кто еще будет расширять это место (возможно только когда расширения пишутся в пределах одной команды).

И я прекрасно отдаю отчет в том насколько это костыль и знаю все его минусы. Но вот ТС в принципе не понимает что он делает - это видно по вопросам которые задает.

И в продолжении этого костыля - тянуть его в обычную разработку - нельзя (вот ТС хочет и флаг ему в руки).
И я даже пару раз встречал когда что-то подобное уже использовалось в небольших конторах. Когда у них спрашиваешь "А нахера"? Так ответы - удобно что-то менять и расширять и так видели в других продуктах. Задаешь еще один вопрос - "Код только сами пишете?", ответ "Конечно!". Фейспалм, занавес, расходимся...

@fixxxer ты же за typescript топишь, так там же тоже любой патчинг можно сделать если не закрывать контекст модифицируемых классов? Значит если так сравнивать, то typescript равно ruby :)))))
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@grigori Я уже писал насчет декораторов, они хороши, но не всегда.
Когда надо единократно расширить/изменить - без проблем. А если будет 20-30 различных дополнений которые будут декорировать одно и тоже - вот веселый багодром будет.
так я ж мысли читать не умею, про "20-30 различных дополнений" никто не писал,
вы пишите однозначно и четко: "интегрировать в существующий класс методы и свойства из другого", и "если брать какой-то конкретный класс", а когда вам отвечают по существу - начинается сарказм про тряпку для быка

чего голову морочите?
 
Сверху