Как стать автором
Обновить

Комментарии 18

НЛО прилетело и опубликовало эту надпись здесь
Да, занятный класс на 2500 строк с 35-ю параметрами в конструкторе.
Это всеобщая тенденция на сегодняшний день. Не знаю как оно по скорости, но работать с такими моделями очень удобно. На Symfony похоже.
0_o

Каким это боком похоже на Symfony?

    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
        AttributeValueFactory $customAttributeFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService,
        Product\Url $url,
        Product\Link $productLink,
        \Magento\Catalog\Model\Product\Configuration\Item\OptionFactory $itemOptionFactory,
        \Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory $stockItemFactory,
        \Magento\Catalog\Model\Product\OptionFactory $catalogProductOptionFactory,
        \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
        \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus,
        \Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig,
        Product\Type $catalogProductType,
        \Magento\Framework\Module\Manager $moduleManager,
        \Magento\Catalog\Helper\Product $catalogProduct,
        \Magento\Catalog\Model\ResourceModel\Product $resource,
        \Magento\Catalog\Model\ResourceModel\Product\Collection $resourceCollection,
        \Magento\Framework\Data\CollectionFactory $collectionFactory,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry,
        \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
        \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor,
        \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
        CategoryRepositoryInterface $categoryRepository,
        Product\Image\CacheFactory $imageCacheFactory,
        \Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider,
        \Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider,
        \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory,
        \Magento\Catalog\Api\Data\ProductLinkExtensionFactory $productLinkExtensionFactory,
        EntryConverterPool $mediaGalleryEntryConverterPool,
        \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
        \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor,
        array $data = []
    )
Возможно, это был сарказм?
На самом деле это намного лучше Symfony. В Мадженто DI для классов сущностей нигде не передается DI контейнер (ObjectManager в терминологии Мадженто), только сущности, которые необходимы конкретному классу. DI контейнер используется только в фабриках, но фабрики в Мадженто это автогенерируемые сущности, поэтому в 90% случаев вам не прийдется их писать руками. Поэтому любая сущность в Мадженто (Модель, Блок, Контроллер) легко покрывается юнит тестами. Достать один из классов и показывать его конструктор — это не интересно и абсолютно не показательно. Более того, когда в Мадженто 1 данная модель содержала в себе все те же зависимости, но использовала внутри себя Service Locator для их инстанциации этого никто не замечал и все с этим жили. DI показал много проблем в зависимостях у классов и модулях, между которыми не должно быть этих зависимостей. Более того, то что вы показываете (модель продукта) это имплементация модели, Мадженто 2 предоставляет Service Layer набор публичных API интерфейсов у каждого из модулей, и именно эти интерфейсы предполагаются будут использованы и расширены (плагинизированы) 3rd party программистами. Эти интерфейсы считаются стабильными, и Мадженто обязуется не менять их без очень острой нужды. И соответственно если такая нужда возникает, то апгрейдится мажорная версия модуля (aka семантическое версионирование). Поэтому зависимости на имплементацию, т.е. в данном случае на модель продукта считается не верными, т.к. Мадженто не гарантирует, что имплементация не будет меняться (даже правильней сказать, что гарантировано, что они будут меняться). Собственно сервис леер и вводился для того, чтобы скрыть имплементация, и всегда иметь возможность провести нужный рефакторинг, не влияя на существующие расширения и контракты. Как и в данном случае, за счет того, что у модуля Catalog есть свои API, предполагается, что программисты будут использовать их, а конкретно эту модельку мы всегда можем отрефакторить, и никто от этого не пострадает
НЛО прилетело и опубликовало эту надпись здесь
Вы не внимательно прочитали мой ответ. Прочитайте еще раз.
Single Responsibility принцип это хорошо, и по возможности нужно ему следовать. Но, мы говорим о проекте с более чем 2к классами и огромным числом зависимостей.
Когда DI приходит в такой проект — он обнажает много проблем. Часть из которых более важны, часть — менее.
Если кинуться и исправлять весь код и приводить в соответствие с SOLID это приведет к огромным трудозатратам, но в итоге мы все равно прийдем к проблеме, которая была в Мадженто 1. Когда у нас все классы являлись контрактами для расширения, и в итоге мы никогда не можем изменять их (менять названия методов, удалять методы, менять сигнатуры), потому что это поломает чей-то код. Код, который расширяет через наследование, например. Поэтому та же Мадженто 1 обросла PhpDoc @depricated, чтобы показывать, какие методы мы хотим исключить из контрактов.

Service Layer призван решить эту проблему и зафиксировать интерфейсы взаимодействия с 3rd party программистами.

Я искренне благодарен вам за то, что вы даете такие ценные советы с чем мне стоит разобраться, но вы сами абсолютно не разобравшись в вопросе, просто достаете какой-то фрагмент кода и пытаетесь ловить лулзы. Что выглядит странно и не профессионально. Более того, уверен, что вы даже не нашли этот конструктор самостоятельно, т.к. в этом случае вам бы пришлось посмотреть код, разделение ответственностей, API и т.д. А нашли ссылку на этот конструктор в твиттере, которая ходила пару месяцев назад.

А каким образом это
Мадженто 2 предоставляет Service Layer набор публичных API интерфейсов у каждого из модулей, и именно эти интерфейсы предполагаются будут использованы и расширены (плагинизированы) 3rd party программистами.

связано с таким жирным конструктором?

И почему вы под DI понимаете Service Locator?
Так, давайте еще раз. А то, как-то все смешалось.

1. Это связано с жирным конструктором таким образом, что мы решили строить Service Layer для того, чтобы у нас была возможность всегда вносить изменения (читай рефакторить) конкретные реализации. Данный фрагмент конструктора является конкретной реализацией, и программисты кастомизаторы не должны на него зависеть, для этого у них есть публичные интерфейсы и механизмы их расширения (плагины, событийная модель, предоставление собственной реализации по контракту). Поэтому рефакторинг конкретно этого класса (да, сейчас он выглядит не идеально и нарушает принцип единой ответственности) стал менее приоритетным по сравнению с введением публичных контрактов модуля Catalog, в котором он находится.

По-хорошему, кастомизатору и любому не core Magento программисту в него смотреть вообще не имеет смысла. Поэтому рефакторинг этого класса есть в наших планах, но далеко не в ближайших.

2. По поводу Service Locator. Я как раз под DI не понимаю Service Locator, читайте внимательней. Service Locator это шаблон, который использовался в первой версии Magento, где все внешние зависимости создавались по месту их использования с помощью методов Mage::getModel(), Mage::getSingleton(). DI появился во второй версии мадженто и заменил собой Service Locator
Вы извините, но как ещё понимать эти фразы?
В Мадженто DI для классов сущностей нигде не передается DI контейнер (ObjectManager в терминологии Мадженто), только сущности, которые необходимы конкретному классу.

DI контейнер и не должен никуда передаваться. Передаётся сервис локатор.

Или вот это?
Более того, когда в Мадженто 1 данная модель содержала в себе все те же зависимости, но использовала внутри себя Service Locator для их инстанциации этого никто не замечал и все с этим жили. DI показал много проблем в зависимостях у классов и модулях, между которыми не должно быть этих зависимостей.

Почему пишется про сервис локатор, и потом как следствие упоминаются проблемы в DI?
И каким образом DI создаёт эти проблемы? Тем более что в приведённом коде самый настоящий DI.
DI контейнер и не должен никуда передаваться. Передаётся сервис локатор.


Когда я говорил про DI контейнер я имел в виду сущность, которая в Symfony называется Service Container. Т.е. сущность ответственная за создание сущностей в приложении.

Так вот, в Magento эта сущность называется ObjectManager и она НЕ передается (не должна передаваться) в создаваемые бизнес сущности. Классы имеют зависимости только на другие классы, которые им нужны для выполнения бизнес задач, и не имеют служебных зависимостей на сервис контейнер. Соответственно код бизнес сущностей написан так, что они не знают о существовании ObjectManager и DI в проекте.

Здесь можно подробней почитать про DI в Magento 2

Почему пишется про сервис локатор, и потом как следствие упоминаются проблемы в DI? И каким образом DI создаёт эти проблемы?


Вы не внимательно читаете мои ответы:

Более того, когда в Мадженто 1 данная модель содержала в себе все те же зависимости, но использовала внутри себя Service Locator для их инстанциации этого никто не замечал и все с этим жили. DI показал много проблем в зависимостях у классов и модулях, между которыми не должно быть этих зависимостей.


DI не создает эти проблемы — он их показывает. Проблема с лишними зависимостями в этом классе была всегда, т.е. со времен Мадженто 1, но это было не так очевидно. Потому что в каких-то местах (внутри тела класса) использовался ServiceLocator для создания нужных зависимостей, в других местах использовался Registry, для получения уже инстанциированных сущностей из регистра. В М2 появился DI и конструкторная иньекция. Соответственно все зависимости этой модели перешли в конструктор. И нарушение SRP стало очевидным.
Может имело бы смысл написать отдельный пост на Хабре, т.к. вчера зарелизилась Magento 2 GA
И осветить в нем отдельные вопросы, которые, как я вижу, вызывают много вопросов:
  • Service Layer в Magento 2. Что это, зачем. Как использовать
  • Механизм Плагинизации
  • Как мы (команда Magento) видит правильную работу интеграторов с Magento 2
  • Кодогенерация в Magento 2

Может быть какие-то другие темы будут также интересны. Потому что сам фреймворк М2 очень технологичен и современен, поэтому некоторые вещи на первый взгляд вызывают много вопросов и не всегда правильно поняты. Это как iPhone, которым по словам Стива Джобса не все правильно держали в руках, когда звонят, поэтому уровень сигнала падал :)
я уже ответил на это ниже, никто не спешил.
А это вообще что??? Я конечно понимаю, что можно погуглить, но обычно в новостях хотя бы слово говорят о том, что из себя представляет сабж.
Спасибо за замечание. В следующей новости о релизе обязательно уточню «лидер opensource ecommerce систем». :)
Спасибо за уточнение. Теперь я точно знаю, что мне новость не нужна.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации