Android-CleanArchitecture-Kotlin icon indicating copy to clipboard operation
Android-CleanArchitecture-Kotlin copied to clipboard

Should a complex feature logic be placed in the datastore class or moved to the usecase class?

Open vuksa opened this issue 7 years ago • 6 comments

Hi, I'm working on the app which has a complex usecases which require multiple actions to be performed in order to usecase to be completed.

Lets, for example, say that I want to implement File deletion feature in my app such as Dropbox. This requires this app to firstly do a deletion of some file metadata from a database table and after it, to delete a file from the storage.

So far, we placed all of this logic to datastore class, but it just does not fill right for me, because I think there is no reason that datastore should know about file storage.

So, my question is what would be a better practice, to move this complex logic to Use Case class and there to sequentially execute calls to the Repository and File storage or to keep it in datastore class?

@android10, I'm looking forward to your opinion. Best regards.

vuksa avatar May 10 '18 08:05 vuksa

Hi @Vuksa

I also had this dilemma when 'Repository' contain more logic 'Use Case' that uses that repository.

For example "Sign In" use case can have these steps:

  1. Validate credentials
  2. Make request
  3. Save token details

All these steps need to be executed sequentially in one use case. This use case will use repositories for making request and saving token details.

As conclusion in my opinion you need to do what you mentioned: "this complex logic to usecase class and there to sequentially execute calls to the repository and file storage or to keep it in datastore class"

ghost avatar May 10 '18 08:05 ghost

That sounds like a good case for RxJava since you can have different UseCase implementations that return Observables which you can compose.

That is the first thing that came to my mind when I saw your problem.

android10 avatar May 17 '18 08:05 android10

Hi @Vuksa

I also had this dilemma when 'Repository' contain more logic 'Use Case' that uses that repository.

For example "Sign In" use case can have these steps:

  1. Validate credentials
  2. Make request
  3. Save token details

All these steps need to be executed sequentially in one use case. This use case will use repositories for making request and saving token details.

As conclusion in my opinion you need to do what you mentioned: "this complex logic to usecase class and there to sequentially execute calls to the repository and file storage or to keep it in datastore class"

Hi @Vuksa Did you solve the problem? I have a use case similar

  1. Get list configurations
  2. Save list configurations in local DB
  3. return the result (true or false)

juanagu avatar Aug 30 '19 18:08 juanagu

Hi @juanagu, at the and for my use case I put the logic in the Use Case class.

For your use case, I would put this logic to the repository or data source class. For me, it has more sense to be placed there since you are only doing configuration syncing, and this logic should be encapsulated behind the repository interface.

Even better instead of using Single in your case, I would use Completable as return type. I assume you are probably only waiting to see if configuration syncing is done successfully. Since you are not returning any configuration data upstream, I would rather use Completable there.

vuksa avatar Sep 09 '19 10:09 vuksa

I'd just use Single<Unit> because conversion between singles and completables is pain.

Zhuinden avatar Sep 09 '19 12:09 Zhuinden

@Zhuinden Is there any issue or bad practice with the usage of ignoreElement() method call?

vuksa avatar Sep 09 '19 13:09 vuksa