android10 / Android-CleanArchitecture

This is a sample app that is part of a series of blog posts I have written about how to architect an android application using Uncle Bob's clean architecture approach.
Apache License 2.0
15.52k stars 3.32k forks source link

How to use multiple UseCase in single view or single presenter? #177

Open Joy-Whale opened 8 years ago

Joy-Whale commented 8 years ago

I think the view can only exist single presenter, I see the presenters in demo only need one UseCase, but the UseCase only do single things. so,how to do this?Use multiple presenters in view or user multiple UseCase in presenter?

MkhytarMkhoian commented 8 years ago

@Joy-Whale If you need, use several usecase in one presenter. For example:

private final AddList mAddList;
private final UpdateLists mUpdateLists;

@Inject
public AddListPresenter(AddList addList, UpdateLists updateLists) {
    this.mAddList = addList;
    this.mUpdateLists = updateLists;
}
jpventura commented 8 years ago

@Joy-Whale, according to ECB Pattern, the boundary is related to one and only one use case (or control object, as originally named by Jacobson) that consume other use cases.

image011

You may create use cases that consume other use cases. Too many use cases in a single presenter could lead to you a Good Anti-Pattern, but is up too you decide when you presenter is becoming a demigod.

Object calisthenics advocates your entities should not exceed 50 lines, but since Java is a garrulous language, 150 lines would be a good catch.

If you are using RxJava, you may implement composed uses cases using Subjects.

andreshj87 commented 7 years ago

Domain Services are what you're looking for. Instead of having multiple use cases in your presenter, you have multiple domain services in your use case.

Check out this blog post from Christian Panadero: Modeling my Android domain layer

jpventura commented 7 years ago

@Zireck During Clean Architecture and Design presentation, Robert Marting states:

You could take that use case (or interactor) and put it into an object (... that) encodes the processing rules.

This object encodes the processing rules in that use case somehow (... and) there must be a method in this object called execute.

_If you got an object that got only one method called execute, what design pattern is that by the way? Command Design Pattern._

The command pattern encapsulates a request as an object, packing all information required to perform an action or trigger an event at a later time and observed as a data stream.

Since all information is packed in a single object, it also allows you dispatch command sequences to be executed in other core/threads.

Thus you may have several domain services in a single use case if the compose it, otherwise you would break the pattern and kill one of it most useful virtues.

mradzinski commented 7 years ago

@jpventura A bit late, but... when you mention "command design pattern" and "composition" are you referring to something like this? (stupid example, actually just wrote it here from scratch, but it shows composition through RxJava on a single method class, so it seems to match your description...)

class SimpleInteractor {
    fun execute(): Single<Company> {
        return repository.getUser()
            .flatMap { repository.getCompany(it.id) }
    }
}

That interactor in particular has a single concern but it actually does more than just calling a single method on a repository. It first gets the User and then using it's ID the final result which is the Company. Would that be a properly implemented interactor in your opinion?