Why We Need An Architecture Pattern

4 minute read

Published:

Architecture is about intent!

Let’s say we have an android app with packages like the following:

no architecture image

When I see those packages for the first time I recognize activity, fragment, model.. Etc. Awesome isn’t it?!

But then some questions pop into my head such as:

  1. Why the directories of this application expose the framework? Do I even need to know the framework?!

  2. Or why doesn’t the high-level directory of this application tells me what the application actually does?

Why is the framework in front of me while what the application does is hidden?!

And then I realized that something isn’t right!

So Why Clean Architecture?

When I heard of the clean architecture for the first time it fascinated me.

Let’s take a look at what it actually does.

clean architecture image

Following are the main keys of clean architecture:

  • Independent of Frameworks: the architecture does not depend on the existence of some library of feature-laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.

  • Once you have use-cases layer you can know what the application does without going to the framework.

  • The third key is testability, the business rules can be tested without the framework and I will talk about How to Write a Testable Code? later on.

Understanding Clean Architecture

And now let’s dig deep!

The Data Flow works as the following :

  1. UI calls method from Presenter/ViewModel.
  2. Presenter/ViewModel executes Use case.
  3. Use case combines data from User and Post Repositories.
  4. Each Repository returns data from a Data Source (Cached or Remote).
  5. Information flows back to the UI where we display the list of posts.

The code is divided into three separate layers:

  1. The Presentation Layer: this includes our Framework (ie: Activities, Fragments,…). -never put your business logic in this layer-.

In this layer, you can use your preferred architecture pattern (ie. MVP, MVVM,…).

  1. The Domain Layer: is the most INNER part of the onion and it contains Entities, Use cases. Use cases combine data from 1 or multiple Repositories .. In the following example, we have a UseCase class that describes what the business needs.
class GetMenusUseCase {
    fun getAllMenus(pageNo: Int, menusRepository: MenusRepository = MenusRepository()) = menusRepository.getAllMenus(pageNo)
}

By that we solve our biggest problem which is what the application does by looking to this class, by that we know what should this part of the app does without going to the framework.

many people think about use-case is useless part as it only calls the repository but from my perspective it’s very important part of the architecture , lets take an example if you have a business rule says once you click the button you need to add user to the queue and you know that you cannot add the user without creating the queue first and here the benefit of the use-case you have to include only one rule which is addUserToQueue and the use-case will decide if we have to create the queue first or the queue is created before then add the user. so if you read the use-case you don’t need to know that you have to create queue first all you want to know that their is a rule somewhere says when click on this button add the user to the queue.

  1. The Data Layer: this has all the repositories which the domain layer can use. This layer exposes a data source API to outside classes.
class MenusRepository : MenusDataSource {
    private val remoteDataSource by lazy { MenusRemoteDataSource() }

    override fun getAllMenus(pageNo: Int) = remoteDataSource.getAllMenus(pageNo)
}
interface MenusDataSource {
    fun getAllMenus(pageNo: Int): Call<MenuList>
}

Repositories are responsible to coordinate data from the different Data Sources.

In the above example, we can see the repository that is responsible for getting the data from one or multiple data sources by implementing a Datasource class.

The Dependency Rule of the clean architecture which is the most interesting thing, This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle.

By following this architecture you don’t have to test your views anymore, you can only test your business logic without interacting with the presentation. we will talk about testing in another article.

Note: You’ll find all the code for this project in the following Github

References