Where Do You Put Business Logic Besides Models?

While developing my application I’ve tried to contain all business logic in the models.

However, this has caused some models to become very long. I recently read the excellent book Clean Code (by Robert C. Martin) and it taught me to make my classes single-purposed and small. My current models with tons of methods clearly violate that philosophy.

Since a lot of logic is not really tied to models, I am considering to move it elsewhere. For example I have a lot of methods in one model which are used to parse an incoming JSON file with raw data and create/update all kinds of models in my database. This could be moved into a separate class (or classes), but those won’t be a model (since it would not have any attributes to be validated etc.)

So my question is: what are the best practices to organise business logic that doesn’t belong to a model? I’ve considered /helpers and /components, but those are also specific things in Yii2. Should I just create a folder like /logic and put my classes in there, or is there a better way? And does anyone have suggestions about where to put factory classes etc…?

I use the "/components" path.

Other ways that might apply to you is to wrap that functionality in a "module" or an "extension".

I’m keen to find out what others think of this too, so please share your experiences

Yeah, my first approach was also to use components, but those seem meant to be application-level components that can be accessed via Yii::$app->componentname (correct me if I’m wrong on this)

I use components folder too.

Usually I move helpers to subfolder of components called ‘helpers’.

I can’t remember any mentions or tips about that from official docs, maybe you should decide about this indepently.

But the core developers tips are always welcome. :)

Also if it’s possible to use inheritance or behaviors to store common logic and avoid duplicating code it’s fine too. But it really depends on type of that logic.

I’ve been thinking a lot about this topic as well. I haven’t read Clean Code, but I know others who love the book. I am familiar with SRP, single responsibility principle, and it seems like php frameworks violate this all the time. However there is a key critical difference between PHP and other compiled languages like Java, namely that PHP is compiled at runtime (geesh, I really hope I’m describing this accurately) and this causes it to be less efficient. This drop in efficiency will play itself out at scale if you did a large enterprise project and observed strict SRP, you could have thousands of classes. Since PHP has to read through all the files and directories before compiling (again, I hope I’m describing this accurately), it can cause performance issues. If you factor in the framework itself, which already has a large codebase behind it, it wouldn’t take that much to reach a tipping point, if you tried to implement a strict sense of SRP.

There’s no doubt that SRP leads to cleaner, easier to follow code, which helps everyone involved in a project. I should mention that my own programming skill is still at novice level, but I have been professionally involved in enterprise development for many years in a different role and have seen these issues arise at various times. You can try to increase the number of servers to offset performance problems, but that is an expensive solution that doesn’t always solve the problem. Caching solutions help, but you can still end up with bloat that will unnecessarily slow down your application.

I think you have to find a balance and be mindful not to create too many directories and classes. As I build my first implementation of the Yii2 advanced template, I’m still learning what that is…

Thanks for your thoughtful reply! I have also considered the effects of cross referencing all those different files, but then I realise how the Yii2 framework itself is spread across hundreds of files, so adding a dozen or so of my own wouldn’t make that much of a difference I guess :slight_smile:

Just add more classes. It doesn’t matter which directory are these placed into or if these are components or plain PHP classes.

1 Like