Open mr746866 opened 6 years ago
This is a very valid and common scenario. But I prefer approach 2. Presentation layer should handle all presentation logic and I consider your scenario a presentation logic because this is used to display values onto your screen. For me, there's noting wrong in combining multiple use cases in one UI (or presentation). It is very impossible to only have one use case in one UI. So for me, combining use cases in presentation layer should not be a problem.
@mr746866 Get rid of dirty observables away... Use callbacks. Let your presentation layer be object-oriented not procedural. All you need is just a small change in your precious ChatItemModel which is used in presentation-layer. Then, update each of those which has "Unseen-messages" when callback arrives! What if you need fcm to notify your ChatItemModel to display "New arrived messages"? Are you going to merge another Observable into it? or perhaps use a subject? Stop right there. Rx is for streaming not for screaming.
Imho, the first approach is better. The second approach seems to add business logic in presentation layer, which is something that we do not want. If business logic does not live in domain layer then it is not transferable. Also by coupling presentation with business logic, it would be harder to change presentation layer.
My question is better asked through an example.
Suppose I have 2 repositories,
UserRepository
andChatRepository
, like below.The
Account
class is a model inside the domain layer, contains account information associated with a user and exposes them through methods likegetUserId()
,getUserName()
,getPhotoUrl()
which are self explanatory.I also have separate
UseCase
s for those repository methods namedAllFriendAccountsUseCase
andUnseenMessageCountUseCase
.Now suppose, I need to show a list of friends in my presentation layer, each item of which shows the name and photo of a friend as well as the number of unseen messages from him/her, similar to the list shown below.
Obviously I'll need to do at least 2 things.
Create a new model class which contains name and photo of a user as well as unseen message count. Possibly create separate model classes for domain and presentation layer.
Use both
UserRepository
andChatRepository
methods to construct a list, containing objects of the class described in 1. (In short, get theAccount
s of the friends usingallFriendAccounts()
, and then callunseenMessageCount(final String peerUserId)
for eachAccount
, usingAccount.getUserId()
as parameter.)I can think of 2 approaches, each described below.
Approach 1:
Create a model class in domain layer, for example named
ChatItem
, containing user name, photo url and unseen message count.Create a new
UseCase
, for example namedGetChatItems
, which uses bothUserRepository
andChatRepository
methods internally to build anObservable<List<ChatItem>>
.Create a model class in presentation layer, for example named
ChatItemModel
, corresponding to theChatItem
in domain layer. Also create the mapper to transformChatItem
toChatItemModel
and adapter class as needed.Problem:
ChatItem
seems like a presentation detail and seems out of place inside domain model. Should the domain layer know about how its core models are combined and used in presentation layer?Approach 2:
Do nothing on domain layer.
Create a model class in presentation layer, for example named
ChatItemModel
, containing user name, photo url and unseen message count.Use the existing
UseCase
s,AllFriendAccountsUseCase
andUnseenMessageCountUseCase
in the presentation layer to build anObservable<List<ChatItemModel>>
. Also create the adapter class which uses the emitted list.Problem: Combining
UseCase
s in presentation layer seems ugly.Looking for suggestions. Is there an approach 3 that I missed completely?