Clean Architecture in Android

Learn via video courses
Topics Covered

In the era of advancing technology, achieving optimal architecture is crucial for developing exceptional software programs. This article focuses on creating Android apps using clean architecture and incorporates the Model-View-ViewModel (MVVM) design pattern. By connecting MVVM through Clean Architecture, the discussion delves into building decoupled, tested, and maintainable code. Clean architecture, advocating for concerns about separation and logical code distribution, enhances an Android application's evolution, testing, and maintenance. Utilizing Kotlin's benefits, such as conciseness and safety, the article explores the architecture's layers, along with its advantages and disadvantages in the context of Android app development.

Importance of Architecture in Android App Development

Architecture plays a crucial role in app development by providing structure and organization. It enables the separation of concerns, allowing for a clear division of responsibilities and improving code readability and maintainability. Architecture also promotes code modularity, making it easier to break down complex functionalities into manageable modules, enhancing code reuse and scalability. It emphasizes testability, facilitating thorough testing and quality control. Furthermore, architecture fosters collaboration among developers, ensuring efficient teamwork and productivity. Ultimately, a well-designed architecture leads to robust, maintainable, and successful applications.

Important layers of the mobile application architecture are:

  • Presentation standard:
    This layer handles the user interface and user interaction. It includes activities, fragments, views, and view controllers that display information to the user and capture user input.
  • Business level:
    The business logic and rules for the application are contained in this layer. Between the presentation layer and the data layer, it orchestrates the data flow, performs calculations, validates data, and implements business-specific features. Modular and maintainable code in the business layer of a mobile application architecture is crucial for several reasons like Code Reusability, Testability, Collaboration and Scalability etc.
  • Data level:
    This is where the processing of client data is scheduled. Additionally, this is where the essential controls for data access, data processing, data storage, and other related functions are set. Data level abstracts the complexities of data access from the higher layers. Implementing proper data abstraction offers benefits such as encapsulation, code maintainability, security, flexibility, testability, and collaboration.
  • Continuity level:
    This layer exists so that the data layer and the layer in charge of the user interface can interact. In a single application, multiple transactions could be processed, and the business layer's performance might be negatively impacted. This task is intended to be handled by the service layer. Due to the constrained set of actions that are permitted at this level of the mobile application design, there may also be issues with transaction security.

MVVM

A software design pattern called Model-View-ViewModel (MVVM) is organised to keep programme logic and user interface controls apart. Model-view-binder is another name for MVVM, which was developed by Microsoft architects Ken Cooper and John Gossman.

Like many other design patterns, MVVM streamlines code creation, updates, and code reuse by breaking programmes into manageable modules. The MVVM pattern consists of View, ViewModel, and Model. Each of them has different responsibilities in Android.

For more information refer to the article...

Clean Architecture in Android

a. What is Clean Architecture?

A software design theory known as "clean architecture android" divides a design's components into ring tiers. A key objective of clean architecture is to give developers a way to structure their code in a way that incorporates business logic while maintaining its separation from the delivery mechanism.

b. Principles of Clean Architecture

  • UI Independent:
    Clean design helps in updating the presentation or user interface layers without having to change the application layer. Without altering the other layers or the rest of the system, UI can come from any front-end framework, console UI, or web.
  • Independent of a database:
    The architecture must be adaptable enough to allow the database to be changed without compromising the entities and use cases of the application. Change the dataset to Oracle, MongoDB, MYSQL, MS SQL, or another database as part of the solution.
  • Independent of Framework:
    Future frameworks and libraries should not have any bearing on the fundamental business or application rules. Although we can use frameworks, they should only be used as tools and not as the sole basis for the solution.
  • Testable:
    Without the UI, database, Web server, or any other external component, the architecture must adhere to testing of the business cases, core application, and rules.

c. Layers of Clean Architecture

  • Entities:
    Enterprise business rules are another name for clean architecture. It is made up of simple domains. We add objects (entity or domain) without frameworks or annotations to this layer. We include general logics, such as validations and base entities, that are applicable across all domains. They have no dependencies and are least impacted by outside changes.
  • Use Cases:
    Pure logic of Core business or application is written in this layer. Also known as application business rules. For application use cases, we typically refer to them as services or managers. This layer constructs results using a domain layer.
  • Interface Adapters:
    To store data in external sources like databases, file systems, and third parties, this layer serves as a communicator, converting data into the necessary format and converting it for use cases or business logic. This layer is also known as an adapter since it handles the conversion of data in both directions.
  • External Interfaces(Frameworks and Drivers):
    The outermost layer, called Frameworks and Drivers, contains the implementation details of the external interfaces and technologies. The user interface elements, database access frameworks, web service clients, and any other external libraries or drivers used in the programme are all included in this layer. This layer's main job is to communicate with external systems and provide the infrastructure the application needs to function. It is the most volatile layer as it changes frequently.

MVVM with Clean Architecture

Views, Activities and Fragments and business logic are separated by MVVM. For small projects, MVVM is sufficient, but as your software grows, your ViewModels begin to bloat. Responsibility division becomes challenging.

In these situations, MVVM with Clean Architecture Android works quite well. It takes the division of your code base's duties one step further. The logic of the activities that can be taken in your app is abstracted.

a. Advantages of Combining MVVM with Clean Architecture

  • Navigation across the package structure is even simpler. Clean Architecture simplifies code navigation by providing a clear and organized structure. It separates the code into distinct layers with specific responsibilities, making it easy to locate and modify components. The architecture enforces rules for dependency flow, which helps understand how different parts of the codebase interact. By adhering to the Single Responsibility Principle, each component has a clear purpose, reducing complexity. Dependency Injection and interface-based programming further enhance code navigation by centralizing dependencies and providing clear interfaces for communication
  • Compared to basic MVVM, code is even easier to test. Developers can streamline testing by separating concerns, enabling unit testing of individual components, utilising dependency injection for simple mocking, and obtaining high test coverage by integrating MVVM with Clean Architecture. A test-driven development methodology is supported by this combination, resulting in more dependable and maintainable code.
  • Even faster feature additions are made by the team. Due to the separation of responsibilities provided by MVVM, developers can simultaneously work on various business logic and user interface components. Team members working on various architectural levels may collaborate more easily because of Clean Architecture's distinct boundaries and interfaces. This collaborative setting boosts output, allows for concurrent production, and makes code integration easier.
  • The project is even simpler to keep up with. The separation of concerns and layering approach allows for easier maintenance, as changes can be localized to specific components.

b. Key Components of MVVM with Clean Architecture

The main components of MVVM architecture are:

  1. Activities and fragments:
    These are the classes in which we store the many views that users can interact with. This is a component of the user interface, or a view, of this architecture. It also handles user input.
  2. ViewModel:
    We do activities in a ViewModel class that are either related to the business logic or unrelated to the user interface.
  3. Repository:
    In this class, we carry out operations linked to data sources, which may be a local database or an API. We may say that this is our Model because we get the data that flows in the app from the repository.

Advantages of Clean Architecture

a. Scalability

The ability to separate concerns between the various system layers is one of the main benefits of Clean Architecture. This makes it simpler to comprehend the code's overall structure. Additionally, it facilitates system expansion or modification without creating unexpected side effects. For example, let's talk about a task management app with MVVM and Clean Architecture, the View handles UI, the ViewModel manages data operations, the Use Cases layer encapsulates business logic, and the Data layer handles data persistence. This separation simplifies maintenance, enhances testability, and promotes code reusability. Developers can focus on specific areas, easily make changes, and test components independently.

b. Testability

Clean Architecture has the added benefit of making system testing simpler. The system's layers are independent of one another, allowing for independent testing of each layer. Consequently, checking that the system is operating properly is made considerably simpler. Examples of testing frameworks are JUnit, Mockito, AssertJ, etc.

c. Maintainability

The emphasis on developing systems that are simple to comprehend and maintain is one of the fundamental characteristics of clean architecture. This is accomplished by segmenting the system's concerns into separate layers and breaking them down into smaller, more manageable portions.

d. Flexibility

The flexibility of Clean Architecture is another significant feature. It is flexible to be applied in a wide range of software development scenarios, such as embedded devices, mobile apps, and online applications.

Disadvantages of Clean Architecture

a. Increased Complexity

To separate concerns and control dependencies across various components, Clean Architecture mainly relies on abstraction and indirection. Due to the overhead of additional function calls, object creation, and memory allocation, this may cause performance problems. Small performance penalties introduced by each additional layer of abstraction have the potential to add up and have a detrimental effect on an application's overall performance. But performance impact is minimal as compared to the benefits.

b. Longer Development Time

In Clean Architecture, data transformations are frequently necessary when transporting data across layers. It can involve changing data types, serializing and deserializing objects or mapping data to alternative structures. Due to the additional processing needed to modify the data and the potential for a higher garbage collection burden, this may cause performance concerns.

Combining MVVM with Clean Architecture

The clean design places the application's core—the business logic (the application) and application model (the domain)—at the heart of the system.

We flip the dependencies since The Core must be independent of data access and other infrastructure issues. By including interfaces or abstractions in Core that are implemented by layers outside of Core, this is accomplished.

A. Steps for Implementing MVVM with Clean Architecture

1. Learn about MVVM:

Familiarise yourself with the MVVM's ideas and guiding principles. Recognise the roles played by the Model, View, and ViewModel components. Refer MMVM section above for more information on MVVM.

2. Understand Clean Architecture:

It emphasises independent layers and the separation of concerns. There are layers in the architecture including Presentation, Domain, and Data.

3. Identify the layers:

  • Presentation Layer: Contains the UI components (Activities, Fragments, Views).
  • Domain Layer: Defines business logic and use cases.
  • Data Layer: Handles data access and external dependencies.

4. Implement the Domain Layer:

The domain layer, which houses the primary business logic of your application, should be the first thing you accomplish. Any UI framework or data source shouldn't depend on it.

  • Establish use cases:
    Figure out the tasks that your application must complete and put them into use cases in the domain layer.

  • Establish models:
    Establish the models that your application will use to represent the data and entities.

5. Implement the Data Layer:

The Data Layer, which controls data retrieval and storage, should be implemented. It should be in charge of hiding the specifics of the data sources, such as a network, database, or API.

  • Define repositories:
    Specify data operation interfaces and the repositories that use them.
  • Put data sources to use:
    Implement the actual data sources and link them to the repositories (local database, external API, etc.).

6. Implement the Presentation Layer:

Implement the presentation layer, which controls user interactions and includes the UI elements. To retrieve and update data, this layer communicates with the domain layer.

  • Implement Views:
    Design the Activities, Fragments, and Views for the user interface.
  • Create ViewModels:
    Make ViewModel classes that serve as a bridge between the domain layer and the views. ViewModels show information.

7. Linking the layers:

Link the domain and data layers to the presentation layer.

  • Inject dependencies into the presentation layer from the data and domain levels.
  • Views interact with ViewModels by observing changes in ViewModels and updating the UI as necessary. ViewModels send updates or user interactions to the domain layer.
  • ViewModels communicate with use cases in the domain layer to retrieve or alter data.

8. Implement data binding and observability:

Utilize data binding frameworks or libraries to establish a connection between the Views and ViewModels. This enables automatic UI updates when data changes in the ViewModel.

9. Write tests:

Create unit tests for the domain layer, data layer, and view models by writing tests. Test the UI interactions, data processes, and business logic.

B. Examples of MVVM with Clean Architecture in Android Apps

Here's a Kotlin code example of how you can implement MVVM with Clean Architecture in an Android app:

1. Presentation Layer (ViewModel):

Explanation:
The UserViewModel class acts as an intermediary between the UI components (View) and the domain layer (through the getUserUseCase). It exposes the user data as a LiveData object, which can be observed by the UI components to update the UI when the data changes. The fetchUser method initiates the data fetching process asynchronously using coroutines.

2. Domain Layer (Use Case):

Explanation:
The GetUserUseCase class encapsulates the logic for fetching a user by utilizing the provided UserRepository. It separates the business logic and data transformations from the specific data source implementation, allowing for easier testing and maintainability.

3. Data Layer (Repository and Data Source):

Explanation:
The UserRepository acts as an interface defining the data access methods, the UserRepositoryImpl provides the concrete implementation using a specific data source (UserDataSource), and the RemoteUserDataSource represents an implementation of a remote data source that fetches user data from an API.

4. Dependency Injection:

Explanation:
This module configuration defines the dependencies and their resolutions for the presentation, domain, and data layers of your application. It sets up the necessary injections for the ViewModel, Use Case, Repository, and Data Source classes, allowing them to be easily used and managed within your application.

Layers of MVVM

1. Presentation Layer

Normal operations, fragments, adapters, and view models are all included in the presentation layers. The Data Layer and the Presentation Layer have an agreement called the Domain Layer. Callbacks are associated with the domain layer. Pojo classes or data classes, repositories, Rest Services, and Room DB are all examples of data layers.

2. Domain Layer

Complex business logic or simple business logic that is utilised by several ViewModels must be contained in the domain layer. Because not all apps will meet these requirements, this layer is optional. Use it only when necessary, such as to manage complexity or favour reusability.

3. Data Layer

This contains every repository that the domain layer can use. This layer makes external classes accessible to data source API. PostDataSource is implemented by PostDataRepository. It determines whether data is fetched from a nearby database or a distant server.

4. Framework Layer

The MVVM paradigm is well known, and the community has developed several frameworks to make this kind of development easier. MVVM frameworks also offer custom commands, navigation assistance, dependency injection/service locator components, and UI platform integration in addition to the functionalities offered by each framework.

When to Use Clean Architecture?

a. Appropriate Scenarios for Clean Architecture

Clean Architecture is suitable for various scenarios, including:

  • Systems on a grand scale:
    Clean Architecture functions effectively for intricate systems with numerous features and components. As the application expands, it aids in keeping a distinct and well-organized structure.
  • Collaboration among teams:
    Clean Architecture establishes distinct boundaries between various layers and modules, making it simpler for groups to work independently and concurrently on various application components. Each team can concentrate on its area of expertise without impacting the others.
  • Testability:
    By separating business logic from external dependencies, Clean Architecture fosters testability. It becomes simpler to write unit tests for individual components without the need for complicated setup or mocking when boundaries are specified and dependency injection is used.
  • Lifecycle of long-term projects:
    Clean Architecture is advantageous for projects with a long lifecycle. It facilitates the application's ongoing evolution and improvement while also assisting in the reduction of technical debt.

b. Choosing the Right Architecture for Your Project

Choosing the right architecture for your project depends on several factors. Here are some key considerations to help you make an informed decision:

  • Project Requirements:
    Recognise the precise specifications and limitations of your project. Think about things like time-to-market, scalability, performance, maintainability, and extensibility. These specifications should be met by the architecture.
  • Size and Complexity of the Project:
    Determine the scope and scale of the project. Lightweight designs may be advantageous for smaller projects with basic functionalities, whereas more organised and modular structures may be necessary for larger and more complicated projects.
  • Project Lifespan:
    Take into account how long you anticipate your project will last. You might put a higher priority on rapid development and opt for a simpler architecture if it's a prototype or a short-term project. Architectures that put a higher priority on maintainability, extensibility, and adaptability are better suited for long-term projects.
  • Tools and Frameworks That Support the Architecture You Are Considering:
    Evaluate the Tools, Frameworks, and Libraries That Support the Architecture You Are Considering. Make sure the environment is in place to support the creation and upkeep of the selected architecture.
  • Prototyping and Experimentation:
    If you're not sure which architecture is ideal for your project, think considering prototyping or running some quick tests to compare several possibilities. This might aid in your evaluation of the viability and efficiency of various architectural solutions in achieving the objectives of your project.

Conclusion

  • The choice of architecture for a project depends on various factors such as project requirements, team expertise, scalability needs, and development timeline.
  • MVVM (Model-View-ViewModel) is a software design pattern that separates the user interface (View) from the business logic (ViewModel) and the data (Model). It helps in organizing and maintaining code by providing a clear separation of concerns.
  • Clean Architecture, also known as Onion Architecture, is a software design principle that promotes the separation of concerns by dividing the application into layers.
  • Clean Architecture aims to keep the business logic independent of the delivery mechanism (UI, database, frameworks, etc.) and focuses on testability, maintainability, and flexibility.
  • Combining MVVM with Clean Architecture can provide additional benefits in terms of code organization, scalability, testability, and maintainability.
  • When implementing MVVM with Clean Architecture, the layers involved typically include the Presentation Layer (UI components), Domain Layer (business logic and use cases), and Data Layer (data access and external dependencies).