This article is just highlighting the tip of the iceberg from the original book. Please read the book for better detail and examples given by the author.
Good Design is easier to change than Bad Design. Thus, we believe in the ETC principle: "Easier To Change".
ETC is a Value, not a Rule. It is a guide to help you make decisions. It requires some initial conscious reinforcement, by keep asking yourself during development, "Is it easier or harder to change?"
Two way to validate if your code is ETC:
- Try to make what you write replaceable, to make sure it won't become a roadblock in the future
- Note the situation and choice you made, to reflect back on when you need to revisit the code
Programmers are constantly in maintenance mode. Whatever the reason, maintenance is not a discrete activity, but a routine part of the entire development process.
To develop reliable software, easier to understand and maintain, is to follow the DRY principle:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
These are the problems of duplication along with the general suggestion:
DRY is not just to avoid copy-pasting code, but it is about the duplication of knowledge or intent. When a part of the code logic needs to change, and the changes apply to different places, it means your code is not DRY.
Not all code duplication is knowledge duplication. If there are two functions that do similar things but each has a different intent or purpose, then they are still DRY.
When you comment on a function with the details of how the function works, then the comment is a duplication of the code. The name of the function should already say what it does, and the details are laid out in the source code.
A data structure represents knowledge and it may have duplicated data. Where possible, always use accessor functions to read/write the attributes of objects to decouple the data structure from the implementation module.
Your code interfaces to the outside world. If the interface change, the other code that uses it may break. This duplication is inevitable but can be mitigated. Find tools that help you standardize and document your API to be shared across teams.
Perhaps the hardest type of duplication to detect and handle. We feel that the best way is to encourage active and frequent communication between developers. Make the code easy to reuse. If it isn't, people won't do it, thus risk duplicating knowledge.
In computing, the term has come to signify a kind of independence or decoupling. Two or more things are orthogonal if changes in one do not affect any of the others.
These are the benefits of Orthonogality:
- Gain Productivity: Reduce development and testing time since changes are localized, promote reusability, and composable.
- Reduce Risk: The code is isolated. Make any changes and it only affects that area if there is a bug.
Several techniques to maintain orthogonality:
- Keep your code decoupled
- Avoid global data
- Avoid similar functions
An orthogonally designed and implemented system is easier to test. Writing unit test is itself an interesting test of orthogonality, to validate what does it takes to build and run the module.
We don't always make the best decisions the first time around. The mistake lies in assuming that any decision is final, and not preparing the uncertainties that might arise.
Make your code easy to change. Build abstraction layers. Break your code into components.
The principle applies to projects when you're building something that hasn't been built before, to build a software that can be tested for immediate feedback while moving towards a goal.
Look for the areas where you have doubts and the biggest risk, and prioritize it during development.
Tracer code is not disposable, you write it for anticipating the production code.
Advantages of the tracer code:
- Users get to see something working early
- Developers build a structure to work in
- You have an integration platform
- You have something to demonstrate
- You have a better feel for progress
Tracer code may not always hit their target. Make sure your tracer code is easy to change, to be validated based on feedback, and keep improving to generate a more accurate version of the code quickly.
Tracer code is not Prototyping. Prototyping generates disposable code. Tracer code is lean but complete and forms part of the skeleton of the final system.
Prototyping is much cheaper than full-scale production. It is meant to analyze and expose risk, and make corrections at a greatly reduced cost.
We tend to think of prototypes as code-based, but it does not always have to be.
Prototyping is a learning experience. Its value lies not in the code produced, but in the lessons learned.
Details to ignore in the prototyping:
You must make it very clear that the prototype code is disposable, incomplete, and unable to be completed. This avoid the stakeholder to think that the prototype is ready for production use.
In some cases, Pragmatic Programmers can go to the next level and actually program using the vocabulary, syntax, and semantics of the domain.
Estimate to avoid surprises. By learning to estimate, you will be able to show a magical ability to determine the feasibility of the task/project.
All estimates are based on models of the problem. A basic estimating tricks that always gives good answers: ask someone who's already done it.
You may able to give estimation in two way:
- Give the optimistic, most likely, and the pessimistic estimate
- Give initial estimated time, and update the schedule on every development iteration
When asked, you don't have to give your estimation directly. Spend some time going through the mental model for better accuracy.
I would love to read your sharing of your approach as well. Please leave a comment and I'll be happy to respond. Thank you!