Question
Do you think it’d be easier to switch a project from using service/selector functions for business logic to using custom querysets/model managers for business logic or vice versa? Or about the same effort in either direction?
Context
I’ve been consuming a bunch of info (including many existing forum posts on here) about views and where to put “business logic.” A high-level summary of my freshly minted mental model for this topic:
- Most people want views to default to being about the request/response exclusively without business logic in them, but it’s fine to make a justified exception to this default if there’s a good reason.
- The two recommended ways to include business logic (since it’s not in the views) are:
- use functions located in files named services / selectors or similar (a la Hacksoft styleguide, RAPID architecture, etc.)
- use custom model managers / queryset managers (a la James Bennett’s two posts (1 & 2), Django Views The Right Way, etc.)
- In between those above two extremes, there’re a bunch of opinions that say something like, “we basically subscribe to [one of the above recommendations], but what works for us is to have the following modifications/well-defined exceptions to it: [blah blah blah]”
- Another option (usually seen recommended to beginners) is to keep the business logic in the views until a view is painful (usually defined as long and/or confusing) and then refactor some or all of the business logic out of the view in one of the ways described above.
Also it seems like huge chunks of the discussions are focused more around organizational tradeoffs (aka: can you find what you need when you need it?) and human behavior (aka: making it hard to do problematic coding practices and easy to write “better” code) rather than inherent technical problems with either approach (e.g. in Django structure for scale and longevity, a creator of the Hacksoft styleguide Radoslav Georgiev says, “You can achieve absolutely the same thing with services and selectors with custom managers and custom query sets but this kind of makes you want to use them in APIs and tags and templates and so on. So it’s basically the same, but we just define a nice boundary around it.").
I’ve seen several knowledgeable voices say something along the lines of “you can be successful with whichever way you lean as long as you’re paying attention and not just on auto-pilot when making decisions about what’s right for your project/team”.
I’ve also seen several comments that say, “we tried it [this way], but switched to [that way].”
My overall conclusions/interpretations are:
- it’s a subjective decision that is highly dependent on the requirements of your project and your personal (or team) preferences
- there is no “most benefit” specific practice - as in, even though both extremes imply that “most” projects would benefit from their way, it really hasn’t been proven out in terms of adoption that one way would benefit “most” projects. There is a “most benefit” general practice - as in, most projects would benefit from adopting something for standards to address this topic, but you have to individually look at the options and decide what that “something” is for your specific project.
- you can’t know which approach is “right” for your project until you try one in practice
- it seems like applying either of the approaches would be roughly the same level of effort to implement
- the consequences of picking one approach that you later deem to be “wrong” for your project comes down to how much code you’d have to change/move to the replacement approach and ensuring that nothing gets messed up while you’re changing/moving to the replacement approach. So the earlier you know the better, but you still can’t know which is “right” for your project until after you’ve already tried one anyway. In other words, there aren’t secondary consequences of changing approaches outside of moving/reformatting your code in line with the new approach.
So in other words, as long as the code is consistent in how it’s organized/formatted, it kind of doesn’t really matter which approach you choose until something specific comes up in your project or for your team and provides a justification that it would be better to use a different approach.
Agree? Disagree? Thoughts more than welcome.
Specific-to-me context
I don’t have a team that is dictating their preferences on this choice to me. I’m writing my Django project with the known intent to eventually have others be doing the code development. Because I don’t know who I’d be handing development off to, I can’t know their preferences for something like this right now.
I also don’t have enough experience to know what I personally prefer either, and at this point having read all these things, leaning toward either extreme seems valid (
). I think I need to “just pick something” using my best guess and move forward to see what happens.
“Just picking a way that seems right” seems okay to do for my immediate predicament of wanting to have more organized/consistent code that I don’t cringe at when trying to edit a view, but I also don’t want to make a decision now that will make life unnecessarily hard for whomever I hand it off to in the future (and/or my future self).
It seems to me that if the choices are roughly equivalent and either one can be successful, then I probably want to lean toward first trying whichever approach is easier to switch away from in the future (if there is one). That way, there’s a little less pain if I or others later decide that this early decision was not the best choice for the project.