Skip to main content
Donovan LaDuke - Developer

Avoid "Useless" Cases in Layered Architecture


Featured in Android Weekly Issue 610

It is common practice in layered architectures to create classes called "Use Cases". These classes contain individual units of logic that can be tested in isolation, composed together to create more complex logic, and are often the most important part of an application's architecture. It would seem that you would want all code paths to go through a Use Case, but it can actually be more valuable to skip them sometimes.

The Useless Case #

If every piece of code must include a use case, then the code base will end up with some number of "Useless" Cases, that is Use Cases that do nothing but act as a pass through. This is a common problem in apps that are primarily CRUD based. In this case, why not approach the issue with "YAGNI" - You Aren't Going to Need It! First off, a Useless Case isn't actually testable, there is no logic. Second, a Useless Case isn't composable, the other Use Case can just use the data source/repository directly. Finally, a Useless Case adds nothing to the applications architecture, it's just an extra file that developers have to wade through to get to the code they actually care about. Start with no use case and only add one in when there is coordination, validation, or other logic needed.

Example #

Imagine a basic Task List app that loads data to display, it has no additional work to do so the use case would look something like this.

class GetTaskListUseCase(
  private val taskRepository: TaskRepository,
) {
  operator fun invoke(): List<TaskItem> {
    return taskRepository.getTaskItems()
  }
}

This use case doesn't do anything, it's just wasted code. There is nothing to test and you can just call taskRepository.getTaskItems() directly. So this class can be deleted. Voila! Less code to maintain and manage. Now in the future if requirements change, you can add the use case back if you need to, but you aren't stuck with it if those changes never come.

Conclusion #

Hopefully this shows the value of removing Useless Cases from the codebase. As always, this should still be done with care and with the support of the codebase owners. Some teams like the consistency of having Use Cases for everything, even if they aren't necessary. I've worked on projects that have taken both approaches, and in each case the code was just fine if not overly verbose at times. Try it out, and see what style works best in each particular case. Until next time, thanks!

Did you find this content helpful?

Please share this post and be sure to subscribe to the RSS feed to be notified of all future articles!

Want to go above and beyond? Help me out at one of the services below, it goes a long way in helping run this site. Thank you in advance!

Donate with PayPal Buy me a Coffee on Ko-fi Support me on Patreon