We all come across issues where there is a need to rewrite the same model (class) in two different modules. It usually happens with an extension which implements some logic changes, e.g., Mage_Sales_Model_Order class. At the same time, we have our own extension which implements other changes to the same model via rewrite as well. In order to keep both extensions operating, and to keep logic separated in order that extensions remain compatible with possible updates, we need to refer to several basics of Magento.
First, ensure that implementation of the required changes/logic is impossible without rewriting a class/model. Extending default functionality via observers by subscribing to some specific event is the best method. Moreover, you can subscribe to an event in a predefined scope:
– only for admin area,
– only for front-end.
For this you simply need to add listener to a specific config section: adminhtml, frontend or global.
However, achieving a desired result only with the help of observers can become complicated, which can then necessitate a total rewrite of the specific class/model. To do this properly, we have to take a step back, look at loading fallback, and consider how it actually works.
Basically, Magento locates its extensions in 3 code pools:
– community and
In addition, Magento loads it’s module configuration in the following order:
3. All others in alphabetical order.
Once all configuration files are loaded, Magento will check the section of each config and will put modules after the ones mentioned in this section.
In this way, we ensure that our module is loaded only after the required modules have already been loaded. For example, let’s assume module A is rewritten by module B at the same time we need to implement some changes in the scope of module C. In this case, we will configure our module C with a dependence on module B and will specify rewriting the class from module A. The only thing which remains for us to do is to extend our class from the class located in module B, so that the existing changes in module B are preserved.
Here is a short example. Assuming that there are two modules which must be rewritten, i.e., Sales/Order model, this is how we can define these modules:
As per sample above, the configuration for CoreValue_AutoSupply will be loaded after Mage_Sales. CoreValue_Installment will be loaded after CoreValue_AutoSupply.
Here is a sample configuration of each module as it relates to rewrites.
Now let’s take a look at the actual php files.
This way we ensure that the instance of CoreValue_Installment_Model_Sales_Order will be created on Mage::getModel(‘sales/order’).
In both classes, i.e., CoreValue_Installment_Model_Sales_Order and CoreValue_AutoSupply_Model_Sales_Order, we are rewriting function _checkState():
As a result, each module encompasses changes applied by the Parent class and applies its own changes where required.
This method of applying as many rewrites as needed also saves original logic and time. It does not eliminate the need to be extremely careful when making these changes so as not to break any of the default functionalities.
Senior Engineer, CoreValue
CoreValue is hosting a 3-day open intensive course starting on the 7th of June, 2017 in Wrocław, Poland.
The course is taught by experienced Salesforce practitioner and offers the developers an opportunity to boost their Salesforce skills. Follow the link to register here.
Dmytro Smirnov, a keynote speaker, certified Senior Salesforce Tech Engineer at CoreValue, will introduce Salesforce platform development and discuss main development aspects.
The attendees will also be able to network with colleagues who develop and implement Salesforce and to expand their knowledge during the hands-on workshop. Details here
Salesforce is the world’s leading CRM software and enterprise cloud ecosystem that transforms companies by helping them streamline their businesses activities.
CoreValue will help software professionals learn from experts and give them a competitive edge leading to new career possibilities.
Event details and registration http://bit.ly/2qZe3fp
CoreValue, a Software and Technology Services firm headquartered in New Jersey with Development Labs in Eastern Europe, provides Mobility and traditional Cloud based CRM implementation services, Mobile applications in Pharmaceutical, Medical, Financial Services, Media and Legal verticals. Customers trust CoreValue to provide Infrastructure services utilizing premier staff in Data Science, Data Management, Database Services, Quality Assurance and traditional development.
The term micro-services has been part of the tech lexicon for half-a-decade, but still there is much confusion about its benefits and applications. For many emerging technology practices, appropriate application of this architecture can be a great enabler to drive technology delivery exponentially faster. At the same time, using it simply as a technology patch with traditionally structured engineering teams leads only to unwanted overhead and complexity.
The following article is an examination of decisive factors to help determine whether or not micro-services architecture can be of benefit to any given organization.
For example, micro-services architecture can assist a software development organization to scale its delivery through the use of small autonomous teams, which in turn can also enhance the efficiency of individual engineers. A distinct element of any engineering problem is easier to define, and more likely to result in shorter release life-cycles. Smaller applications/services, also mean simpler management and simpler deployment processes, etc.
Distinctive characteristics of Micro-Services
As the name would suggest, the size is the crucial factor. The typical largish micro-service will contain no more than a few hundred to few thousand lines of code, to be delivered from scratch to MPV in 1-6 weeks by a team of 1-4 engineers. It will utilize a simple and lightweight framework, if not a servlet. Most micro-services have either a persist data model consisting of 2-8 entities, when in 3rd Normal Form, or no database at all. This characteristic eliminates the need for a powerful persistence layer and database abstraction, such as Spring, just to store, for example, two logical class entries in a simple relational database.
Granular and specific
A micro-service should solve a concrete and clearly defined problem. If the problem has, for instance, two aspects, which do not share the same programming logic, consider building two micro-services. Consider building micro-services as adaptors, bridges and decorators to existing services. In general, similar principles employed to avoid scope creep in the design of source-code class structure are valid in the world of micro-services.
Autonomous and agnostic
To keep the scope as small as possible, a micro-service will still have its own logical meaning and re-usable value. It can also be black-box tested with logically meaningful scenarios. A reusable micro-service is a well designed micro-service.
Managing external dependencies is crucial to planning, the delivery cycle, testing and release, and may be completely asynchronous from other services. A common mistake is to be influenced by the desire for central control, common in the design of monolith systems. Routing, authentication, identity management, set-up routine services, etc., will still need to be aware of multiple other services, but that usage should be limited to reference and enumeration only.
Note this example. There is a trap inherent with the design a central administration area that is aware of the specific-problem logic of each service. The trap lies in the number of dependencies that such an approach introduces. A well designed central service should not need to be changed beyond simple run-time configuration in order to include a new member service. To avoid direct dependencies, consider:
inversion of control;
external-plugin-in style API interface which will allow dependency injection;
simple SSO-ed iframe mash-up of user-interfaces from different micro services.
A truly independent micro-service can be radically re-written from scratch in order to replace its internal implementation, seamlessly from the point of view of another service. It can even be re-written on entirely different technology stack, while the change remains invisible to any other micro-service.
Such a degree of flexibility and independence always proves its value and saves time in the medium and long run. The major project, where no elements need to be re-written or severely modified during the course of its delivery, has yet to be found.
What does all this give us?
Flexible delivery team structure is the key
The first and and most sought-after benefit is a small self-organizing team structure around which all delivery revolves. Whether the company’s delivery methodology is classic SCRUM with fixed teams owning a number of micro-services between releases; an FDD agile with a Feature Team formed for each micro-service; a more conservative RAD with teams and services organized around graphical interface elements etc. smaller and independent teams give flexibility and remove the overhead of constant synchronization. In addition, each service development has a different optimal pace.
As an example, a micro-service dealing with a user interface for capturing data for medical appointments via web-form will have frequent releases and multiple demo interactions. On the other hand, an algorithmically heavy service, e.g., dealing with appointment booking optimization, etc., will be developed in a more conservative fashion with similarities to clean-room coding techniques, a lot of automated testing and in larger iterations.
Obviously, the complexity and effort to synchronize dependencies have been removed from the individual service delivery teams and now reside directly with the system Architect. This is the desired state of affairs when the strategic approach of organization is focused on intelligent architecture.
Individual Engineer Efficiency
As postulated in the The Mythical Man-Month: Essays on Software Engineering, by Fred Brooks, the ability to scale and speed-up a delivery process depends heavily on the level of functional decomposition, degree of structured encapsulation, and minimized dependendencies of the system design. This is where micro-service architecture becomes the real champion.
Small concretely defined problems can be fully understood by a single engineer or subject-matter experts on each element of the business logic. There is 100% code ownership, with the highest possible tolerance to diversity in development approaches and matching specialist programmers against their expertise. There is nothing to hold back development from the aspect of management.
Taking the divide-and-conquer approach also means among other things
- no large code merges;no more refactoring unfamiliar code;
- no god-classes and ambiguous structures left as inheritance from long time ago;
- no more time-consuming alignment of test/sandbox deployments;
- no more endless bug tracing across multiple layers of complicated frameworks.
Risk mitigation and adaptivity
Often the size and simplicity of a micro-service allows re-building the entire service in a matter of hours. Legacy code can be re-factored altogether with minimum time loss and other project consequences. To avoid spoiling the speed with which micro-services can be delivered, consider a simple deployment/dev-ops tool which does not require long configuration time or manual operation.
If the possibility of rolling out a service to its previous state, without the need to merge code or synchronize with any functionality or service, sounds attractive, consider also the ability to build throw-away stubs for services or temporary implementations without risk of the code becoming entangled and wasting effort upon removal. “Fail small and fail quick” as the Agile mantra goes.
Shorter release process
In practice, independent delivery and release cycles for each team means improvement of the overall functionality at every release of each service. Wait-time for the completion of a global sprint (the longest common denominator of time) is no longer needed for testing, demos or release. Just by taking the latest working version of each micro-service, one has an operation-ready system. [Note: The flexibility and speed, which micro-service architecture offers when combined with blue-green environment approach and API versioning, will be the subject of Part 2 of this article.]
Right technology for the right task
For decades, large companies have established policies to unify technology stack and development tools. However, diversification of the technology stack can prove to be very effective when looking to build rapidly. As an example of a diverse technology stack, consider a product eco-system, whose development teams chose to use Java for complicated business logic; Django and Angular for front end-presentation; PHP to customize external opens-source CMS modules; and low-level languages for the purpose of building custom, high-efficiency modules. After all, some tools and languages are better at some tasks than others. Most high-end programmers are either polyglots or have personal preferences of technology for solving a problem.
Why not allow the specialist who decides the methodology to solve a problem to also pick the right tool? In the end, it is only a technology agnostic API which connects a micro-service with the rest of the system.
So is it right for me?
Before adoption of micro-service architecture, decide whether or not it is advisable and feasible to change both the structure of delivery and the company culture toward more independence. Small, holistic team approach is what more and more technology companies choose as a basis for growth and consistent delivery. It is a particularly attractive option for new organizations, or those willing to restructure their technology teams from-the-ground-up.
On the other hand, companies with a well established structure, deep hierarchies of engineering roles, centralized specialist departments, long delivery cycles, etc., rarely find practical value in micro-service architecture.
To Be Continued
Part 2 : Optimizing and scaling micro-services. Organic growth of eco-systems.
Senior Technical Architect, CoreValue