Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean Architecture: Combining Interactors

Tags:

I've recently stumbled upon Clean Architecture, by Uncle Bob, and I'm curious to know whether Interactors can execute other Interactors.

For example, these are my Interactors as of now: getEmptyAlbums, getOtherAlbums. Both have Callbacks that return with a list of Albums (An ArrayList of an Album model) respectively.

Am I allowed to have an Interactor called getAllAlbums that executes the previous two Interactors within it's run block?

@Override public void run() {     getEmptyAlbums.execute();        }  void onEmptyAlbumsReceived(ArrayList<Album albums){      getOtherAlbums.execute; } void onOtherAlbumsReceived(ArrayList<Album albums){          mMainThread.post(new Runnable() {          callback.onAlbumsReceived(albums);      } }); 
like image 268
Chris Rohit Brendan Avatar asked May 05 '17 11:05

Chris Rohit Brendan


People also ask

What is interactor in clean architecture?

Interactors: little, reusable chunks of code that abstract logic from presenters while simplifying your app and making future changes effortless. But are they all they're cracked up to be? Before I go on, the interactor pattern has a number of variations in Android.

What are the four layers of clean architecture?

Clean architecture vs. The logical layers of this style are as follows: Presentation layer ( accounts for the presentation to the user) Business logic layer (contains the business rules) Data access layer (processes the communication with the database)

What are Android interactors?

Interactor is a class which separates Domain Layer from Presentation Layer. In simple words it provides way to write business logic separately than code which is used for manipulate UI (by binding data to UI/ animate / navigation). So Interactor is mediator between Presenter/ViewModel and Repository pattern.


1 Answers

I have been pondering the same thing and after finding very little on the subject, I have come to the conclusion "Yes" it is probably the best option.

my reasoning as follows:

  1. Single Responsibility: If you can't aggregate use-cases, then each can't really be single responsibility. Without aggregation, it means domain logic ends up in the presentation layer, defeating the purpose.
  2. DRY: use cases can be shared, and should be where it makes sense. As long as the intent of the use case is identical. Obviously this should be thought through before being done. In my experience there's rarely a need for this outside of the next point.
  3. Orchestrator classes: for instance if you need to fetch multiple data sources and persist to a repository. A use case which will run all of those child use cases is required, ensuring things like order of operations and concurrency are correctly implemented. This I think is the most compelling reason for calling other use cases.

To preserve single responsibility, I would consider limiting aggregating use-cases to do only that, i.e. executing those use cases and doing any final transformations.

Given the age of this question, I'd be interested to know which way you went with this and issues you encountered.

like image 63
Ben Neill Avatar answered Sep 30 '22 23:09

Ben Neill