Recently I was reminded of what could be a good strategy to organize a codebase in a back-end web-service consisting of several use-cases. A colleague told me of the problem they had, and how they solved it.
They started separating the application-logic in a class that contained only that: application logic. Accordingly, its name was: AppLogic. The controllers would only talk to the app-logic. This in turn would get the dependencies it needed, and invoke the necessary methods on those dependencies (usually involving the persistence layer).
At the beginning of the project everything was fine. This was an acceptable approach since the uses-cases covered by that app-logic remained within grasp. But of course over time the use-cases started to grow and the amount of methods started to pile up. It didn’t make sense anymore.
The solution they came up with is something I think I saw somewhere before (was it part of DDD maybe?) but as my colleague mentioned it again, it struck me as an excellent idea: they started to organize their use-cases into … use-case-objects!
Each use-case would be encoded in a class. That class would get only the dependencies needed to perform the use-case needed. That class could have its own private helper methods, without polluting other use-cases. The use-case class would have a name reflecting the implemented use-case, and a entry-point method with a similar name.
This not only made a “god class” like AppLogic no longer necessary, but created an opportunity to have a nice overview of the different use-cases supported by the application. I did not see the code, but I can imagine that things like choosing appropriate package-names for these classes would be a nice way of grouping them, if applicable. I can also imagine a more clear testing approach and code as a result.
All in all the idea interested me very much, especially for code like in a web-based back-end, where each request results in the execution of a use-case. It only feels natural to choose an approach like this.