Hi,
TL;DR: Separating non-trivial logic from both models and views is a good idea.
Trying to separate it from the framework isn't.
This one made me cringe. class GetProductInteractorFactory? Seriously? Haven't
they forgotten "Manager" in that name? And the way they defined the private
vars and public getters in the very first class they present... I think even
modern Java is better than that.
But it goes deeper than the naming and coding style: All of the talk of
Dependency Injection, wrapping everything with redundant levels of indirection
(ViewWrapper)... If you think all of that is appropriate, I would suggest that
Django is not the right framework for you.
A specific point I found worthy of critique is the attempt to make the logic
"framework independent". I think there's about as much sense in that as in an
attempt to make it language independent (hint: the way to tool independence in
the large, goes through microservices).
>
http://mitchel.me/2017/django-service-objects/
>
That one seems much more reasonable. I don't agree with all of their choices,
but the general idea of putting non-trivial business logic in a place that is
separate from all of the "built in" candidates -- models, views. forms and
serializers -- that I fully agree with. And that is what I tend to do.
> What do you think about those suggestions? how do you solve this kind of
> problems and design your django apps?
So, usually, simple methods which mostly help bridge the gap between the way I
think of the objects in the app and the way they can be represented in the
database, go in the models (the Django ORM takes care of some of this gap, but
often not all of it). More complex methods can go there too, if they only
touch one model -- "complex" and "simple" here are judgment calls, anyway.
But, as I said above, non-trivial logic, especially when it needs to handle
more than one model, belongs in separate modules, typically called "logic".
Also typically, these modules contain independent functions, not classes --
these calculations should normally not have "state" of their own.
>
> My current take is Moving all business processes and logic to services,
> resolvers, calculators etc, But they are called through the model as a
> facade and sometime (depends on how complicated the separation is) except a
> model/s as parameter and not regular variables. I also try to wrap results
> in namedTuples/classes and pass them around and not primitive results
>
I see the logic level as standing "above" the models level -- that is, logic
uses models, not the other way around. It is important to keep the layers
separate, or else trouble will come one way or another -- forms/serializers
never call or import views, models never import forms or serializers or logic.
Generally speaking, logic and forms/serializers shouldn't be calling each
other -- both should be called from views. But I'm not sure how religious I am
on that.
Whether results should be wrapped is, again, a judgment call (how complex are
the things you return?). This is a real question, not a rhetorical one: What
do you gain by avoiding primitive return values?
HTH, and sorry for the length,
Shai.