Kompozycja (która) się opłaca

8 lat ewolucji architektury Magento

Marzec 2007

i "Inteligentny Autoloader"

Core

Community

Local

"Leniwi" programiści kopiujący całe moduły
z core/ do local/ by zmienić pojedyncze metody.

i Wszechmogący Singleton

Inicjowanie modeli?

Mage::getModel('core/url_rewrite')

... i helperów

Mage::helper('customer')

Logowanie zdarzeń?

Mage::log('Customer cannot be saved.')

Informacje o sklepie?

Mage::app()->getStore()

Publikowanie zdarzeń

Mage::dispatchEvent('my_own_event')

Zarządzanie rejestrem

Mage::register('my_variable', 'and value')
Mage::registry('my_variable')

i Wszechobecne Dziedziczenie

... a nowy, lekki model?

class MyCompany_Module_Model_Customer extends Mage_Core_Model_Abstract

No to przynajmniej surowy helper?

class MyCompany_Module_Helper_Data extends Mage_Core_Helper_Abstract

Dodatkowa metoda w modelu?

class MyCompany_Module_Model_Customer extends Mage_Customer_Model_Customer

... używane przez programistów nawet gdy pisali klasy kompletnie niezwiązane z Magento

i Rozszerzalność Klas

... hola! To nie wszystko.

require_once Mage::getModuleDir('controllers', 'Mage_Customer').DS.'AccountController.php'

Nowa akcja w kontrolerze?

class MyCompany_Module_AccountController extends Mage_Customer_AccountController

... bo Magento nie jest w stanie załadować oryginalnego, nadpisywanego przez nas Controllera

Stwórzmy nowy kontroler

class MyCompany_Module_CustomController extends Mage_Core_Controller_Front_Action

i Globalna Konfiguracja XML

Każda wartość konfiguracji w XML...

<global>
   <models>
      <customer>
          <rewrite>
              <customer>MyCompany_Customer_Model_Customer</customer>
          </rewrite>
      </customer>
   </models>
</global>

Parsowana jest do jednej ogromnej tablicy konfiguracyjnej.
Wygrywa ten moduł, który nadpisze konfigurację jako ostatni.

i Wścibskie Observery

Zarówno w Core, jak i zewnętrznych modułach...

class Mage_CurrencySymbol_Model_Observer
{
    public function currencyDisplayOptions(Varien_Event_Observer $observer)
    {
        $baseCode = $observer->getEvent()->getBaseCode();
        $currencyOptions = $observer->getEvent()->getCurrencyOptions();
        $currencyOptions->setData(Mage::helper('currencysymbol')
            ->getCurrencyOptions($baseCode));
        return $this;
    }
}

Observery modyfikują otrzymane dane!

Listopad 2015

Developers should understand that Magento 2 way of doing something is actually OOP way of doing something. We did not invent a wheel.

We just try to follow good OOP/OOD practices.

IGOR MINIAILO

Magento 2 architect, part of Community Engineering Team

i PSR (PHP Standard Recommendation)

namespace MyCompany\MyModule\Model;

class MyModel implements IdentityInterface
{
    ...
}

Jasno określone w dokumentacji "Programming Best Practices"

https://devdocs.magento.com/guides/v2.2/ext-best-practices/extension-coding/common-programming-bp.html

i Dependency Injection

namespace MyCompany\MyModule\Setup;

use Magento\Framework\Setup\UpgradeDataInterface;

class UpgradeData implements UpgradeDataInterface
{
    ...

    public function __construct(
        BlockRepositoryInterface $blockRepository,
        BlockInterfaceFactory $blockFactory
    ) {
        $this->blockRepository = $blockRepository;
        $this->blockFactory = $blockFactory;
    }

    ...
}

Potrzebujesz? Wstrzykujesz!

i koncepcja Service Contract

Klasy abstrakcyjne

Interfejsy

Rozmowa z "innym" modułem odbywa się poprzez Interfejsy zdefiniowane w API

public function __construct(ProductInterface $product) {
    ...
}
<preference for="Magento\Catalog\Api\Data\ProductInterface"
    type="Magento\Catalog\Model\Product" />

Wskazanie preferowanej implementacji interfejsu

<type name="MyCompany\Module\Controller\ProductController">
    <arguments>
        <argument name="product" xsi:type="object">MyCompany\Module\Model\Product</argument>
    </arguments>
</type>

Wstrzyknięcie konkretnej implementacji interfejsu

i Wzorzec Proxy (Interceptor)

Rozszerzalność metod publicznych przez kompozycję

i Konfiguracja szyta na miarę

Typy stref w Magento:

- Panel Administratora (adminhtml)

- Store front (frontend)

- Podstawowa (base)

- Web API REST (webapi_rest)

- Web API SOAP (webapi_soap)

i Niezależne Observery

Zakaz modyfikowania danych przekazanych do Event'u

https://devdocs.magento.com/guides/v2.2/coding-standards/technical-guidelines.html#14-events
class SampleEventObserverThatModifiesInputs
{
    /**
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /** @var \Magento\Framework\App\DataObject $transport */
        $transport = $observer->getData('transport');

        if ($transport->getData('some_value') === true) {
            $transport->setData('output_return_value', true);
        }
    }
}

... no i gdzie ta kompozycja?

Ciągłe dążenie społeczności do pozbycia się "legacy"

277 309 open

4300 7584 closed

... i dekompozycja architektury u podstaw

Obecnie

Docelowo

Catalog

CatalogAdmin

Catalog

CatalogWebAPI

CatalogAPI

CatalogPWA

CatalogStorefront

CatalogProxy

Łukasz Bajsarowicz

Nazywam się

Magento Developer dla 

Kompozycja (która) się opłaca! 8 lat ewolucji Magento

By Łukasz Bajsarowicz

Kompozycja (która) się opłaca! 8 lat ewolucji Magento

Prezentacja wygłoszona podczas PHPers Summit 2018 w Poznaniu, poświęcona ewolucji Magento na przestrzenii 8 lat począwszy od Magento 1 do Magento 2.

  • 184