We can easily found the blogs explaining the pros of using Clean Architecture but there is so little to be said about the pitfall and constraints that it enforces. I will mainly focus on the pitfall and constraints of using the Clean Architecture, I hope it will help you make the correct choice of architecture.

Firstly, If you listen carefully to Uncle Bob’s talk, you will quickly realize that he suggesting us to apply Clean Architecture to the entire system i.e. back end and front end. Also, he says for UI layer use the MVP or MVVM architecture. Mobile applications that we develop is nothing but the UI for our systems.

Before opting for the Clean Architecture you must consider the following points to avoid the overhead of complexity and writing boilerplate code.

Can we remove the domain layer or make it optional?

I know a lot of eyebrows will be raised with this sentence. Generally, all the complex business logic is handled on the back end side. There is not much to handle on the front end, except some validation and simple mathematical calculations.

In the project I worked on, we have around 100 use cases, out of which 90 use cases just have a code for accessing the repository layer. The remaining 10 use cases are mostly for the validation data enter by the user in different forms. Also out of those 10 use cases no use case got reused.

Similar to our project, if the complex business logic handled by the server then you should give a serious thought of using MVP or MVVM kind of architecture. Clean Architecture in this type of project will demand you to create a lot of boilerplate code, use case, mapper, entity and test cases, etc. Writing those classes is error-prone and time-consuming.

Also, if your project has a strict deadline, people will find the shortcuts to achieve the functionality. I have seen the data entities used in the presentation layer, which will violets the dependency rule. Someone might argue that through code review should be done to avoid it, but when you have unrealistic targets and jobs on the line most ethical people will also choose the shortcuts. Please don’t miss considering the deadline while deciding on architecture.

For some projects, there might be some small amount of business logic which can be reused. In such cases even using MVP or MVVM we can create a common class for it, whether to call it use case or not is I will leave up to you.

By removing the domain layer I mean using MVP or MVVM and by making it optional I mean creating a class of reusable business logic.

What about the dependency flow and separation of layers?

While using MVVM or MVP, we can use the repository pattern which ensures the decoupling of data and UI layer. It will solve the issue of constantly changing APIs and structural modification in the database.

In my five year career, I have seen API changes more frequently than the UI. The API needs to provide support for various channels like mobile, web, etc. There are bound be some changes in the definition of API as we make progress. Aesthetic changes in UI will not require any change in the entity returned by the repository, the view layer can easily handle those.

So I can say that we can achieve the desired dependency flow and layer separation using MVP or MVVM.

What about frameworks and third party libraries?

You can say for certain that a piece of code that you’re not in control of will make your life harder. Generally, those are libraries and frameworks which we are using.

The library or framework creator constantly tries to update their library for adding new features and enhancing it. As a result of this, there will breaking changes along the way, which will force you to change the dependent code or in the worst case switch to another library due to compatibility issues.

To overcome this we can hide that dependency using a class or interface so that the change in the implementation of a single class will result in changes in the entire code base. This concept is a standalone thing, we can achieve it with any kind of architecture or even without any architecture.

While finding the candidates for this abstraction consider the frequency at which the library can change, the number of classes dependent on it, the amount of effort needed if there is some breaking change.

E.g. in one of my projects, we started using Retrofit 1.9, soon after Retrofit released 2.0. After updating the latest version everything got broken. We have to make the changes in almost all of the activities as there was no architecture in place. Such libraries with a wide range of reach in the codebase are the prime candidate for it. Similarly, we can abstract the library for loading images from the internet e.g. Glide, Picasso, etc.

On the other hand, I have used a library MPChart for displaying the charts. It is used only once in the entire application and that too in UI, so it doesn’t make any sense to abstract it.

Will there be layers and boundaries?

In MVP or MVVM, we can create data and presentation layers with ease. Even we can have a clear architectural boundary between them. If you are not having a large amount of business logic on the front end there is no need to have a domain layer. Two layers can suffice your need and can create a scalable application.

Can we have a separation of concerns and responsibility?

Separation of concern says that a component should have only one reason to change — one responsibility. Classes belonging to the database should have nothing to do with the UI or the networking components. They should be isolated. This can be easily achieved with MVP or MVVM and a repository pattern.

We can make the UI so dumb it should not contain application logic, but it will responsible for formatting, and make decisions on how to present them to the user. View Model or Presenter can help us with this.

What about maintainability?

I am considering mainly two factors under maintainability, ease of making changes & adding new functionality. For the small project, where complex business logic is handled on the back end, you will find many duplicate entities. For each layer you create a separate entity, but under the hood, they are all similar. This will increase the size of the APK and the application’s memory footprint.

Making changes in such a project will have a larger impact as classes in different layer needs to be modified for a single change. This will be a repetitive and boring task. Even with MVP or MVVM, if proper care is taken we can structure our code is a way that we can easily add new functionality.

What about testability?

Using the mocking frameworks and testing library, we can make code written in MVP or MVVM architecture 100% testable. By mocking the behavior dependent classes we can decrease the execution time.

Source link