Есть такое понятие, как best practices. Никто не говорит, что твой подход не работает. Просто понимание того, сколько времени понадобится на перепил в большинстве типичных случаев приходит только с количеством сделанных рефакторингов. Ты можешь использовать любую практику и тратить время на перепилы множества высокосвязанных мест, вместо того, что бы наслаждаться пивом. А можешь использовать обкатанные практики и работать не напрягаясь, внося точечные изменения в небольших количествах. Практика элементарная: не связывай код конретными именами классов и всегда оставляй возможность для расширения класса (модификация через наследование и внедрение зависимостей). Не нужно думать, что ты настолько гениален, что можешь сегодня предугадать что будет лучше для этого участка кода через месяц или год. Просто пиши так, что бы в случае необходимости ты мог легко вносить изменения в код. Для этого код должен быть слабосвязанным, расширяемым и повторно используемым. Открываешь википедию, читаешь SOLID и смотришь, как статические вызов влияет на код по каждому пункту.От части согласен, но не вижу проблемы если использовать статические методы только для класс-специфичных вещей, а на ограничение до одного инстанса иду сознательно,
если честно, я просто не могу понять реальных проблем которых дает такое решение,
вот, например, есть объект приложения, его тоже надо делать не синглтоном? я сейчас про реальные потенциальные приложения на практике
для тестов можно будет всегда подменить зависимости и инициировать заново
Ну ты попробуй унаследуй и переопредели с новой реализацией, а потом нам расскажешь. В твоем последнем примере interface DIPuttable абсолютно лишен смысла. Интерфейс говорит буквальноЯ понимаю, но разве мой вариант закрыт для расширения?
У тебя нет ни одного экземпляра. Если твой этот код работает, то только изза "особенностей" реализации PHP. Потому что в нормальном языке ты был бы послан по причине неоднозначности между статическим методом и имплементируемым интерфейсом DIPuttable. Твоя реализация метода входит в противоречие с требованиями интерфейса по области действия.любой, кто имплементирует этот интерфейс имеет методы _класса_ с такими вот сигнатурами. По этому, вы можете вызывать эти методы, если оперируете с _экземпляром_ производным от DIPuttable.
У тебя твой класс жестко связан с классом контейнера. В нем прописано имя класса контейнера. Это значит что твой класс зависит от класса контейнера, хотя непосредственно для работы в этом нет никакой необходимости. Тут уже писали про сервис-локатор. Да, это вариант, но не лучший. Но он на порядок удачнее, чем твой первый вариант связка статического метода + впрыск в конструктор.И чисто практический вопрос - чем передача в конструктор зависимости лучше, чем получение из контейнера, как у меня?
А это и есть единственная причина. Инверсия контроля называется. При правильном применении позволяет значительно повысить качество кода по всем параметрам.Мм, одну причину сам вспомнил, есть фреймы которые могут сами определять потребности в объекта и передавать ему ту или иную зависимость, а еще?
Пожалуйста, не называй фреймворки устаревшим html-тегом.Мм, одну причину сам вспомнил, есть фреймы которые могут сами определять потребности в объекта и передавать ему ту или иную зависимость, а еще?
естественно, для этого значение которое возвращает функция getDIKey в классе OtherClass1_Fake должно совпадать с OtherClass1PHP:class OtherClass1{} class OtherClass1_Fake{}DIContainer::set(OtherClass1::getDIKey(), new OtherClass1_Fake()); \DIContainer::get(OtherClass1::getDIKey())->getInstanceFromDI(); // Seems class hasnt been initiated yet
да, я сделал ошибку, методы в интерфейсе надо сделать статическимиУ тебя твой класс жестко связан с классом контейнера. В нем прописано имя класса контейнера. Это значит что твой класс зависит от класса контейнера, хотя непосредственно для работы в этом нет никакой необходимости. Тут уже писали про сервис-локатор. Да, это вариант, но не лучший. Но он на порядок удачнее, чем твой первый вариант связка статического метода + впрыск в конструктор.
Нет. Ты пытаешься сделать ошибку используя интерфейс там где это не нужно. Методы интерфейса не могут быть статическими. Интерфейс работает на основе полиморфизма, как и наследование. Статические члены не полиморфны. Статические члены жестко привязаны к классу, то есть к реализации. Полиморфные члены работают только для объектов классов. Объект имеет таблицу методов, которая может быть переписана (перегружена). Класс не имеет такой динамической возможности. Это очевидно. Потому что если ты перегрузишь метод класса, ты сломаешь шаблон класса, то есть получишь сломанный (поврежденный) тип - тип данных, который не соответствует изначально данному описанию класса. Полиморфны только объекты. Выкинь статику и не ломай себе мозг. Эти красоты с точками в именах не стоят того.да, я сделал ошибку, методы в интерфейсе надо сделать статическими
Никак не добавить, если язык этого не позволяет. Да это и не нужно. Ты не на том фокусируешься. Ты фокусируешься на расширении, а нужно на использовании.Если честно не понял, как набор методов у объекта может быть изменен динамически? Js, python да, но как в php уже созданному объекту добавить метод?
И в любом случае ведь полиморфность проявляется как раз в перегрузке методов класса, а не объекта, разве я не прав?
function doSomething(DIPuttable $puttable);