In this post I will be talking about David Thomas and Andrew Hunts’ The Pragmatic Programmer book, specifically Chapter 7, in this chapter we will talk about The Pragmatic Approach.
Listen to Your Lizard Brain
All of us have have an animal side that represents in our instincts, throughout the years we have been taught to eliminate that animal part from us, but the reality is that this part is really important. Many people that have been attacked or robbed, sensed something different or uncomfortable before getting assaulted, that’s our animal side screaming danger. In coding, this applies in the same way. We need to listen to our guts, if a design, architecture, or code seems weird or funny, we should not ignore our feelings. This ability is really helpful in the daily life as well as the programming world.
When we are programming there’s a common fear to the blank page, or the opposite scenario in which we are going to modify an existing code that it’s not ours. Either way, we should still listen to our guts and be relaxed. There’s no need to panic, if you have a blank page think first of doing a prototype, and as things move forward you will forget that you started from scratch and start to develop the prototype idea, you need to pass from the state of nervousness to the one in which you are focused on getting things done or solving a certain problem, same applies to the scenario in which you are modifying someone else’s code, focus on the problem and make a prototype of the solution and start implementing it, obviously before doing this you should interpret and understand the existing code.
Programming by Coincidence
Many times we make certain actions or tests to determine something, but sometimes those actions or tests are not the correct ones, for example, if a soldier walks into a big land of grass he suspects that it could be a minefield, he walks slowly, pokes the floor and as he advances he feels more secure about his tests and starts walking normally when suddenly he gets blown to pieces. His first tests were successful but only by coincidence, he didn’t made the correct ones and that’s why in the end he got blown away. In programming the same happens, many times we make tests and pass but after some weeks the program fails, these tests where just ok by coincidence, the real tests in production revealed that not all edge cases were considered. We need to make sure to cover all the cases and possibilities as much as possible.
We need to program deliberately, here are some tips to do this:
- Always be aware of what you are doing.
- Can you explain the code, in detail, to a more junior programmer? If not, perhaps you are relying on coincidences.
- Don’t code in the dark. Build an application you don’t fully grasp, or use a technology you don’t understand, and you’ll likely be bitten by coincidences. If you’re not sure why it works, you won’t know why it fails.
- Proceed from a plan, whether that plan is in your head, on the back of a cocktail napkin, or on a whiteboard.
- Rely only on reliable things. Don’t depend on assumptions. If you can’t tell if something is reliable, assume the worst.
- Document your assumptions.
- Don’t just test your code, but test your assumptions as well. Don’t guess; actually try it.
- Prioritize your effort. Spend time on the important aspects; more than likely, these are the hard parts. If you don’t have fundamentals or infrastructure correct, brilliant bells and whistles will be irrelevant.
- Don’t be a slave to history. Don’t let existing code dictate future code. All code can be replaced if it is no longer appropriate. Even within one program, don’t let what you’ve already done constrain what you do next — be ready to refactor.
You can estimate the length of a project and also the stories and this is really helpful to determine the project’s development time. Algorithms can also be calculated in how much time it will take to execute them. The Big O notation is a pretty popular term and there’s a whole science behind it in how to calculate any algorithms time to execute. In a projects development cycle you should estimate your algorithms order. Calculate these times and test if the order is correct. Also, take in count that fastest is not always the best, you need to see what your project needs. There’s a point in which the time difference of a given algorithm makes no difference and maybe the time to implement it is much longer.
You should refactor when you learn a better way to do something. It doesn’t matter if you learned it minutes ago or in 3 weeks, always refactor if you can. Any number of things may cause code to qualify for refactoring:
- Duplication: You’ve discovered a violation of the DRY principle.
- Nonorthogonal design: You’ve discovered something that could be made more orthogonal.
- Outdated knowledge: Things change, requirements drift, and your knowledge of the problem increases. Code needs to keep up.
- Usage: As the system gets used by real people under real circumstances, you realize some features are now more important than previously thought, and “must have” features perhaps weren’t.
- Performance: You need to move functionality from one area of the system to another to improve performance.
- The Tests Pass: Yes. Seriously. We did say that refactoring should be a small scale activity, backed up by good tests. So when you’ve added a small amount of code, and that one extra test passes, you now have a great opportunity to dive in and tidy up what you just wrote.
You should Refactor Early and Refactor Often.
Test to Code
Testing is not about finding bugs, it is used to make your system more manageable and consistent, they will help you to validate future changes and make it easier to detect bugs. The tests are the first user of your code, this will help to visualize the tests and that believe will help you build them also. TDD is pretty popular and is one of the best practices of this. Always build your tests End-to-End, not Top-Down or Bottom Up, always build small pieces of end-to-end functionalities.