Ну, тут элемент словоблудия есть конечно, согласен, имелось в виду, что диспетчеризацию запросов в приложении можно строить по разному, использование REST-принципов, а именно, анализ вида запроса и content negotiation в дополнение к разбору адреса наиболее универсально по сравнению с традиционной системой routes а-ля Rails первых версий и URL patterns в Django, например. Ну то есть под универсальностью понимается минимум ограничений в системе роутинга, как-то так.
За исключением последнего примера найти ошибку в выражении не сложнее, чем найти ее же в ассоциативном массиве с количеством уровней вложенности > 1, что в общем то вполне себе часто встречаемый паттерн. Причем в случае массива можно еще, например, в имени ключа опечататься (а в случае объектов — в имени свойства) и это никак не контролируется. В случае вероятность заметить ошибку может быть выше.
В PHP в этом смысле вообще весело, от опечаток может гарантированно защитить только 100% покрытие юнит-тестами :)
По поводу __get() etc — я думал вы про производительность скажете.
Что касается отсутствия свойства у объекта — у нас это решается наличием стандартных интерфейсов для объектов, которые поддерживают динамические свойства. Называется Core_PropertyAccessInterface, его поддержка гарантирует одновременную реализацию __get, __set, __isset и __unset, реализация интерфейса также подразумевает следование определенной модели обработки этих свойств, в частности, генерацию исключений, если это нужно.
На и по поводу последнего тезиса — если это мощный инструмент, чего ж его не использовать? В случае PHP он закрывает массу вопросов, как минимум:
1. честную инкапсуляцию свойств свойств объекта без необходимости реализации массы тупых методов доступа типа get{Property}/set{Property};
2. поддержку read-only свойств опять же без get{Property};
3. вычисляемые свойства.
Можно, в принципе, писать на PHP как на классической Java — с access-методами, бинами и т.д., но тогда лучше сразу на Java, где все стандартно, строго типизировано и не надо ничего изобретать. Посмотрите исходники Shindig, например, такой стиль выбран намеренно (портировали с Java) — на это без слез не взглянешь.
Ничего не имею против присваиваний. Я же не призываю _все_ приложение так писать.
Теперь по поводу DI. Это немного из другой оперы, как мне кажется. В случае DI у нас есть некий интерфейс и различные его реализации, контейнер позволяет управлять тем, какая конкретная реализация используется в том или ином случае. Собственно, поэтому это так востребовано в Java: стандартная спецификация определяет интерфейсы и все им следуют, в т.ч. различные вендоры. В случае PHP, кстати, никаких общих интерфейсов, кроме SPL, как то особенно и не сложилось.
Мы же просто строим систему связанных экземпляров объектов, реализация которых однозначна, во многих случаях это несложные value objects с минимальной логикой. Мы же не будем описывать схему роутинга адресов страниц, например, с помощью Dependency Injection.
1. ini, XML и YAML — полностью статичны, иногда выгодно иметь возможность что-то в конфиге вычислить. Кстати, встроенному парсингу ini-файлов в PHP вообще ничего нельзя доверить :);
2. Второй пример — там полное практически делегирование вызовов конструируемым объектам, этот набор можно создать и традиционным образом, API допускает использование и без билдера, вообще использование билдеров — всегда опциональная надстройка над традиционным API;
3. ob_* — перестраховка от лишнего текста в конфиге, можно и не использовать, вообще говоря;
4. foreach — это не переписывание штатного foreach, это выполнение дочерних задач в контексте родительской. Альтернатива — длинные скрипты с большим количеством промежуточных присваиваний и циклов foreach, выглядит довольно уныло.
5. Про __get(), __set() и __call() — почему вы так считаете?
Ну, исходный язык такой, что особо не размахнешься, увы. В случае Google AdWords получается, тем не менее, реально короче, там для многих типовых задач альтернатива — написание длинных унылых скриптов с большим количеством промежуточных объектов. Применять, разумеется, следует в очень разумных пределах.
Для расширения языка есть, к сожалению, крайне мало возможностей, в 5.3 получше за счет переопределения статических методов, но все равно это не радикально лучше. Игрушечный язык — игрушечные DSL, как то так :(
Статические фабричные методы, кстати говоря, тем еще хороши, что позволяют создать объект и вызвать его метод в одном выражении (по крайней мере в 5.2 «new Config_DSL_Builder()->load('config.php');» не сработает, а «Config_DSL::Builder()->load()» — сработает).
В этом смысле по соотношению объем кода/полезность лидирует функция:
Да, так и есть (там еще на самом деле есть список параметров со значениями по умолчанию), у каждого модуля определен соответствующий класс, в нем, как правило, фабричные методы и, иногда, упрощенный процедурный фасад (как в perl).
С объектом удобнее работать, как правило, плюс в переопределенные методы можно навешать дополнительную логику, да и вообще выглядит эстетичнее, вроде как.
В PHP в этом смысле вообще весело, от опечаток может гарантированно защитить только 100% покрытие юнит-тестами :)
Что касается отсутствия свойства у объекта — у нас это решается наличием стандартных интерфейсов для объектов, которые поддерживают динамические свойства. Называется Core_PropertyAccessInterface, его поддержка гарантирует одновременную реализацию __get, __set, __isset и __unset, реализация интерфейса также подразумевает следование определенной модели обработки этих свойств, в частности, генерацию исключений, если это нужно.
На и по поводу последнего тезиса — если это мощный инструмент, чего ж его не использовать? В случае PHP он закрывает массу вопросов, как минимум:
1. честную инкапсуляцию свойств свойств объекта без необходимости реализации массы тупых методов доступа типа get{Property}/set{Property};
2. поддержку read-only свойств опять же без get{Property};
3. вычисляемые свойства.
Можно, в принципе, писать на PHP как на классической Java — с access-методами, бинами и т.д., но тогда лучше сразу на Java, где все стандартно, строго типизировано и не надо ничего изобретать. Посмотрите исходники Shindig, например, такой стиль выбран намеренно (портировали с Java) — на это без слез не взглянешь.
Теперь по поводу DI. Это немного из другой оперы, как мне кажется. В случае DI у нас есть некий интерфейс и различные его реализации, контейнер позволяет управлять тем, какая конкретная реализация используется в том или ином случае. Собственно, поэтому это так востребовано в Java: стандартная спецификация определяет интерфейсы и все им следуют, в т.ч. различные вендоры. В случае PHP, кстати, никаких общих интерфейсов, кроме SPL, как то особенно и не сложилось.
Мы же просто строим систему связанных экземпляров объектов, реализация которых однозначна, во многих случаях это несложные value objects с минимальной логикой. Мы же не будем описывать схему роутинга адресов страниц, например, с помощью Dependency Injection.
2. Второй пример — там полное практически делегирование вызовов конструируемым объектам, этот набор можно создать и традиционным образом, API допускает использование и без билдера, вообще использование билдеров — всегда опциональная надстройка над традиционным API;
3. ob_* — перестраховка от лишнего текста в конфиге, можно и не использовать, вообще говоря;
4. foreach — это не переписывание штатного foreach, это выполнение дочерних задач в контексте родительской. Альтернатива — длинные скрипты с большим количеством промежуточных присваиваний и циклов foreach, выглядит довольно уныло.
5. Про __get(), __set() и __call() — почему вы так считаете?
Для расширения языка есть, к сожалению, крайне мало возможностей, в 5.3 получше за счет переопределения статических методов, но все равно это не радикально лучше. Игрушечный язык — игрушечные DSL, как то так :(
В этом смысле по соотношению объем кода/полезность лидирует функция:
Тогда можно: