I just finished reading the book “The 7 Habits of Highly Effective People” by Stephen Covey. At the end of the book, he explained how principles are universal and timeless, while the practices can change case by case or over time. What he said triggered a chain of thoughts. First, I immediately started thinking about principles I’ve been studying all over my career. There were SOLID principles, KISS, and YAGNI. Then came the long train of best practices. A handful of those practices had early returns, implementing small functions and creating short but elegant names. Although I’ve had my differences with Stephen Covey throughout the book, he was right about something: Principles come before practices. The best practices we, software craftspeople, talk about all day do come from universal principles.
Let’s analyze some of the best practices through examples. First, having early returns is a way to simplify the flow of the code. By returning early from certain conditional statements, you avoid ending up with nested code blocks: the code and the logic you implement become simpler to understand. However, the value of early returns multiplies by the length of the function. So if you have a longer function, returning early will save you a lot of trouble.
On the other hand, if you achieve short functions, early returns would not add the same value, although still helpful. On top of both, if you can come up with a concise name for your function, perhaps the next developer would not have to read inside your function to understand it anyway. As you can see, applying best practices help by default. However, the value you gain depends on the case.
Now let’s move on with the principles. KISS and YAGNI are two perfect examples of principles. “Keep It Simple, Stupid” won’t tell you much about how you should structure your code but will ask you to keep things simple. Simple is easier to understand: this is a universal fact. A similar principle goes by the phrase “You Ain’t Gonna Need It.” It is a reference for avoiding premature optimization. It’s a beautiful principle that stresses the unnecessary complexity the assumptions could introduce.
From its looks, I could also argue that best practices are coming from sound software principles. We can attribute all three best practices I talked about to KISS. For the same reason why implementing shorter functions is a best practice, I can also come up with the opposite being the best practice: Implement sufficiently long, deep functions. Why? Because shorter functions don’t necessarily provide simplicity. If we create shorter functions without thinking, we’ll end up with shallow functions that provide no independent value. So practices may change, but we can still understand whether it’s a best practice or not by looking at the principle behind it.
We talked about universal principles and then the best practices. Where, then, I thought, do SOLID principles fit in? We can attribute all five to specific use cases—wouldn’t this make them best practices instead? We can find a middle ground for particular principles like SOLID. Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion principles are Object-Oriented Design Principles. They work very well within the OO domain. I’m not going to discuss the usefulness or the ongoing discussion of whether they are still valid today or not. But I’m going to say that, although they’re OO-specific principles, they’re based on two universal principles: High cohesion, loose coupling. These two notions gave birth to the SOLID principles and are helpful regardless of the field or the domain. That’s what makes principles so powerful.