I was recently conducting an audit of a system manufactured by another work team, part of the evaluation process to verify whether or not I could accept the continuity project, something that I usually reject outright, but upon knowing the organization that was working on the project (and trusting a little in their technical experience) I decided to give it a chance and see if I could follow up on it or not.
In the end I did not accept the project, not because I could not take it, but because I did not feel comfortable accepting the project with that design, since surely the client would expect me to be productive from day 0, but I would invest a lot of the initial effort in “correcting” some incorrect practices of the previous supplier.
Always when I try to design the structure of a project, I try to remember that joke that says the following, which is attributed to “John F. Woods”
[…] Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.
In Spanish it would be something like:
[…] Always program as if the guy who ends up maintaining your code is a violent psychopath who knows where you live. Program with reading in mind.
Last night (01/12/2019) before going to sleep, I came across this Tweet from Rizqi Djamaluddin, who I had the pleasure of listening to at the last Laracon Europe:
Not a fan of the term "clean code". Often it's a stand-in for "code the way I find pleasing", which is great, but doesn't communicate much. What is it, really? Self-descriptive code? Less-bug-prone code? Saves-memory code? Static-analysis-enabling code? Easily-extendable code?
— Rizqi Djamaluddin (@rizqi_djm) January 13, 2019
This reminded me of that experience a few days ago while looking at the code. I am a fan of the book “Code Clean” by Robert C. Martin fn-2 and although the book defines different general “good practices”, many times we do not know how to put them into practice in these modern frameworks, such as Laravel or Rails.
A problem that I commonly notice is that we tend not to create enough files or methods and we focus on reusing existing ones. This is why I think it is useful to be able to share two small lessons when developing in these MVC style frameworks:
- Try to have the greatest number of Controllers
- The business logic should never exist in the Controller, but in the model
I will analyze both cases a little below:
#.You have very few Controllers
Let’s start with this point. Something I commonly see is avoiding creating enough Controllers in the system.
A long time ago DDHH, creator of Rails, wrote the following Tweet:
Common problem I see in Rails code: Too few controllers. More controllers doing less work obviates need for many other fancy patterns.
— DHH (@dhh) April 7, 2014
Or in Spanish:
A common problem I see in Rails code: Too few Controllers. More Controllers with less code obviates the need for more “fancy” patterns.
I cannot agree more with this message. The solution is simple: try to create as many Controllers, which are responsible for the least amount of functionality possible.
An easy way to know when you require new Controllers is when you start the process of creating actions other than the common ones (in Laravel they would be those that come in the Resource Controller), which are only:
- Index
-Create -Store -Edit
- Update
-Destroy
If your Controller has more actions than these, it is very likely that you can restructure your code in different Controllers, to address specific functionality.
In the end, creating a new Controller in Laravel is as easy as
php artisan make:controller nombreor in Rails:
rails g controller nombreIf it’s so easy, why aren’t we doing it today?
This practice is best explained in Adam Wathan’s talk “Cruddy by Design” at Laracon US 2017 fn-3.
#.Those models look very ‘skinny’ and your Controllers very ‘fat’
There is a pattern called “Fat models, skinny controllers” widely used in the Rails and Laravel community. The intention does not mean that we should, in fact, have bloated Models, but rather that we should extract the logic that is not part of the Controller’s Request processing and send it to the Model.
Note: The intention is not for the Models to be “fat”, I prefer a more “Skinny Model, Skinny Controller” pattern.
I see the breaking of this practice very commonly when other engineers create Controllers that are in charge of doing things that they shouldn’t, such as:
- Make validations (in Laravel it would be better practice to use Requests fn-4)
- Upload files directly
- Create filters (for the DB)
#.Wrap up
I think if I had a way to summarize all of this it would be through the following:
Try to create more files that do fewer things and follow Clean Code practices (regarding naming, comments, simplicity, DRY, styling, etc.).