Чи є історія колекцій у Magento 2?


25

Я знаю, що багато Magento 2 (2.1.2) є більш-менш перенесеним з Magento 1 і що багато коду буде замінено еквівалентом у майбутньому. У цьому аспекті мені цікаво, яке майбутнє у колекціях Magento 2.

Дозволь пояснити:

Magento 1:

У Magento 1 ми звикли отримувати колекцію так:

$products = Mage::getModel('catalog/product')->getCollection();

Потім ми можемо застосувати фільтри та інші операції до колекції:

$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...

І останнє, але не менш важливе, наша колекція повертає моделі:

foreach ($products as $product) {
    echo get_class($product); // Mage_Catalog_Model_Product
}

Magento 2:

Magento додає багато нових шарів абстракції, реалізуючи більш ТВОРИЙ спосіб роботи. Це означає, що коли ми хочемо список об'єктів, ми запитуємо його з сховища:

$productResults = $this->productRepository->getList($searchCriteria);

Якщо ми хочемо застосувати фільтри ми використовуємо комбінацію з SearchCriteriaBuilder, то FilterGroupBuilder, то FilterBuilderі SortOrderBuilder:

$this->searchCriteriaBuilder->addSortOrder(
    $this->sortOrderBuilder
        ->setField('created_at')
        ->setAscendingDirection()
        ->create()
);
$priceFilter = $this->filterBuilder
    ->setField('price')
    ->setValue(10)
    ->setConditionType('gteq')
    ->create();
$createdAtFilter = $this->filterBuilder
    ->setField('created_at')
    ->setValue('2016-10-10')
    ->setConditionType('lt')
    ->create();
$filterGroups = [
    $this->filterGroupBuilder->addFilter($priceFilter)->create(),
    $this->filterGroupBuilder->addFilter($createdAtFilter)->create()
];

І якщо ми хочемо повторити свої результати, ми отримаємо Моделі даних, а не фактичні (успадковані) моделі:

foreach ($productResults->getItems() as $product) {
    echo get_class($product); // \Magento\Catalog\Model\Data\Product
}

Цей вид абстракції відповідає принципу SOLID і охоплює принцип "склад над успадкуванням" . Будь-які "екзотичні" операції, які б інакше були зроблені на колекції (як приєднання до прикладів), здійснюються внутрішньо в сховищі, що також полегшує використання поза модулем.

Питання:

Все це змушує мене замислитись: маючи в майбутньому підсистему сховища / даних модель, чи є в майбутньому приміщення Magento 2 для колекцій? Чи використовуються колекції тільки внутрішньо самим модулем, а не поза ним? Або ж це буде застарілим на користь менеджера суб'єктів господарювання?

В даний час, якщо ви хочете прийняти Моделі даних, вам все одно доведеться створити успадковану модель (успадковану від \Magento\Framework\Model\AbstractModel) лише для того, щоб колекція працювала (оскільки Magento\Framework\Data\Collection::setItemObjectClassпотрібно, щоб модель поширювалася з Magento\Framework\DataObject). І вам потрібна колекція, щоб мати можливість фільтрувати у вашому сховищі. Але знову ж таки, у сховищі вам доведеться "перетворити" свою (звичайну) модель в модель даних.

Або нам доведеться реалізовувати це як сховище порядку, де getList()повертається екземпляр Magento\Sales\Api\Data\OrderSearchResultInterface, але під водою результати пошуку є не що інше, як звичайна колекція, що реалізує цей інтерфейс. Веселий факт: результати пошуку стверджують, що він поверне масив Моделей даних ( Magento\Sales\Api\Data\OrderInterface[]), але якщо проаналізувати код, getItems()він виконає, Magento\Framework\Data\Collection::getItems()що взамін повертає не моделі даних, а моделі порядку (як встановлено Magento\Sales\Model\ResourceModel\Order\Collection::_construct()). Стільки за «склад над спадщиною».

Дуже багато запитань щодо того, який правильний шлях у Magento 2. Знову є 100 способів зробити те саме, але що таке "Шлях до Мадженто"? Або я просто зовсім не на тому шляху?


2
Задайте справжні запитання тут +1. Я дуже хотів би тут відповісти на основний розробник
Маріус

Я вважаю, що план зборів буде припинено. Однак, як ви помітили, це майже не є близьким до виконання, і існує багато областей, які, здається, знаходяться в різних станах реконструкції (маючи стабільну api як Magento \ Sales \ Api \ Data \ OrderSearchResultInterface, дозволяє Magento замінити те, що буває під кришкою легше згодом). Це не допомагає, що різні реалізації getList ще не настільки здатні, як те, що ми можемо зробити з колекціями. Невідповідність, яку ви зазначили навколо заявленого повернення, може бути вартим для проблеми на Github.
Крістоф у Фомані

Відповіді:


16

Колекції зараз не застарілі. Хоча деякі модулі вже розкривають API контрактів на послуги, інші все ще розкривають лише моделі API / Collection.

План такий:

  1. Відображайте поточний стан з кращим охопленням @api: коментуйте абстрактні колекції та конкретні колекції в деяких модулях за допомогою @api
  2. Удосконалити рамки стійкості, щоб забезпечити просте створення контрактів на обслуговування, не покладаючись на API, засновані на спадку: колекції, моделі, моделі ресурсів
  3. Вимкніть абстрактну колекцію, щоб не сприяти здійсненню Контрактів на обслуговування на основі колекції
  4. Поступово випускайте новіші версії модулів з API контрактів на обслуговування

Тож колекції в якийсь момент будуть застарілими, але зараз вони є одним з API Magento 2.

Що стосується виконання контрактів на обслуговування, - Моделі та колекції - єдиний зручний спосіб їх реалізації в Magento <= 2.1. Договори на обслуговування - це лише інтерфейси. Їх реалізація не є частиною публічного API і може бути змінена пізніше.


1
Дякую за вашу відповідь. То яка ваша порада розробникам, які створюють нові модулі? Моя нинішня стратегія полягає у створенні контрактів на обслуговування, які (під водою) все ще використовують колекції, тому що: а) це робить фільтрацію легкою, і б) менеджер об'єктів все ще занадто експериментальний / недокументований. В якийсь момент внутрішню роботу можна замінити чим-небудь іншим, але інтерфейс залишається тим самим. Але якщо я правильно зрозумів вашу відповідь, це зараз правильний шлях?
Giel Berkers

Правильно. Я відредагував свою відповідь, щоб це відобразити.
Антон Криль

1
Враховуючи викладене, який би був правильний спосіб впровадити функціонал, який вимагає даних, які неможливо отримати за допомогою контрактів на обслуговування? Наприклад, якщо модуль А вимагає всіх замовлень, відфільтрованих за способом оплати.
Степан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.