I try to separate data from business logic....
That's your problem right there: you appear to be taking this as a primary
goal rather than as a technique for making your code more clear and
easier to maintain.
Experienced developers treat things such as "separate data from business
logic" as guidelines, not as hard-and-fast rules. They are not applied
blindly, but applied because (and only when) they achieve better code.
Every time you apply guideline such as this, you should be able to say not
just, "I separated the business logic from the code," but "I separated the
business logic from the code in this situation because it made the code
better than the alternative in the following way: ...."
You need to look at your particular situation and imagine how it would look
and how maintainable it would be if you used technique X. If you're
finding it difficult to imagine, you might even try it both ways. That can
be done in the short term (sketch it out both ways and commit the one you
find better now) or even in the long term (use a certain design now, and
weeks or even months later try changing your approach if the current
approach is not working out). Since the result is dependent on the context
of the code, which changes over time, it may even be the case that when you
start one technique works better but as that area of code changes and
expands, or the code in other connected parts of the system changes, the
best technique to use there changes. (This is one of the reasons we
Note that trying it both ways may even remain embedded in the production
code for some time. It's not unusual for me to have a chunk of code mostly
done in one way but where I've introduced a change in technique for a part
of it to see how it works out. This can take some time and require
examination by and opinions from other developers on the team; as we move
forward and better understand the implications and effects that technique
we'll either start refactoring other code towards that design or reverse
course and bring the new code back to the original design. (Many of my
attempts to improve code start with an incomplete move towards a different
design precisely so that I don't spend too much effort before being able to
evaluate the results, and so that if it turns out not to be going well I
don't need to spend too much effort reversing course.)
If you have any doubts about whether or not separating the business logic
is a good idea in your case, try it. There's no problem having
"experiments" in your code so long as everybody knows that those are
experiments and why they're being done. This should be explained in
comments in the code and also mentioned in the commit message. Writing out
a concise explanation of what problem you're wanting to solve, what you're
trying in order to solve it, and the benefits and problems the new design
introduces will not only help other developers understand what's going on,
but will help you better understand what's going on there.
This "try it out" technique does assume that you can fairly easily change
the code if what you're currently doing does not work out as well as you'd
hoped. That generally presupposes that you have support for this in the
form of being able easily to write and run tests and so on. If you don't
yet have that, you should probably focus some effort on doing that first,
especially since this can significantly affect the design of the code.