New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UseCase responsibilities #94
Comments
In example 1 : In example 2 : Example ( a bit of a dumb one, but just to describe the scenario) : The problem is that is UseCase 1 is successful, we need to execute UseCase 2, if not, there's no need for that. The solution is not to call those 2 UseCases but create UseCase 3 (login user and if ok, get the search results). It's not because you already have atomic UseCases for certain actions, that you cannot create a new one to handle a specific business task. Now depending on the complexity, you might abstract things like "Login User via Api" to a separate "Api Manager" which both UseCase 1 and 3 may call, so there isn't any specific duplicate logic in both Use Cases. |
Hey @Trikke and @alextimonin ! Please I could lend some advice on this pagination/use case scenario. Are you saying that the view should know about which is the reference to the next page? Or should it be the responsibility of the presenter? (That is orchestrating everything?) So is the flow something like this? I am a bit unsure if this is the way to do this. Thank you. |
Hey @fabiocarballo , It should be the responsibility of the Presenter. The only thing the view does is handle the event for when the next page should be loaded. The Presenter is then notified and handles the logic with pagination details. So :
Did this help? |
@Trikke Very clear, however can you outline exactly the difference and responsibilities of the user case vs the repository? |
@trungie the responsibility of the repository is store and retrieve data that is used in the Domain layer. How it does that doesn't matter to the Domain layer. So it is an abstraction between the actual implementation of the store (sql, plain text,...) and the business part of your app. A Use Case is part of this business bit of your app. You can have a lot of those, and sometimes even for the smallest, most idiotic things. Your business rules (read how your app works) reside in the Domain layer and usually in these Use Cases. Lets make a quick, dumbed down, example: We create an app to get the top 5 GitHub projects of today (this sentence is our actual business logic). So we have a screen with a button "get projects". That's the only thing our app will do, for now. The user presses that button, the View notifies the Presenter that the button is pressed and it needs to do something. The Presenter will then have or create a Use Case. This Use Case's only purpose is to enforce our business rule from above, getting the top 5 GitHub projects of today. In the Data layer, we have a Repository that is able to fetch and store the GitHub projects. The Repository will also have parameters like "amountOfProjectsToFetch" and "projectTimeFilter". The first one is to specify the amount of projects to retrieve from the Github API, and the second one exist to indicate a timeframe to filter these projects. (reminder, i'm making this up as we go along, the Github API in reality will work differently) The idea to take away here is that it isn't the Presenter or the Repository that gets to specify how many projects we need to get from Github. There isn't such a method in the Repository, it only gets lists of projects from the GitHub API with parameters. It doesn't case that our app wants the top 5 GitHub projects. The other way around, the Use Case doesn't care HOW we get these top 5 GitHub projects. It only cares that there is a way to do it, and that it can dictate WHAT to get. Now imagine you want to expand your app and show a button to get the top 10 GitHub projects of this year. You only need to add a new Use Case that does this, and have your Presenter execute that one on the right button press. Now imagine this last feature is a paying feature. This is business logic. So we modify the last Use Case to also check if the current User has payed for this feature, and block access to it if needed. It would either return the top 10 GitHub projects or notify the Presenter that the user cannot, and should see a payment dialog. (keep in mind, this is all very simple and might seem like a lot of code for a small app. But soon your app grows and grows, and you keep adding new features and rules. Then this architecture will start making more and more sense as testability and usability remain simple) |
@Trikke Thanks for making great explanation.
I still have some questions about sentence above.
|
A quick example :
So the control flow would be
Please read up some more on programming patterns. The ones shown here in this sample are not the only ones, and will not cover all your requirements. So don't treat this as "this is the final example on how to do it, and i only will need this". There's a lot more out there, explore! |
Hi @Trikke, I have two UseCases: Both UseCases share the same first part "GetUserIdFromPreferences -> QueryUserFromDB". I'm trying to apply the same concept in my app (have a common place for "GetUserIdFromPreferences -> QueryUserFromDB") to avoid repeating myself. Is it correct to have something like a common method: Or, there's a better method to implement? |
What can subclasses of UseCase do? What can't they do? In this project use cases are atomic tasks used to simply obtain data, but what about decision making, where does that belong?
Example 1: I have a collection of items and lazy loading. Is there one UseCase handling all pagination logic and calling necessary repository methods, or are there multiple UseCases and something (presenter?) orchestrating them?
Example 2: after executing a UseCase, based on its response we make a decision on what UseCase to call next. Again, where is this decision made?
The text was updated successfully, but these errors were encountered: