DEV Community

Cover image for Do We Really Need Use Cases in Mobile Apps?
Valerii Popov
Valerii Popov

Posted on

Do We Really Need Use Cases in Mobile Apps?

In mobile development, use cases are often used to encapsulate business logic, providing a clear structure for handling interactions between the app’s presentation layer and data layer. However, in many mobile apps, especially those with straightforward data access needs, use cases end up being simple wrappers around repository calls. Let’s explore what use cases are, why they’re commonly used as repository wrappers, and when you might want to consider omitting them altogether.

1. What is a Use Case?

A use case in software development represents a specific action or task within the application’s business logic. In mobile development, use cases are classes that contain single responsibilities, often designed to perform a single action, like FetchUserProfile or GetUserPosts. They serve as intermediaries between the ViewModel (presentation layer) and the repository (data layer), aiming to encapsulate business logic for a single action.

Here’s an example of a simple use case class in Kotlin:

// Example Use Case in Kotlin
class FetchUserProfileUseCase(
    private val userRepository: UserRepository
) {
    suspend operator fun invoke(userId: String): User {
        // The use case orchestrates the fetching of user profile data.
        return userRepository.getUserProfile(userId)
    }
}
Enter fullscreen mode Exit fullscreen mode

This structure can be beneficial if there’s complex logic involved in obtaining the User data, like validating the userId or applying filters, caching, or error handling. However, if the use case merely calls the repository function, it might add unnecessary layers to the code.

2. Use Cases as Wrappers: Adding an Extra Layer

In many mobile apps, especially those with straightforward data requirements, use cases often end up acting as thin wrappers around repository calls, simply forwarding requests to the repository without additional business logic.

Here’s an example of a "wrapper" use case:

class GetPostsUseCase(private val postRepository: PostRepository) {
    suspend operator fun invoke(): List<Post> {
        // Just calls the repository, without any additional processing.
        return postRepository.getPosts()
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, GetPostsUseCase doesn’t provide any real value on top of what the repository already does. The repository itself could be directly accessed by the ViewModel, following the Repository Pattern, without sacrificing readability or maintainability. This pattern calls data from a centralized source and could be an ideal way to streamline code.

3. When to Consider Omitting Use Cases

In cases where a use case doesn’t add value beyond calling the repository, omitting it can simplify your codebase. Calling the data layer directly via a repository in these situations makes your code easier to read and maintain without sacrificing structure.

class ProfileViewModel(
    private val userRepository: UserRepository
) : ViewModel() {
    fun getUserProfile(userId: String) = liveData {
        emit(userRepository.getUserProfile(userId)) // Directly calling the repository.
    }
}
Enter fullscreen mode Exit fullscreen mode

By directly using the UserRepository, we reduce the need for an extra class and method that serves no additional purpose. For straightforward data access patterns, the repository pattern alone can keep the code well-organized while avoiding the verbosity and potential maintenance of unnecessary use cases.

Conclusion: Streamline Where Possible

While use cases can provide clarity and structure in complex applications with business logic-heavy features, they are often overused as simple data wrappers in mobile apps. In situations where they don’t contribute additional functionality or encapsulate business logic, omitting empty use cases can simplify your code. As always, choose what best fits your app’s needs and keep your code as lean as possible.

Top comments (0)