The Most Popular Extension Builder for Magento 2

With a big catalog of 224+ extensions for your online store

Magento 2 Must-know Design Patterns for Development Success

Magento 2 Design Patterns can become a beneficial assistant if used correctly. In software programming, design patterns are dispensable support for developers. Everything related to building programs becomes more accessible and organized, reducing much work for the dev team. This article will explore the most essential types of design patterns in Magento 2 to find out what they are and the benefits of using each.

Table of Contents

1. Object Manager

Object Manager plays an essential role in Magento 2, replacing the Mage class - a function used to implement and call almost every object in Magento 1. This innovation solves several difficulties with parameter instantiation by establishing a solid connection between the three patterns: object management, dependency injection, and plugins.

Get and Create Methods

Object Manager pattern generates and configures Objects using two main methods: GET and CREATE.


  • Return a singleton object (a class instance that is used to share between multiple components)
  • Provide the same response when calling from 2 places


  • Return an utterly new class instance
  • Provide a new object when calling from 2 places

Object Manager Main Purpose

  • Construct and place the class given in the constructor
  • Run the singleton pattern
  • Control dependencies
  • Automatically instantiate parameters

2. Dependency Injection

What is Dependency Injection?

Dependency Injection (DI) is one of the most crucial design patterns for Magento 2 development, built to replace the Mage class in Magento 1 and handle programming dependencies.

Let’s look at this system by separating its name to see what it is.


  • Meaning when something depends on another one
  • Example: class is dependent on another class/object to perform some functions


  • Meaning: provide something in a third person
  • Example: inject a class into the dependent class Dependency Injection is an object management system used to remove an object’s direct dependency on a class and make objects for that class with a third class.

Magento 2 Dependency Injection

Dependency Injection is made of four following parts:

  • Service object: declares dependencies
  • Client object: is dependent on the service object and inherits dependencies
  • Interface object: determines the ways that the client can use to access the service’s dependencies
  • Injector object: performs the dependencies of the service and passes them to the customer’s object

Dependency Injection

Magento 2 DI can be implemented in 2 ways:

  • Via Constructor: Magento\Catalog\Controller\Adminhtml\Product\Save
  • Via Method: Magento\Catalog\Api\ProductAttributeManagementInterface

3. Factory

What is Factory?

Factory is another essential aspect among other Magento 2 design patterns. The Factory design pattern in Magento 2 is a non-injectable object that enables the instantiation of representative objects for entities. The Object Manager and business code instantiate it. Magento automatically generates the Factory (located in the “generated” folder) with this type: Factory.

Ex: Magento\Catalog\Block\Product\ImageFactory

How to use Factory Design Pattern

  • In the Constructor, Call Factory:
     function __construct(\Magento\Cms\Model\BlockFactory $blockFactory) {
      $this->blockFactory = $blockFactory;

Then, to make a copy of the object, call the create method as follows:

$block = $this->blockFactory->create();
  • In case of multiple classes that need some parameters, directly transfer parameters to create:
    $resultItem = $this->itemFactory->create([
     'title' => $item->getQueryText(),   
     'num_results' => $item->getNumResults(), 

4. Proxies

To developers, Proxy is one of the most efficient Magento 2 design patterns. It can significantly enhance performance and reduce resource consumption when utilized appropriately. It effectively addresses redundancy issues within a project.

Proxy advantages:

  • Simple procedure: only required to declare the “class/Proxy” => the “di.xml” file
  • Enhance the program’s performance
  • A clear framework, easy to understand

5. Preferences

What are Preferences?

The Preference Design Pattern overrides existing classes and extends business logic. It is crucial to use it appropriately, considering other available design patterns like plugins and observers, which may be more suitable in some instances. Preferences are ideal when alternatives like plugins or observers are not applicable.

There are two ways to manage Preferences in Magento 2:

  • /etc/di.xml (Global)
  • /etc//di.xml

Let’s examine an example such as this file: app/code/Mageplaza/Custom/etc/di.xml

<preference for="Magento\Quote\Model\Quote" 
type="Mageplaza\Custom\Model\Quote" />
  • Class A: Magento\Quote\Model\Quote
  • Class B: Bss\Custom\Model\Quote

The next step is to run the loadByCustomer part. At this time, Class B is called as B is required to expand A.

Pros and Cons

Of course, as an alternative to other design patterns, Preferences have different benefits and drawbacks. In details:


  • Simple to use and declare
  • Capable of adjusting most classes in the core
  • Able to modify most functions


  • Conflict with third-party extensions
  • Not able to adjust in case of class directly calls via Object Manager

As the advantages of Preference dominated its disadvantages, it’s pretty clear why this pattern is listed among the must-know Magento 2 design patterns.

6. Argument Replacement

What is Argument Replacement?

Argument Replacement is one of the must-know efficient coding techniques when changing constructor argument without affecting other classes. Argument Replacement’s name in the XML file corresponds to the name used in class. For instance, in this file: vendor/magento/module-catalog/etc/di.xml In the constructor of this class: Magento\Catalog\Helper\Product:

Types of Argument

  • Object ```
{typeName} {typeName}
- String
{strValue} {strValue}
- Boolean
- Number
- Init_parameter


- Const


- Null
- Array
### Pros and Cons

- Diverse types to modify the class
- Flexible

- Complex framework
- Strict structure requirement

## 7. Virtual Types
In Magento 2, Virtual Types provide a way to modify existing classes without impacting other classes or needing to create new class files. They offer the flexibility to inject these Virtual Types wherever they are required.
In other words, Virtual Types can be considered as a sub-class for an existing class. 

## 8. Events and observers
Whenever someone wants to modify a class in Magento, events and observers usually come up in their mind. Let’s discuss each one in detail!

### Events
Events can be activated by the module’s action. Notably, events and observers share the same data so that you can change the input data. Additionally, Magento enables us to customize events to modify data.

**Dispatching Events**
To create a new event, utilize the class Magento\Framework\Event\ManagerInterface. The dispatch function within this class can be used to instantiate the desired event name for dispatching.

Code example:

**Event Areas**
Events are categorized into three types based on the events.xml file:
- etc/adminhtml/events.xml – adminhtml
- etc/frontend/events.xml – frontend
- etc/events.xml – global

### Observers
We use Observers to catch events and modify input data, allowing for adjustments to logic and more.

**Create an Observer**
To generate a new observer, place your file in the <module-root>/Observer folder and inherit the class Magento\Framework\Event\ObserverInterface.

Code example: 

Subscribe events
Utilize the XML file to declare events and observers.
Example: <module-root>/etc/adminhtml/events.xml
After adding the products successfully, it’s likely to move to the execution part of the class AddProductObserver. Then you are free to edit data transmitted through the checkout_cart_add_product_complete event, which already includes request and response. 

If you want to turn off events, just insert **disable =“true”** after the observer.

## 9. Plugins
Another approach for customizing a feature in Magento 2 is to use Plugins. The technique can be used on any public method in a class, interface, or framework.
However, it is essential to note that Plugins cannot be applied to the following cases:
- Final method
- Final class
- Non-public method
- Static class method
- __constructor
- Virtual Type
- Objects that are instantiated through Magento\Framework\Interception

So, how can we declare the Plugin? You’re going to need the di.xml file for this. 


Required elements:

  • Type name: Name of class or interface to edit
  • Plugin name: Name of the plugin
  • Plugin type: Name of the plugin to edit

Optional elements:

  • Sort order: Execution order of the plugin
  • Disabled: Turn off the plugin

Three ways to use the Plugin method:

  • Before: Modify a function’s input data
  • Around: Modify a function’s operation process
  • After: Modify output data

Pros and Cons:


  • Clear framework
  • Flexible
  • Suitable for most public method functions


  • Incapable of the protected and private method
  • Unable to be modified if the class is called directly via Object Manager

10. Repositories

Regarding reading, modifying, or deleting entities, Repositories, and Factories are similar. On the other hand, factories are mainly used for building new entities. Repositories support Soap/Rest API as part of the service contracts- interface.

It’s a bit different when applying these methods:

  • ProductRepository: Returns specified data as defined in the \Magento\Catalog\Api\Data\ProductInterface business code. Unnecessary data will be removed, and cached data will be retrieved from the disk instead of directly from the Model via the database.

  • ProductFactory: Returns model entity’s complete data, including potentially unnecessary information.

In summary, if Repositories meet your requirements, using them instead of Factories is highly recommended.

11. Injectable/Non-Injectable Object

Last but not least, Injectable and Non-Injectable are also crucial Magento 2 design patterns. Let’s get to know more about them!

There are two kinds of Objects in Magento 2 Dependency Injection: Injectable and Non-Injectable. Here are some notes about this pattern:

  • Injectable object: singleton objects that can be instantiated and shared by the Object Manager in Magento. These objects can have dependencies on other objects and are typically defined in the di.xml configuration file.
  • Non-injectable object: cannot be instantiated by the Object Manager and require manual instantiation. Both of these objects often have a shorter lifespan and may require input data before they can be created.

In reality, most models in Magento are non-injectable objects. Let’s take Product as an example. It actually needs the product ID for transmission.


So, this article has provided a detailed explanation of some of the essential Magento 2 design patterns. While there are more design patterns available, the ones covered here are fundamental to understanding Magento 2 development. By implementing these efficient coding techniques, you can enhance your Magento 2 projects and improve code organization, performance, and maintainability. We hope that this blog has been helpful to you and that you can apply these design patterns successfully in your Magento 2 projects.

Image Description
Sam is the CEO & co-founder of Mageplaza, a company established to support Magento merchants with different powerful tools and resources. Sam Nguyen is also the CEO & founder of Avada Commerce, an e-commerce solution provider headquartered in Singapore – aiming to support more than a million online businesses to grow and develop.
Website Support
& Maintenance Services

Make sure your store is not only in good shape but also thriving with a professional team yet at an affordable price.

Get Started
mageplaza services

    People also searched for


    Stay in the know

    Get special offers on the latest news from Mageplaza.

    Earn $10 in reward now!

    Earn $10 in reward now!

    go up