My question is better asked through an example.
Suppose I have 2 repositories, UserRepository and ChatRepository, like below.
public interface UserRepository
{
/**
* Fetches Accounts of all the users who are friends with the authenticated user.
* @return an Observable that emits all the Accounts of friends in a List.
*/
Observable<List<Account>> allFriendAccounts();
}
public interface ChatRepository
{
/**
* Fetches the number of messages sent by a peer that are unseen by the authenticated user, by the peer's userId.
* @param peerUserId the userId of the peer.
* @return an Observable that emits the number of unseen messages sent by the peer as a Long.
*/
Observable<Long> unseenMessageCount(final String peerUserId);
}
The Account class is a model inside the domain layer, contains account information associated with a user and exposes them through methods like getUserId(), getUserName(), getPhotoUrl() which are self explanatory.
I also have separate UseCases for those repository methods named AllFriendAccountsUseCase and UnseenMessageCountUseCase.
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 and ChatRepository methods to construct a list, containing objects of the class described in 1. (In short, get the Accounts of the friends using allFriendAccounts(), and then call unseenMessageCount(final String peerUserId) for each Account, using Account.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 named GetChatItems, which uses both UserRepository and ChatRepository methods internally to build an Observable<List<ChatItem>>.
-
Create a model class in presentation layer, for example named ChatItemModel, corresponding to the ChatItem in domain layer. Also create the mapper to transform ChatItem to ChatItemModel 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 UseCases, AllFriendAccountsUseCase and UnseenMessageCountUseCase in the presentation layer to build an Observable<List<ChatItemModel>>. Also create the adapter class which uses the emitted list.
Problem: Combining UseCases in presentation layer seems ugly.
Looking for suggestions. Is there an approach 3 that I missed completely?
My question is better asked through an example.
Suppose I have 2 repositories,
UserRepositoryandChatRepository, like below.The
Accountclass 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
UseCases for those repository methods namedAllFriendAccountsUseCaseandUnseenMessageCountUseCase.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
UserRepositoryandChatRepositorymethods to construct a list, containing objects of the class described in 1. (In short, get theAccounts 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 bothUserRepositoryandChatRepositorymethods internally to build anObservable<List<ChatItem>>.Create a model class in presentation layer, for example named
ChatItemModel, corresponding to theChatItemin domain layer. Also create the mapper to transformChatItemtoChatItemModeland adapter class as needed.Problem:
ChatItemseems 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
UseCases,AllFriendAccountsUseCaseandUnseenMessageCountUseCasein the presentation layer to build anObservable<List<ChatItemModel>>. Also create the adapter class which uses the emitted list.Problem: Combining
UseCases in presentation layer seems ugly.Looking for suggestions. Is there an approach 3 that I missed completely?