bufferapp/android-clean-architecture-boilerplate

Questions about the architecture

dhaksddj opened this issue ยท 4 comments

The use cases assume the caller is also the receiver of the data. In most cases, the presenter will call the use case and wait for the result to return for display purposes.

This is mostly true but there are circumstances when it is not what is wanted. For example, my app has chat functionality which uses a websocket. Incoming messages from the server are received in a Socket class in my data module. I could call a use case to deal with it but (a) it seems dirty that such a low level class is using a use and (b) the result of the use case should notify the presenter (if running) about the event.

Any ideas how to deal with this?

Another issue is that by default, the presenter is running on the UI thread so returning data is also on the UI thread (enforced by the use case infrastructure). However, further processing such as domain model to view model can be required and it would be done on the UI thread by default.

Maybe the thread management should remain with the presenter and the use case is oblivious?

A late response but still..

You can use an Event Bus to push events from the Data Layer and subscribe for these events in a Presenter.
It's also important to note that it's best to not include detailed data in the Event object itself and leave fetching it to the Presenter itself.
So in your case it would mean passing only a newly received message's id in the Event object and then in Presenter load this message via the corresponding Use Case.
Of course, this depends on the limitations you have when dealing with the server. But the idea behind this is to avoid skipping the any business or data logic that you might apply to this data when getting it with a Use Case.
All the information is taken from this thread.

Regarding your question about mapping โ€“ you can resolve this by changing Use Case execute() method to return an Observable that it creates to a Presenter instead of directly subscribing to it.
And then apply all the additional logic you need in a Presenter. You can either apply the same threading logic in the Use Case as before and in a Presenter use something like:

getUser
    .execute(userId)
    // switch from the UI thread in which we return Observable from the Use Case
    .observeOn(ioThread)
    .map { mapper.mapToView(it) }
    .observeOn(uiThread)
    .subscribe()

Or remove specifying threads in the Use Case and do it entirely in the Presenter:

getUser
    .execute(userId)
    .map { mapper.mapToView(it) }
    .subscribeOn(ioThread)
    .observeOn(uiThread)
    .subscribe()

The choice is entirely up to you, it might depend on what makes more sense in regard to other Use Cases usage in your application.
The rule of thumb is to avoid multiple thread switching and delegate a particular responsibility to a single layer if appropriate.

I am in a similar situation trying to apply clean architecture principles on a websockets application.
I did not thought about the event bus but it looks too complicated for my case.

I changed my UseCase interface so it only has a request but not a response, just like all the messages on my application, they might trigger or not one or more output messages. Then I injected a dependency on my use cases so they can reply to the presentation layer any time they want. I know this goes against one of the clean architecture principles: dependencies only point to inside layers, never outside, but I think in a websockets application is normal that use cases involves different messages to different clients and this message dispatching is part of the use case logic.

You can check out the code on https://github.com/z-stars/FakeAndDrawBack/blob/master/src/main/java/com/fakeanddraw/domain/usecase/AddPlayerToGame.java

If you have any suggestion I would be happy to hear :)

hi dear friends.
how to make app with clean architecture which every feature have one module and how to share parent module like domain or data between them ?
please help me i searched all of internet but i found nothing