I have had a chance to speak at Magento Live UK 2016 with topic "Key Insights into Development Design Patterns for Magento 2". Feel free to share, comment, provide feedback.
In the deck i highlight Development Design Patterns used in Magento 2. I also speak about Aspect Oriented Programming and how it affected Magento 2 implementation.
More about Magento 2 read at my blog: https://www.maxpronko.com/
6. What is Design Pattern?
describes a problem which occurs over and over again,
and then describes the core of the solution to that
problem, without ever doing it the same way twice
“
- Christopher Alexander
7. Composite pattern is used to treat a group of objects in
similar way as a single object uniformly
Composite Pattern
13. Strategy Pattern
class CaptureStrategy implements BuilderInterface {
/** @var BuilderInterface */
protected $partial;
/** @var BuilderInterface */
protected $capture;
public function build(array $buildSubject) {
$condition = //set condition
if ($condition) {
return $this->partial->build($buildSubject);
}
return $this->capture->build($buildSubject);
}
}
14. Define an interface for creating an object, but let
subclasses decide which class to instantiate. Factory
Method lets a class defer instantiation to subclasses
Factory Method Pattern
16. Transfer Factory Example
namespace MagentoBraintreeGatewayHttp;
class TransferFactory implements TransferFactoryInterface
{
private $transferBuilder;
public function __construct(TransferBuilder $transferBuilder) {
$this->transferBuilder = $transferBuilder;
}
public function create(array $request) {
return $this->transferBuilder
->setBody($request)
->build();
}
}
17. Transfer Factory Example
namespace MagentoBraintreeGatewayHttp;
class TransferFactory implements TransferFactoryInterface
{
private $transferBuilder;
public function __construct(TransferBuilder $transferBuilder) {
$this->transferBuilder = $transferBuilder;
}
public function create(array $request) {
return $this->transferBuilder
->setBody($request)
->build();
}
}
class GatewayCommand implements CommandInterface {
public function execute(array $commandSubject) {
$transferO = $this->transferFactory->create(
$this->requestBuilder->build($commandSubject)
);
$response = $this->client->placeRequest($transferO)
// … code
}
}
18. Define a one-to-many dependency between objects so
that when one object changes state, all its dependents
are notified and updated automatically
Observer Pattern
27. Object Manager Usage
Good
• Factory
• Builder
• Proxy
• Application
• generated classes
Bad
• Data Objects
• Business Objects
• Action Controllers
• Mage::getModel like calls
• Blocks
28. Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for
extending functionality
Decorator Pattern
36. a programming paradigm that aims to increase modularity
by allowing the separation of cross-cutting concerns. The
goal is to achieve loose coupling
Aspect Oriented Programming
39. Types of a Plugin
Method
Before After
Around
Affects input
method argument
Modifies behaviour
Affects method
return value
40. Check Module Status Plugin
After
Around
namespace MagentoFrameworkModulePlugin;
class DbStatusValidator
{
public function aroundDispatch(
MagentoFrameworkAppFrontController $subject,
Closure $proceed,
MagentoFrameworkAppRequestInterface $request
) {
if (!$this->cache->load('db_is_up_to_date')) {
$errors = $this->dbVersionInfo->getDbVersionErrors();
if ($errors) {
// throw exception
} else {
$this->cache->save('true', 'db_is_up_to_date');
}
}
return $proceed($request);
}
}
41. Invalidate Cache Plugin
After
Around
namespace MagentoWebapiSecurityModelPlugin;
class CacheInvalidator
{
public function afterAfterSave(
MagentoFrameworkAppConfigValue $subject,
MagentoFrameworkAppConfigValue $result
) {
if (condition) {
$this->cacheTypeList->invalidate(MagentoWebapiModelCacheTypeWebapi::TYPE_IDENTIFIER);
}
return $result;
}
}
42. Password Security Check Plugin
After
Around
namespace MagentoSecurityModelPlugin;
class AccountManagement
{
public function beforeInitiatePasswordReset(
AccountManagementOriginal $accountManagement,
$email,
$template,
$websiteId = null
) {
$this->securityManager->performSecurityCheck(
PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST,
$email
);
return [$email, $template, $websiteId];
}
}
Big changes compare to M1, everything become possible
Solid architectural goals
- flexibility, upgradability
- time to market
- scalable
- service contracts
- unit simplicity
smalltalk book, remember almost nothing.
overview of the class - Builds payment gateway request - capture or auth
builders array is a builder interface
as a result - prepares key value ready to convert to xml/dom/soap request
Di.xml config
virtual type! - idea
Single responsibility
later added to transport factory
Magento 2 only capture request (no partial)
CaptureStrategy to allow send partial request
In Magento it is not always enough events
auto-generated code
Object Manager enables Proxy support for all objects
Instantiates object only during first method call
Auto-generated class
Extends Original class
Implements Magento\Framework\ObjectManager\NoninterceptableInterface interface
Proxies all calls to original class
Additional behavior to existing code (an advice) without modifying the code itself
Separately specifying - "log all function calls when the function's name begins with 'set'".
This allows behaviors that are not central to the business logic to be added to a program without cluttering the code core to the functionality.
AOP forms a basis for aspect-oriented software development.