The Code Shall Set You Free
The code should comment itself.
That just sounds silly. It’s like saying a car should drive itself. But it can be done. A lot of this change of heart about comments has come from my commitment to becoming a better developer and spending countless hours reading about the practice of great development, which is something I’ve written about in the past. I’m a big believer that most of the time if you need to comment a piece of code, then it’s either bad code or too complicated. Of course that’s not true 100% of the time, but for the other 99% it really is. There are cases where things need to be explained and especially warned of, but a lot of the time, commenting is just an easy escape from having to do “proper” coding. It took me years and years to get a basic understanding of proper OO and I’ve still got a long way to go to reaching Journeyman levels of understanding, but I would always create large objects with huge and complex methods, when really what I needed were more concise classes with more responsibility for what they should be able to do. It’s not object orientated when you’re focus is on the method and not the class.
A simple example of commented code:
# Feed the fish. def check_food(food) # Check if Fish has eaten more then 5 hours ago. if self.last_meal_time < 5.hours.ago return "Not hungry" # Check if the Fish eats this food. elsif !self.edible_foods.contains?(food) return "Can't eat that!" # Make sure the fish isn't being underfed. elsif food.amount < fish_feeding_amount(self.type) return "Not enough food." # Make sure the fish isn't being over fed. elsif food.amount > fish_feeding_amount(self.type) return "Too much food." end # Eat food. self.eat(food) end
Most comments can be done away with. If we split out functionality into more concise bits, then just reading the code should explain what’s happening better:
def feed(food) return "Not Hungry" if self.recently_eaten? return "Can't eat that!" if self.does_not_eat?(food) return "Not Enough food" if self.not_enough_food?(food) return "Too much food" if !self.too_much_food?(food) self.eat(food) end
This isn’t a great example as once again the validation of whether the food can/will be eaten should move into it’s own method or class ever. If we’re follow Uncle Bob’s SOLID principles, the above examples breaks the OCP (Open Closed Principle) where entities should be open to extension and closed to modification. If more validation rules were needed, then that would require the code to be modified.