First of all, I'm not asking where does business logic belong. This has been asked before and most answers I've read agree in that it belongs in the model:
Where to put business logic in MVC design?
How much business logic should be allowed to exist in the controller layer?
How accurate is "Business logic should be in a service, not in a model"?
Why put the business logic in the model? What happens when I have multiple types of storage?
However people disagree in the way this logic should be distributed across classes. There seem to exist three major currents of thought:
- Fat model with business logic inside
- Anemic model and business logic in "Service" classes.
- It depends.
I find all of them problematic.
The first option is what most Fowlerites stick to. The problem with a fat model is that sometimes a business logic funtion is not only related to a class, and instead uses a bunch of other classes. If, for example, we are developing a web store, there should be a function that calcs an order's total. We could think of putting this function inside the Order class, but what actually happens is that the logic needs to use different classes, not only data contained in the Order class, but also in the User class, the Session class, and maybe the Tax class, Country class, or Giftcard, Payment, etc. Some of these classes could be composed inside the Order class, but some others not. Sorry if the example is not very good, but I hope you understand what I mean. Putting such a function inside the Order class would break the single responsibility principle, adding unnecesary dependences. The business logic would be scattered across entity classes, making it hard to find.
The second option is the one I usually follow, but after many projects I'm still in doubt about how to name the class or classes holding the business logic. In my company we usually develop apps with offline capabilities. The user is able to perform entire transactions offline, so all validation and business rules should be implemented in the client, and then there's usually a background thread that syncs with the server. So we usually have the following classes/packages in every project:
- Data model (DTOs)
- Data Access Layer (Persistence)
- Web Services layer (Usually one class per WS, and one method per WS method).
Now for the business logic, what is the standard approach? A single class holding all the logic? Multiple classes? (if so, what criteria is used to distribute the logic across them?). And how should we name them? FooManager? FooService? (I know the last one is common, but in our case it is bad naming because the WS layer usually has classes named FooWebService).
The third option is probably the right one, but it is also devoid of any useful info.
To sum up:
- I don't like the first approach, but I accept that I might have been unable to fully understand the Zen of it. So if you advocate for fat models as the only and universal solution you are welcome to post links explaining how to do it the right way.
- I'd like to know what is the standard design and naming conventions for the second approach in OO languages. Class names and package structure, in particular. It would also be helpful too if you could include links to Open Source projects showing how it is done.
Thanks in advance.