Сборщики магии на Varien_Object
(M1) и DataObject
(M2) являются обычной практикой, но с Magento 2 кажется неправильным использовать его.
Хорошо:
- легко читать / писать
Плохо
- Это вызывает проблемы при использовании цифр в ключах (см .: Magento 2: другой способ получить поле коллекции или атрибут Get Get Product с использованием верблюда )
- инструменты анализа кода жалуются на несуществующие методы
Вопрос
С Magento 2 у нас есть два новых метода:
getDataByKey($key)
getDataByPath($path)
Есть ли веская причина, чтобы все еще использовать getData($key)
или какие-нибудь магические добытчики?
Редактировать:
@ Винай спасибо. Я не упомянул @method
метод, потому что мой подход был совсем другим.
Это только помогает IDE, но не влияет на другие вещи.
Существует несколько PR mergedf, которые являются «микрооптимизациями», такими как приведение (int)
вместо intval()
или получение размера массива вне циклов (даже для небольших массивов).
С другой стороны, есть
магические добытчики, у которых есть некоторые "накладные расходы", как описал Мариус ....
strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
getData($key)
Методы также должны пройти 2-3 дополнительных проверки ...if ('' === $key) {
if (strpos($key, '/')) {
if ($index !== null) {
Для собственного кода полностью согласен отдавать предпочтение реальным методам, но в тех же случаях это не возможно ... например, вы создали пользовательское событие ...
$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');
Использование 3-го с /** @var some $value */
мне кажется лучшим. (?)
Ответы:
Вышеупомянутый вопрос об использовании магических методов против
getDataByKey
илиgetDataByPath
. Я думаю, что есть и третий вариант, который реализует реальные методы получения и установки.У
getData*
всех методов есть недостаток в том, что они должны быть аннотированы для вывода типа для работы.Обычно это делается с помощью
/* @var string $foo */
аннотации надgetData*
звонком.Это немного вонючий, потому что тип данных должен быть объявлен в классе, который содержит данные, а не в классе, который вызывает
getData*
.Причиной этого является то, что если данные изменяются, класс, скорее всего, будет обновляться не всеми
getData*
сайтами вызовов.Вот почему я думаю, что реальные методы повышают удобство обслуживания по сравнению с использованием методов
getData*
доступа.Поэтому я думаю, что это сводится к компромиссу между ремонтопригодностью и более быстрой реализацией (меньше кода для написания).
К счастью, в настоящее время IDE действительно хороши в создании для нас реализаций getter и setter, так что этот аргумент больше не применяется.
Еще один аргумент против магических методов получения и установки, который отсутствует в приведенном выше вопросе, заключается в том, что для них невозможно создать плагины.
Единственное другое значение, которое, я думаю, я могу добавить к этой теме, - это попытаться собрать причины, по которым можно использовать или не использовать
@method
аннотации, если по какой-то причине о реализации реальных методов не может быть и речи.Pros
@method
Аннотации немного меньше коды записи по сравнению с реализацией реального получения и установки. Это едва ли верно в настоящее время, потому что IDE хороши в создании методов доступа, так что это больше не является реальным преимуществом.Cons
@method
аннотация, и реальный метод с одинаковыми именами, сигнатура типа аннотации переопределяет реальный метод во время статического анализа кода, что противоположно тому, что делает интерпретатор PHP. Это снова может легко привести к тонким ошибкам.По указанным выше причинам я лично не использую
@method
аннотации, если могу их избежать.Для кода, который предназначен для жизни долго, я реализую реальные методы получения и установки. Повышение удобства обслуживания стоит усилий по запуску среды IDE для их генерации.
Для более экспериментального кода во время всплеска или для простой детализации модуля я
getData*
тоже использую методы, потому что я ленивый.источник
Да, это вонючий, но можно (и нужно?) Избежать. Я думаю, что это очень распространенный код и часто предлагается:
Проблема в том, что вы просто предполагаете, что возвращаемое значение имеет тип
Foo
с вызываемымgetId()
методом.Для удобства обслуживания почему бы не принять тип переменной и добавить
InvalidArgumentException
?Это также исправляет статический анализ кода в случае, если он
$model->getProduct()
имеет разные типы возврата - напримерFoo|false
. В первом случае он будет жаловаться на звонкиdoSomething()
по возможностиfalse
.источник