Architecture Challenges

Magento 2 Customizations

About Me

  • One of former members of Magento 1.x Core Team
  • I love to take challanges
  • I love to optimize performance
  • I give trainings and independent consultancy

Are there any Software Architects?

Are there any Senior Developers?

Are there any Middle Developers?

Are there any Junior Developers?

Every developer in this room is a Software Architect

We are all responsible for our Software Design

Architecting software is hard...

For example in the beggining of 2007

ZF1 just went into first beta (0.8.0)

Symfony 1.0 just got released

Composer?

Unit testing was not yet a thing

Everyone was using Subversion (SVN)

I wish I knew everything I know now back then

But then we wouldn't have this talk today

Magento 2.x is a refactor of legacy 1.x

Challange #0: Using Magento 1.x approach

Magento 2.x is a huge step ahead, learning new concepts hard at first

I am happy Magento 2.x does not use Symfony and Doctine

Challenge #1: Looking at the core modules to create your own functionality

There are some new code, but mostly it is still good old Magento 1.x code

Do not look at the core module for an example of implemenation.

Even Magento_Customer module is not the best example.


namespace Magento\Customer\Model\Customer;

class Customer extends \Magento\Framework\Model\AbstractModel
{
    public function __construct(
    	\Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Eav\Model\Config $config,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Customer\Model\ResourceModel\Customer $resource,
        \Magento\Customer\Model\Config\Share $configShare,
        \Magento\Customer\Model\AddressFactory $addressFactory,
        \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressesFactory,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
        GroupRepositoryInterface $groupRepository,
        \Magento\Framework\Encryption\EncryptorInterface $encryptor,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        CustomerInterfaceFactory $customerDataFactory,
        DataObjectProcessor $dataObjectProcessor,
        \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
        \Magento\Customer\Api\CustomerMetadataInterface $metadataService,
        \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
    }
}

This is a dependency hell from 1.x

So avoid looking into Magento core modules

Look at http://devdocs.magento.com/ instead

Challenge #2: Data model dependencies

Global Website Store (GWS)

Binding your data model to GWS leads to scaling issues of your implementation

Example

  • EU Merchant can sell to 28 member states
  • Countries might have more then one language
  • Every country might get own domain name
  • Price might differ per country

Problem

  • You might end up with 100+ store views
  • Language+Country results in data duplications in EAV structure

Avoid existing structures where possible and inverse your dependencies

Challenge #3: Extending existing functionality

Rewrite is a bad thing

(not because of conflicts)

Plugin is a bad thing

(unless you are doing it on interface)

Dependency Injection is a good thing

Substitution is a good thing

(but only for interfaces)

Challenge #4: Depending on concrete implementation

Injecting concrete class from another component leads to fragile dependency

Protect your code by introducing own abstractions

How To

  • Find functionality you want to use from Magento 2 module
  • Create your own interface for that implementation
  • Create adapter based on that interface with Magento 2 module class as dependency

Over-engeneering?

You are abstracting your business logic from concerete framework implementation

It means you can re-use your business logic in Magento 1.x or any other platform

The Ultimate Challenge

Porting M1 code to M2

Is it really a challange?

It is a great opportunity

How To

  • Drive your new design by BDD
  • Start from highlevel abstractions
  • Introduce new code by referencing requirements from existing one
  • Abstract your business logic from the platform
  • Create adapters for framework specific code

Workshop

Tomorrow we are going to take that challange together

Learn about SOLID principles as we design new module

Join it at 14:00 and 16:30

Thank You

Q&A