This presentation is about real examples of Design Patterns usage in Magento 2. There are 2 major architectural goals set for Magento 2 project:
1. Enable streamline customisations.
2. Simplify external integrations.
There are much more Design Patterns used in Magento 2, some of them are discussed in the deck.
5. SINGLE RESPONSIBILITY PRINCIPLE
➤ Class should have only 1 reason to change.
namespace MagentoCmsControllerPage;
class View extends MagentoFrameworkAppActionAction
{
/** code */
public function execute()
{
$pageId = $this->getRequest()->getParam('page_id', $this->getRequest()->getParam('id', false));
$resultPage = $this->_objectManager->get('MagentoCmsHelperPage')->prepareResultPage($this,
$pageId);
if (!$resultPage) {
$resultForward = $this->resultForwardFactory->create();
return $resultForward->forward('noroute');
}
return $resultPage;
}
}
5
6. OPEN/CLOSED PRINCIPLE
➤ Classes should be open for extension, but closed for
modification.
namespace MagentoCatalogControllerAdminhtmlCategory;
class RefreshPath extends MagentoCatalogControllerAdminhtmlCategory
{
/** code */
public function execute()
{
$categoryId = (int)$this->getRequest()->getParam('id');
if ($categoryId) {
$category = $this->_objectManager->create('MagentoCatalogModelCategory')->load($categoryId);
/** @var MagentoFrameworkControllerResultJson $resultJson */
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData(['id' => $categoryId, 'path' => $category->getPath()]);
}
}
}
6
8. INTERFACE SEGREGATION PRINCIPLE
➤ Client should not be forced to depend on methods it does not
use.
namespace MagentoPaymentGatewayHttp;
interface TransferInterface
{
public function getClientConfig();
public function getMethod();
public function getHeaders();
public function shouldEncode(); //Client Zend
public function getBody();
public function getUri(); //Client Zend
public function getAuthUsername(); // None
public function getAuthPassword(); // None
}
namespace MagentoPaymentGatewayHttpTransfer;
interface AuthInterface
{
public function getUsername();
public function getPassword();
}
interface ZendUrlEncoderInterface
{
public function shouldEncode();
}
interface ConfigInterface
{
public function getValue();
}
namespace MagentoPaymentGatewayHttp;
interface TransferInterface
{
public function getMethod();
public function getHeaders();
public function getBody();
}
Decoupling example
8
Might be improved
9. DEPENDENCY INVERSION PRINCIPLE
➤ High-level modules should not depend on low-level modules.
Both should depend on abstractions.namespace MagentoFramework;
class Image
{
/**
* @var ImageAdapterAdapterInterface
*/
protected $_adapter;
public function __construct(
MagentoFrameworkImageAdapterAdapterInterface $adapter,
$fileName = null
) {
$this->_adapter = $adapter;
$this->_fileName = $fileName;
if (isset($fileName)) {
$this->open();
}
}
/** code */
}
9
10. SOME TIPS
➤ Create tiny classes to avoid
monsters
➤ Build your code on
abstractions (interfaces)
➤ Look inside code for good
practices
➤ Refactor, refactor, refactor
10
12. “Each pattern describes a problem which occurs over and over
again in our environment, and then describes the core of the
solution to that problem, in such a way that you can use this
solution a million times over, without ever doing it the same
way twice
-Christopher Alexander
DESIGN PATTERNS
12