Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Clean Architecture UseCase for each method of repository?

Does we need to create UseCases for each method from Repository interface in domain layer?

For example assume that I have such Repository interface

interface ThingRepository {
    void create(Thing thing);
    void delete(Thing thing);
    List<Thing> readAll();
    int size();
}

As you can see there is size() method that returns number of records in database or in file, whatever. And this method is pretty fast. I guess that there is no need for UseCase for this method because it wouldn't block UI thread and can be executed synchronously.

So could you explain me when you create UseCases and when you don't. Basically is there any rules for UseCase creation?

Sorry if there is some misunderstanding in this question.

Thanks in advance ;)

Also I opened the same issue on Android-CleanArchitecture repo on github but nobody answered it yet that's why I'm asking here.

like image 932
hotHead Avatar asked Apr 03 '17 18:04

hotHead


1 Answers

Fun question!

The easy answer. You as a programmer do not write the use-cases. Your specifications document is where you derive your use-cases from. Once you have your use-cases all lined up nice in your kanban board, then you start solving those problems. One at a time.

Notice I said programmer? That's only if you go to work, sit down, boss hands you a specification, and you code for 8 hours and then go home. However, that's usually not the case and some of us are architects as well. (This is an oversimplification for my following point.)

From the context of your original post, and why everyone in the comments is jumping on you is because of this...

Does we need to create UseCases for each method from Repository interface in domain layer?

Simply put: In test driven development, you don't write a single character of code until you write a failing test first. The same goes for use-case driven development; you don't write a single character of code until you have a use-case you are trying to solve.

and

As you can see there is size() method that returns number of records in >database or in file, whatever. And this method is pretty fast. I guess that >there is no need for UseCase for this method because it wouldn't block UI >thread and can be executed synchronously.

What that sounds like is. "I didn't have a use-case to display the number of records in a database so I added a size()function to the repository interface because I thought it should have one, and I'm trying to write a use-case for it." That simply not the goal of use-case driven development.

So all that being said, let's come back to the size() function in your ThingRepository. The only reason you should have added the size() function is to solve a use-case.

Example: "The application should display the total number of all Things in the database.

The problem with that use-case is, if I'm displaying Things to a user, then more than likely my Presenter has a _ThingRepository injected into it. I would much rather run a _ThingRepository.readAll().Count() because it's either already in memory, or needs to be at some point for other Presenter functions, which is much faster than making another trip to the database (which could possibly be in another country) for a simple record count.

If you were trying to solve the size() use-case first, your kanban board is probably out of order, as "Displaying things to user" is a Presenter function and an implementation detail that should be put off until the last responsible moment.

So, does the size() function even really need to be there? Not unless you have a really good reason to put it there, and not until you need it.

like image 117
Adam Vincent Avatar answered Oct 20 '22 10:10

Adam Vincent