Domanda

I've recently started applying the Clean Architecture while developing an Android application. And so I divided my application in 4 different parts.

enter image description here

Data layer

Contains the implementation of repositories.

Device layer

Contains implementation of android related stuff like AlarmManager, not related to storage of entities.

Domain layer

Use cases (interactors) are implemented here and interfaces for repositories are defined here.

Presentation

UI related stuff, fragments, view models, activities.


This application is not in isolation, it exists in a system with a backend and a frontend (web app) where some users use the mobile app and some use the web app.

Now, according to the clean architecture, the business logic should reside in the domain layer. But in this scenario I feel like it does not belong there. Let's take an example.

Let's say a User can purchase MovieTickets from different type of cinemas.
In this scenario, we would have a use case called PurchaseMovieTicket.

Now the question is. Where should the actual logic on the purchase be implemented? There are two ways this can be done.

Type 1

Most examples on clean architecture on android only consider the Repository as something to do CRUD operations on whether its on the cloud or local storage (eg. Android Room). This would mean the PurchaseMovieTicket use case would include logic such as.

  • Remove money from user
  • Add the movie ticket to the user
  • Call update on the repository with the User as parameter

Now the drawbacks here is obvious. What if the backend needs to do other things related to purchasing of movie tickets, perhaps communicate to other systems even, then all this would also need to be implemented in the app. You can almost see how this is not possible.

Type 2

The Repository contains a method called purchaseMovieTicket which takes a MovieTicket and a User. This method would do the necessary logic on the backend or wherever it is implemented.

Drawback here is well, the use case becomes almost unnecessary because it just forwards the call from the view model to the repository. And there is no business logic to talk about.

Question

  • Which type would be the best to use in this system? Why?
  • Is it good to put the business logic in the backend?
  • If you go with implementation type 2, does the repository break the clean architecture principles?
È stato utile?

Soluzione

It should be on a case-by-case basis but I would expect most of the logic to go in the backend.

Your interactor might still contain several methods ("Check ticket availability", "Add ticket to basket", "Checkout") but yes the implementation could be expected to be very simple in some cases.


You might want to consider:

  • Security. Any code that you need to trust, implement on the backend. Assume a hacker can change the client code to do what they want. In your type 1 example, what if they changed it to only call "Add the movie ticket to the user" and not "Remove money from user"?

  • Communication coupling. As you mention, for anything that needs to communicate with other systems, prefer the backend so that the client only needs to communicate with your backend.

  • Responsiveness. Things on the client end (aside from heavy computation) will generally have better performance for the user than communicating with the backend. Something like computing a total basket price might be better on the client end for this reason.

  • Duplication. If you have two clients, implementing the logic in the client will require it to be duplicated, so prefer the backend.

  • Data location. Prefer to put the logic with the data that it operates on. For example, if it requires computing on a lot of data from the backend database, but only sends a small result to the user, put that logic in the backend. Or the opposite might apply.

  • API. Prefer to place the logic so that the backend's API feels cohesive and consistent.

  • Race conditions. Placing logic in the backend makes use of transactions and similar techniques much easier, decreasing the risk of concurrency issues.

  • Resource requirements. On mobile, I'd suggest heavy computation should be done on the backend. If this was a desktop app known to run only on decent machines, it might be better to prefer the client end to reduce server load.

Note this isn't an exhaustive list.

Altri suggerimenti

The very definition of the terms "front end" and "back end" comes from the separation of business logic (back end) from the user interface (front end). So yes, business logic should be in the back-end, whether that is a remote service or simply a different layer in the same application.

Given that you already have a separate back-end system, you should apply Clean Architecture primarily to this system, which should house all the business logic. The mobile app can be thought of as an extension to the UI layer of the back-end system, and therefore does not have any business logic of its own. All the use cases and repositories live in the back-end, and the mobile app simply uses a gateway to talk to the back-end.

Im a DBA not a developer, so i will offer you a pro db perspective.

Implementing logic using a combination of Stored procs and table driven values in the db that can be shared by both the web app and mobile app means you get security, performance and consistency.

It has the added advantage that when you want to make a change that change is rolled out immediately to all users irrespective of interface.

It also means changes to behavior can be made by the business without having to redeploy software.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top