A major goal of Magento 2 is to make it even easier to extend and adapt to the needs of merchants wanting a true flexible platform. The service layer work I described in a previous post is a part of this. The service layer helps provide a constrained, well defined API for other modules to call. But there is more being done. While Magento has always had a modular architecture, the current module boundaries are not always ideal. Magento 2 includes significant module rework to improve some of the divisions to make it easier to extend Magento.
Disclaimer: I work with the Magento team, but this post contains personal opinions and perspectives and does not necessarily reflect those of eBay Inc. Or in other words, this post is not binding!
Acknowledgements: This post has borrowed heavily from Anton Kril’s (@AntonKril) presentation at the Magento Imagine 2014 conference.
Framework vs Modules
The first stage of reworking modularity in Magento 2 was to pull out from modules what should be in the underlying Magento framework. Modules are intended for e-commerce functionality. The core framework functionality should be in the framework, not mixed in with modules. As a result, many areas of framework functionality have been pulled from modules and added to the Magento framework. Core from Magento 1 was the biggest example of this – most of Core is now in the Magento Framework. Another example is the Theme module where most of the processing logic has been moved into the Framework (the Theme module still exists in this case – it contains the UI for allowing the site administrator to change which theme to use).
Divide and Conquer
Next, work started on decomposing some existing modules into multiple smaller optional modules. For example, the configurable and grouped product types are now defined in separate modules. If you don’t need grouped products, you can remove that module from your site. Fewer modules means less to maintain, less to go wrong, and a slightly more performant site (less code). Shipping is another module that has been broken up into multiple modules. A module has been defined per major shipping vendor (FedEx, UPS, USPS, etc) allowing a site to be built from the shipping mechanisms supported for the site. It also allows other shipping methods to be more easily incorporated later.
In addition to shipping and product types, other modules being considered for rework (broken up) include payments, sales, and checkout. Feel free to note your favorites in a comment!
It is worth noting that refactoring code to improve modularity is not always straightforward. For example, pulling product types out into multiple modules (rather than being hard coded in a single module) caused some implementation complications. To render a shopping cart containing different product types required some rethinking. The solution taken was to introduce a new block whose purpose was to render the cart. The product types in separate modules then register how to render themselves with this new cart-rendering module.
One focus is to make it so that geographic specific functionality is easier to customize or remove. For example, USPS (US Postal Service) is now in its own module making it easier to remove for non-US sites. This is an ongoing area of development with additional work planned before the developer beta release. More modules under consideration for simplification and rework include: Logging, Admin Notification, RSS, Log, Weee, Tax, and Search. Each is being considered based on merit, while keeping an eye on the Magento 2.0 delivery date.
The Magento team has been working hard on getting Magento 2 ready for release. Not all of the potential modularity rework will be undertaken by the Magento 2.0 dev beta release due to the sheer code volume – the team are focussing on doing the most important ones well. If you have an interest in helping decouple modules please leave a message or otherwise reach out to me. Getting small pockets of experts on specific groups of modules may be one way to get more done before the developer beta. (However, no promises!)
If you look back at an earlier post titled Visualizing Magento 2 Module Dependencies, I described the module dependency graph before the modularity rework began. The sheer number of cross dependencies looks pretty darn scary. Thinking more about it since then, it is hard to capture a data based metric that really indicates success. I mentioned a goal of reducing the number of dependencies, but to make the system more modular, some modules have been broken into smaller (easier to replace) modules. As a result, the total number of dependencies has gone up, but for positive reasons. Cycles are less desirable as you cannot remove modules in the cycle (you need all or none). However they are not unacceptable as there are ways to extend or customize functionality without removing a module. There are also specific places in Magento that people are more likely to customize. Improving such hot-spots is more important than the global metrics. I like metrics to measure progress, but I have not come up with one I like yet.
Progress is being made on cleaning up the internal dependency graph for Magento 2. This is currently based on subjective feedback and customer reported problem areas, rather than mathematical models such as cyclometric complexity. More importantly, there are a number of key technologies going into Magento 2 to help improve modularization. Getting these into the framework now is more important than improving all of the module dependencies as the dependencies can be tackled incrementally in future releases with relatively minor impact. Changing the underlying framework can have a much greater impact. So what are some of these technologies?
- Enhanced layout files supporting better inheritance and extension, making it easier for one module to add it’s UI components to another module.
- Cleaner HTML markup separating presentation from structure, making it easier to repurpose existing HTML by adjusting the CSS without markup changes.
- Better separation of HTML markup into template files (out of PHP code) making it easier for other modules to override such HTML.
- The introduction of the service layer, as a part of separating presentation code from business logic and defining well defined APIs to be used for dependencies between modules.
- Dependency injection, which makes it simpler to replace one implementation of a class with another.
- Plugins, which allow one module to inject code into the flow of another module without going to the extreme of class rewrites (which cause conflicts when multiple modules want to extend the same class).
I plan to cover more of these topics in future posts.