- Repository is the Model that is supposed to be used to expose the data for a given entity. In practice, they may optimise how the data is loaded. For instance, product repository uses a caching mechanism
- Factory is used to create an instance of a Model that loads an entity (Magento auto-generates Factory class in generated folder)
similarity: they both lead to read/gather data for an entity
difference: if the entity is meant to be exposed with an API, the repository will be the model used whereas factory only loads data (and returns an object). Factory has more granularity than repository; meaning it is easier to customise the collection factory query than customising a repository getList method (playing with extension attributes is more abstract than playing with sql)
plugin is a way to intercept public functions for most classes in Magento. It can intercept before/around or after (as you well know indeed)
observer enables the developer to intercept a place in the system where the event for the observer is triggered.
similarity: they both intercept a place in the Magento system.
difference: plugin extends a class to customise its behaviour and observer extends the system by enabling additional logic/action to be happening within the observer. Observers are often more intricate to debug because they can spread the code logic amongst several places in the system whereas plugin follows the flow of features more naturally
quote/quote items: we use these anywhere in the frontend website when we want to interact with the items to be purchased in the customer session. items when we change product related info (price, tax, qty..) and quote when we interact with total for instance
order/order items: we use these mostly in checkout when the order is placed or customer order history and backend; order for dealing with order details (address, customer, total, status) and order items to read cart data for the order
differences: quote data are most often used for session data and order data for are used for data that have had a payment transaction/or payment commitment made against them
similarity: they both read data that are related to customer purchases. Most of the data structures are identical: customer, customer address, tax, cart, totals
Apologies, it is clear some people would make a better job for it but I'd thought I'd give it a go tonight, thanks for asking this question
UPDATE:
Below is an example that shows how repository and factory get used and more importanlty how factory is very much hands-on whilst repository is more abstract
<?php
namespace Mbs\ProductListWithImage\ViewModel;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
class ExampleRepositoryAndFactory
{
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
private $productRepository;
/**
* @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
*/
private $productCollectionFactory;
/**
* @var FilterBuilder
*/
private $filterBuilder;
/**
* @var SearchCriteriaBuilder
*/
private $searchCriteriaBuilder;
public function __construct(
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
FilterBuilder $filterBuilder,
SearchCriteriaBuilder $searchCriteriaBuilder
) {
$this->productRepository = $productRepository;
$this->productCollectionFactory = $productCollectionFactory;
$this->filterBuilder = $filterBuilder;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
}
public function getProductByIds($productIds)
{
$collection = $this->productCollectionFactory->create();
$collection->addFieldToSelect('small_image');
$collection->addUrlRewrite();
$collection->addFieldToSelect('name');
$collection->addIdFilter($productIds);
if ($collection->count() > 0) {
foreach ($collection as $item) {
// do things with product data
}
}
$searchCriteria = $this->searchCriteriaBuilder
->addFilter('entity_id', $productIds, 'in')
->create();
$result = $this->productRepository->getList($searchCriteria);
if ($result->getTotalCount()>0) {
foreach ($result->getItems() as $item) {
// do things with product data
}
}
}
}