Skip to content

Where to combine methods from different repositories? #276

@mr746866

Description

@mr746866

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.

chat_list

Obviously I'll need to do at least 2 things.

  1. 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.

  2. 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:

  1. Create a model class in domain layer, for example named ChatItem, containing user name, photo url and unseen message count.

  2. Create a new UseCase, for example named GetChatItems, which uses both UserRepository and ChatRepository methods internally to build an Observable<List<ChatItem>>.

  3. 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:

  1. Do nothing on domain layer.

  2. Create a model class in presentation layer, for example named ChatItemModel, containing user name, photo url and unseen message count.

  3. 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions