When we are in the process of planning the development of a new application as developers we usually don’t think about the architecture and just go coding guided by some mockups or a list of generic requirements, let’s be clear, this practice is more common than we think, also we are mentally blocked by the idea of being agile (ignoring that it doesn’t mean fast) and we skip the step of architecting our systems.
If we don’t make an statement that architecture matters from the beginning, the cost of maintenance is going to increase and we eventually will spend more hours developing a new feature or even worst a simple task of changing a part of our system could be a mess to develop.
In this article we are going to see how Clean Architecture could help us to organize and structure our Xamarin projects, using some references from the famous book Clean Architecture A Craftsman’s Guide to Software Structure and Design by Robert C. Martin (also known as Uncle Bob) in which he says:
“The architecture of a software system is the shape given to that system by those who build it. The form of that shape is in the division of that system into components, the arrangement of those components, and the ways in which those components communicate with each other. The purpose of that shape is to facilitate the development, deployment, operation, and maintenance of the software system contained within it.”
Clean Architecture has a main objective, which is the separation of concerns, this separation is done by dividing the software into layers. In the simplest form our architecture should have at least one layer for business rules, and another layer for user and system interfaces.
This kind of architecture produces systems with the following characteristics (extracted from the Uncle Bob’s book):
– Independent of frameworks. The architecture does not depend on the existence of some library. This allows you to use such frameworks as tools, rather than forcing you to cram your system into their limited constraints.
– Testable. The business rules (through use cases) can be tested without the UI, database, web server, or any other external element.
– Independent of the UI. The UI can change easily, without changing the rest of the system. A Xamarin UI could be replaced with a Console UI, for example, without changing the business rules.
– Independent of the data source. You can swap out SQLite or Realm for CosmosDB or something else. Your business rules are not bound to the database.
– Independent of any external agency. In fact, your business rules don’t know anything at all about the interfaces to the outside world.
- Presentation: layer that contains the UI.
- Framework: implements the interactions with platform specific SDKs and external libraries, also provides the concrete implementations of the data layer.
- Use cases: contains application-specific business rules. It encapsulates and implements all of the use cases of the system.
- Domain: contains the entities that represent business objects, these objects can have methods (Critical Business Rules), or it can be a set of data structures and functions.
- Data Interfaces: interfaces with the definition of all data sources, they are implemented in the Framework layer.
- Repositories: contains the repositories, they use the the Data Interfaces for retrieving external information.
- Tests: Unit tests pointing to the use cases.
The golden rule that makes this architecture work is the Dependency Rule: “Source code dependencies must point only inward, toward higher-level policies.”
With that being said, nothing in an inner circle can know anything about something in an outer circle.
In order to maintain a simple approach, we are going to group the layers into App (yellow circles), Core (gray circles) and Tests (red circles).
Let’s break this down with an app with only one use case: get orders for current user.
This is how it looks in a Xamarin Project:
As you can see, all begins in the UI, when the end user opens the app it shows the Order’s MainPage.xaml, this view has a Binding Context connected to the MainPageViewModel which calls the corresponding use case for get the list of orders and show them to the user.
The connection between the use case and all the dependencies needed it’s done by Unity (using Prism) at the App layer, following the Dependency Rule, is something like this:
The final result of the flow is this screen:
If you want to examine all the code, you can check out the project from GitHub:
In conclusion (yes, another reference from Uncle Bob):
Your architecture should tell readers about the system, not about the frameworks you used in your system. If you are building a health care system, then when new programmers look at the source repository, their first impression should be, “Oh, this is a health care system.” Those new programmers should be able to learn all the use cases of the system, yet still not know how the system is delivered.