y

    Yasser AKBBACH

    3 weeks ago
    Hi all, I have a question, if
    use cases
    in
    clean architecture
    with Android are just calling
    repositories
    , why should we bother creating them? why not injecting
    repositories
    in
    viewmodels
    like we used to do?!
    Javier

    Javier

    3 weeks ago
    Personally I don't like repositories and I only use use cases
    K Merle

    K Merle

    3 weeks ago
    If your "usecase" is simple, you can have one or the other, but if logic is complex, having repository as single place to search for feature datasource API's and usecase as place where domain logic is done is a good separation imo.
    y

    Yasser AKBBACH

    3 weeks ago
    can u give me an example of a complex use case (in :android:)?
    K Merle

    K Merle

    3 weeks ago
    I would consider it if it's talking more than 1 API that is in a lower level, this includes also if it's consuming 2 API's from same repository. Example, user changed some field, and we need to store data locally and send network request.
    y

    Yasser AKBBACH

    3 weeks ago
    I see, but don't you think that in most cases we only go with passing the
    input
    and caring about
    output
    and most of the work is being done in the
    repos
    🤔 ?
    K Merle

    K Merle

    3 weeks ago
    You can do it in repository, but for me, repository is the place where I put all my datasource API's, so it's a place of gathering the datasource API's, and not some high-level place that usecases were supposed to be.
    y

    Yasser AKBBACH

    3 weeks ago
    Yeah as the name says it's a
    repository
    Thanks 🙏
    Javier

    Javier

    3 weeks ago
    curiously, clean arch says nothing about repositories
    K Merle

    K Merle

    3 weeks ago
    I wonder if Gateways could be considered a Repository.
    Javier

    Javier

    3 weeks ago
    I think it is adding complexity which is going to be useless a lot of times, overall in Android applications, like creating mappers as objects that are injected lately instead of simple functions.
    y

    Yasser AKBBACH

    3 weeks ago
    You're speaking my suffering man 😂
    Javier

    Javier

    3 weeks ago
    almost all android application just draw fetching from API and adding offline support, without a really complex logic. You can inject all of those objects in the use case implementation and and don't have a huge function
    meanwhile using both, repositories and use cases, you will get tons of anemic use cases
    K Merle

    K Merle

    3 weeks ago
    It should certainly be thought before if it makes sense.
    c

    curioustechizen

    3 weeks ago
    Anemic use cases is a pain; but combining use cases and repositories is not the right solution according to me; and it is a layering violation. In the architectures that I've worked with: • UseCase resides in the domain layer • Respository interface resides in domain layer (so use cases have access to repository interfaces) • UseCases only handle the business logic. Specifically, UseCases do not know about where or how your data is stored. They definitely do not know about your backend URL or JSON formats. • Repository implementations reside in data layer. These repository implementations are the ones responsible for API calls/database calls/JSON parsing etc. A more viable alternative to avoid one-liner usecases is to inject repository interfaces directly into ViewModels where it makes sense, and inject UseCases in ViewModels only if the UseCase is more than a one-liner. However in practice I've found that it is makes things more predictable to always inject UseCases in ViewModels and never repositories (even if those usecases are likely to start off as one-liners). This is because many times a UseCase might start as a one-liner but then evolve to something more. As a concrete example in one project we introduced in-memory caching for some data; and then a bunch of UseCases which were one-liners turned into UseCases which had logic: First check the cache, if it is there return it; if not fetch it and store into cache before returning.
    j

    Jan Starczewski

    3 weeks ago
    In my opinion just keep both in mind. Analyze the case you are implementing, when it is simple and needed in one place, there sometimes is no need to add an extra UseCase boilerplate. When code needed to use data from repository is getting complicated (business logics grows) and there is a need to use them in many places (depending on the rules in the project, for example: one, two, refactor), just refactor the code to UseCase to encapsulate shared logic.
    Francesc

    Francesc

    3 weeks ago
    A thing to keep in mind is that the presentation layer should not depend on the data layer. With use cases changes to the data layer are isolated to your use cases so that these changes do not leak to the presentation layer, forcing you to do a major refactor in your presentation layer if you make changes at the data layer. Data types should also not leak to the presentation layer, if you change backend technologies that should be transparent to the presentation layer.
    K Merle

    K Merle

    3 weeks ago
    Here is an interesting usecase, where you might see how big usecase can get. https://kotlinlang.slack.com/archives/C0B8M7BUY/p1661928688133889
    Javier

    Javier

    3 weeks ago
    You can have private function in an use case to allow to understand it.
    class SomeUseCaseImpl : SomeUseCase {
        operator fun invoke(id: Id): Flow<Some> {
          val someDto = fetch()
          someDto.saveInDatabase()
          return database.getSomeAsFlow()
        }
    
       // do network request 
       private fun fetch()
    
       // map to entity and save
       fun SomeDto.saveInDatabase()
    
       …
    }
    Arun Joseph

    Arun Joseph

    3 weeks ago
    The approach suggested by https://betterprogramming.pub/how-to-avoid-use-cases-boilerplate-in-android-d0c9aa27ef27 seems to reduce the
    UseCase
    boilerplate while maintaining layering.