How PayU improves code testability with MVVM architecture:- www.deekpay.com
In this article, I will describe how PayU migrated its application and SDK to an MVVM architecture to enhance code testability, scalability, and readability. Over the past few years, we have made several iterative user interface (UI) updates while the core business logic has remained largely unchanged (with the exception of new features). However, with the original architecture, it was difficult for us to keep up with the pace of updates required to grow the business. Therefore, we focused on redesigning the underlying architecture to make the code more readable, scalable, and testable by adopting MVVM architecture.
What did we do before?
Until then, we followed the MVC pattern. In theory, this pattern seemed to work well for us, but as the codebase grew and the UI iterations increased, we realised that the codebase became unmanageable for two reasons:
With each UI iteration, we change not only the UI code, but also the business logic. This is a direct indication that our UI is not fully separated from the business logic.
As our code base expands, the amount of unit test code we have decreases - meaning we are relying more and more on end-to-end testing. This in itself is a bad sign, as our test pyramid is turned upside down.
We are moving in the wrong direction (left to right).
When we try to understand the problem, we realise that both View and Controller depend on Model. In addition, Activity and Fragment contain both UI logic and controller logic. As a result, the amount of code for our unit tests decreases and the code becomes unmanageable.
MVC architecture
MVVM Architecture Redemption
We started looking for a better architecture and that's when MVVM became our salvation. Even, Google favoured MVVM.
MVVM stands for Model-View-View Model:
Model: represents the data layer of the application.
View: represents the UI logic of the application.
ViewModel: is the model of the view. It serves as a bridge between the view and the model and does not directly reference the view.
The MVVM architecture removes the tight coupling between components. Child components do not directly reference the parent component, they only do so through observable properties. Note that each component only depends on the next level component. This design creates a coherent and enjoyable user experience.
Another important component in the above diagram is the Repository module. It handles data manipulation. It provides a clear API so that other parts of the application can easily retrieve data. It knows where to get the data from and what API calls need to be performed when the data is updated. You can think of the repository as a mediator between different data sources such as persistence models, web services, and caches.
LiveData is an observable data holder. Other components of the application can use this holder to monitor changes to objects without creating explicit and fixed dependency paths.The LiveData component also respects the lifecycle state of application components such as activities, fragments, and services, and includes cleanup logic to prevent object leaks and excessive memory consumption.
vantage
Separation of concerns: It's a common mistake to write all of your code in an Activity or Fragment. the UI classes should only contain logic that handles the interaction between the UI and the operating system. By keeping these classes as simple as possible you can avoid many of the problems associated with the lifecycle.MVVM lets you ensure that each type of class is responsible for only one task.
Testability: The user interface and interactions can be tested by instrumenting test cases (Espresso library). ViewModels (ViewModels) and the repository (Repository) can be tested using JUnit .
Extensibility: you can easily introduce UI updates. Add new features without refactoring or changing large parts of your existing code base. We can insert and pull components more easily.
Manageability: the code base is more manageable - all UI logic in one place, business logic and data logic in another.
drawbacks
Getting started with MVVM and adding new features may require some pattern experience. The learning curve is relatively steep.
Following the MVVM pattern may result in the creation of more Java classes.
concluding remarks
Choosing the right architectural model is critical when building any application - there is no one-size-fits-all model.
In our case, MVVM proved to be a useful pattern as we have a UI-rich product with frequent iterative UI updates, we wanted to focus on the testability of the product and wanted to achieve a separation of concerns so that we could just change the relevant components of the code base without affecting the rest of the code.The MVVM architecture was a perfect fit for us!
