Over the long term, your time investment will be repaid as you and your team become more efficient, write code that’s easier to maintain, and spend less time in meetings.
You rarely take things as given without first getting the facts. When colleagues say “because that’s the way it’s done,” or a vendor promises the solution to all your problems, you smell a challenge.
We who cut mere stones must always be envisioning cathedrals.
Every day, work to refine the skills you have and to add new tools to your repertoire.
1. A Pragmatic Philosophy && Software Entropy
When you find yourself saying, “I don’t know,” be sure to follow it up with “—but I’ll find out.” It’s a great way to admit what you don’t know, but then take responsibility like a pro.
Before you approach anyone to tell them why something can’t be done, is late, or is broken, stop and listen to yourself. Talk to the rubber duck on your monitor, or the cat.
Don’t leave “broken windows’’ (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up.
It’s time to bring out the stones. Work out what you can reasonably ask for. Develop it well. Once you’ve got it, show people, and let them marvel. Then say “of course, it would be better if we added…’’ Pretend it’s not important. Sit back and wait for them to start asking you to add the functionality you originally wanted. People find it easier to join an ongoing success. Show them a glimpse of the future and you’ll get them to rally around.
If you give your users something to play with early, their feedback will often lead you to a better eventual solution.
Talking to other people will help build your personal network, and you may surprise yourself by finding solutions to other, unrelated problems along the way. And that old portfolio just keeps getting bigger.
The more different things you know, the more valuable you are.
Know what you want to say. Know your audience. Choose your moment. Choose a style. Make it look good. Involve your audience. Be a listener. Get back to people. Keep code and documentation together.
if you don’t listen to them, they won’t listen to you.
Treat English (or whatever your native tongue may be) as just another programming language. Write natural language as you would write code: honor the DRY principle, ETC, automation, and so on.
A good idea is an orphan without effective communication.
2. A Pragmatic Approach
In the modern world, it’s critical to test ideas and get feedback before you commit to them whole-heartedly.
We feel that the only way to develop software reliably, and to make our developments easier to understand and maintain, is to follow what we call the DRY principle: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Don’t rely on the properties of things you can’t control.
Requirements, users, and hardware change faster than we can get the software developed.
The distinction is important enough to warrant repeating. Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system. Think of prototyping as the reconnaissance and intelligence gathering that takes place before a single tracer bullet is fired.
Our suggestion is fairly simple: don’t spend more effort than you save. Writing a domain language adds some cost to your project, and you’ll need to be convinced that there are offsetting savings (potentially in the long term).
Use paper, not a file or a wiki: there’s something special about the act of writing compared to typing. Give it a month, and see if you’re getting any benefits.
3. Pragmatic Paranoia
But Pragmatic Programmers take this a step further. They don’t trust themselves, either. Knowing that no one writes perfect code, including themselves, Pragmatic Programmers build in defenses against their own mistakes.
The finish what you start tip tells us that, ideally, the routine that allocates a resource should also free it.
Much of the time, tomorrow looks a lot like today. But don’t count on it.
Let’s look at four strategies that help.
Finite State Machines
The Observer Pattern
Publish/Subscribe
Reactive Programming and Streams
Let us suggest three techniques that mean you should never need to use inheritance again:
Interfaces and protocols
Delegation
Mixins and traits
We still want configuration data kept external to the application, but rather than in a flat file or database, we’d like to see it stored behind a service API. This has a number of benefits:
Multiple applications can share configuration information, with authentication and access control limiting what each can see
Configuration changes can be made globally
The configuration data can be maintained via a specialized UI