Chp 1 – A Pragmatic Philosophy
Summary
This chapter is a high level introduction to several aspects in the book that are detailed more in later chapters. Basically there are principles that can help any programmer no matter where they are in their career development. It’s a guideline for how to conduct yourself, how to design and build your code and how to maintain it.
Key Topics
- The Cat Ate My Source Code – You are responsible for taking charge of your career and knowledge training. Never be afraid to admit ignorance or error but always follow up with “I will find out” or “I will correct that”. Always offer up solutions or alternatives if something isn’t possible in it’s current form.
Take responsibility when necessary. Never blame others for anything. That sets a negative tone and queues others to do the same in similar situations.
- Software Entropy – entropy means disorder. It is sometimes called software rot. It starts small but if not managed can quickly grow. Example is the broken window scenario. You see a nice building and it gets a broken window. Rather than fixing the window right away, you let it go. Soon more of the building degrades. Tenants stop caring about it, it loses its shine and before you know it, it becomes unlivable. Moral: always fix the window if it breaks. Don’t let small problems become bigger and bigger until they take over everything.
- Stone Soup and Boiled Frogs – Three soldiers came to town carrying no food. Each villager hoarded their own food stores and wouldn’t share with anyone. The soldier’s filled a pot with water and 3 stones. Curious villager’s came over asking what they were making. The soldier’s said yummy stone soup. But you know what would make it even better? Some Potatoes.
A villager ran home and came back with potatoes.
The soldier’s then said, meat would really hit the spot.
Another villager ran home and came back with meat.
This went on for a bit until the soup was an amazing mix of several different ingredients. The soldiers removed the stones and then shared the soup with all the villagers.
This analogy can be used for building a new project. Get the end users to feel they are a part of things and that their ideas matter. Have them help you make the project succeed. In the end, share the soup.
- Good Enough Software – It’s better than have something working well any day over having something work perfectly. Perfection can be strived for but will never be fully realized. Your customers will be thrilled with a working project built well than a non-working one because you are still trying to get it perfect.
- Your Knowledge Portfolio – In tech you always have to be learning. You need to make your learning process a habit you follow. Some type of knowledge needs to occur daily. You can use habit tracking to see your knowledge grow visually.
- Invest regularly – Even small learning adds up over time.
- Diversify – The more different things you know the more valuable you become.
- Manage risks – Just like stocks, you should look to invest your time in a 80 / 20 rule. 80% tech you know will be around a long time and 20% emerging that may take off. If it doesn’t take off, you haven’t wasted all your time on it but if it does….
- Review and rebalance – As with anything, you should assess and reevaluate periodically to make sure the things you are learning are still relevant today as when you started learning them. You can use things like Google Trends to see what things are on fire and what have fizzled out.
Goals
* Learn at least 1 language per year
* Read 1 tech book per month
* Read 1 non tech book per quarter
* Take classes
* Participate in local user groups and meetups
* Experiment with different environments
* Stay current
- Communicate!
- Know your audience – what do they want? have they been burned in the past? How can you avoid those pitfalls?
- Know what you want to say – have a rough outline of what you will be communicating to them.
- choose your moment – don’t decide to meet on a Friday and 4pm etc.
- choose a style – delivery can be important. How do they like to receive their knowledge? Do they like short briefings? Long meetings? Email reports? Just the facts? etc.
- Make it look good – always be proud of your information. Present it in a professional manner.
- Involve your audience – Listen to what their concerns are. never leave anyone hanging, always get back to them if you can’t answer immediately.
- Documentation – find ways to document (either manually or automated) your data / processes. It helps you and everyone on the project in the long run.
Chp 2 – A Pragmatic Approach
Summary
- The Essence of Good Design – Make your code ETC (Easy To Change). Develop it with the future in mind so that upgrades and other things don’t break it.
- DRY (Don’t Repeat Yourself) – There may be several places in your application that do similar or the same things. Rather than coding each separately but using the same functionality, find ways to consolidate code so that you are using the same code in multiple places. This saves on overhead, troubleshooting and upgrading and maintenance. Also you should never comment your code with an explanation of what a code segment does, rather use naming conventions etc. that allow another coder to determine what the code is doing for themselves. This is a much more efficient way of doing things.
Make sure that you and your team members aren’t duplicating work for each other as well. This can be managed with quick meetings, code reviews etc. so that everyone knows what everyone else is working on and can collaborate.
- Orthogonality – Two or more things are orthogonal if changes in one do not affect any of the others. Example: in a well designed system the db code is orthogonal to the UI.
Benefits include
* You gain productivity because small simple components are easier to write / maintain that giant blocks of code.
* It promotes reuse because components have well-defined responsibilities.
* There is a subtle gain in productivity.
Reduces Risk
* Bad sections of code are isolated and less likely to spread.
* The system is less fragile.
* Better testing since components are smaller.
* You are not tied to 3rd Party Vendors since any code with them is smaller and isolated.
When writing code
* Keep it decoupled.
* Avoid global data.
* Avoid similar functions.
- Tracer Bullets – Look at the project’s most important requirements and areas you might have doubts or confusion about. Then build your code around these so that you can show the users and get feedback. This helps you and them get a better idea of where the target is and how to hit it now. There might be things they didn’t think about when they initially sent requirements or things might have changed.
Advantages of this
* Users get to see something working early.
* Devs build a structure to work in.
* You have an integration system which you can now add to.
* You have something to demonstrate.
* You have a better feel for progress.
- Prototypes and Post-it Notes – Prototyping is a high level way to map out general things like:
- architecture
- new functionality to existing systems
- structure or content of external data
- 3rd party tools
- performance issues
- UI design
Use Post-it Notes or whiteboards to map out processes or flows.
- Estimating – Use these rules
- give broad ranges rather than highly specific ones.
- Saying something will be done in 130 working days is not as good as saying it will be ready in about six months. The latter is much more open to sliding the date in case of issues.
- give broad ranges rather than highly specific ones.
How to determine an estimate * Understand what is being asked * build a model of the system to help you * break the model into components and identify each one’s parameters * see which are critical and which are not * look at past projects or tasks that may have been similar and how long they took
Also, add completion metrics to your project post-mortems so you can use these in future estimation.
Chp 3 – The Basic Tools
Summary
Invest in your toolbox. Identify what tools you will need regularly and then branch out to those one offs that are more specialized later.
- Power of Plain Text – study Unix command line (it will get you far)
- Shell Games – GUI is great but using a shell is better. There is a higher learning curve but rewards are vastly better.
- Power Editing – Learn to edit in the shell (VI editor) using the keyboard instead of the mouse.
- Version Control – IMPORTANT! Learn Git fully so that you can succeed here
- Debugging –
- Sometimes you need to watch the user step through the process if you can’t recreate the bug yourself.
- Rubber Duck – talk to the rubber duck and you might answer your own questions.
- Use process of elimination.
Debugging Checklist
* Is the problem a direct bug or a symptom?
* Is the bug in the framework, OS or your code?
* If you explained the bug to a coworker, what would you say?
* If the code passes unit tests, are the complete enough?
* Do the conditions that caused this bug exist anywhere else in the system waiting to hatch?
- Engineering Daybooks – Carry a notebook around everywhere. Use it for:
- meetings
- ideas
- notes
- information you might need later (reference)
- rubber ducking
Chp 4 – Pragmatic Paranoia
Summary
This chapter details methods to follow when coding your projects to keep them from breaking while you fix them.
- Design by Contract – document the major aspects of the project beforehand. Then show and sign off with all the stakeholders so that everyone is on the same page. This sets the initial expectations where they should be.
- Dead Programs tell no lies – Don’t fall into the trap of assuming that particular errors just can’t occur. Use Try…Catch in order to grab all possible errors so that you can code for them proactively.
- Don’t Outrun Your Headlights – Make sure you take small, incremental steps while you develop. Doing so makes it much easier to notice and correct errors before they become major problems later.
Chp 5 – Bend, or Break
Summary
This chapter is all about making sure your code is flexible enough to adapt and change instead of being too rigid. Code that can’t adapt, like species has no hope for survival. The following techniques can help.
- Decoupling – Breaking code into compartmentalized portions can help keep it dynamic. Code that relies too heavily on other code, like in a chain of coding processes, can have a domino effect when an issue occurs. This can create huge problems. Find ways to decouple.
* Train wrecks - chains of method calls
* Globalization - the dangers of static things
* Inheritance - why subclassing is dangerous
Symptoms of coupling
* Wacky dependencies between unrelated modules or libraries
* Simple changes to one module propagate through unrelated modules or break things elsewhere
* Developers are afraid to change code because they aren't sure what will be affected
* Meetings everyone has to attend because no one is sure who will be affected
Chp 7 – While You Were Coding
Summary
You have reached the coding phase of the project. You need to know some things that might trip you up in this portion of things.
- Listen to Your Lizard Brain – Follow your instincts. If something is nagging you with an uncomfortable feeling, more than likely it means you need to dig into something deeper. Sometimes it can be daunting to just get started. Most people become paralyzed and either just sit there or do other things rather than coding. The fix? Just start writing code. Anything, even if you know it won’t work. Just the act of beginning can have huge benefits and get you in the right mindset. Another way to kickstart your brain is to focus on some aspect of the project you are interested in and begin coding that. If the project is pre-existing, study the code already there and see why things were done the way they were and how you can add your pieces following the same or similar methodology.
- Programming by Coincidence – You can write code that appears to work but may in fact not. Don’t make assumptions. Test everything you can possibly think of as you move forward. Take nothing for granted. Program deliberately:
- Can you explain the code to a junior programmer?
- Proceed from a plan
- Document assumptions
- Refactoring – Instead of thinking about coding like constructing a building think of it like gardening. Your finished project isn’t a rigid structure but a dynamic and ever-changing food bearing plot. You need to constantly be monitoring things like weather and bugs (lol) because at any time things can change. You adjust your code, refactor, to make it adapt and keep the plants blooming. When should you refactor?
- To avoid duplication
- When requirements change or drift and your knowledge of the problem increases
- As the system is used by real people under real circumstances
- When you need more functionality from one area or another
- Stay Safe Out There – Look for ways in which your code might go wrong. Add these to your tests. Things like passing bad parameters, leading or unavailable resources etc. Thinking about these things can save you from hackers. Basic principles.
- Minimize attack surface area
- Having complex code makes things more vulnerable
- Input data can be an attack vector (make sure you clean form import values before using them)
- Make sure you authenticate services
- Keep number of authorized users to an absolute minimum. Cull unused, old or outdated users and services
- Be careful of your output. Giving too much information or leaving debugging on can help hackers get in
- Minimize attack surface area
Chp 8 – Before the Project
Summary
There are many things that can make a project unsuccessful without proper planning before getting started. What types of tools to use, full gathering of requirements, everyone on the same page etc.
- The Requirements Pit – The truth is that your users have a general idea of what they want but not a really good grasp of how to get there. They’ve seen fancy bells and whistles somewhere else and want the same thing without understanding the underlying concepts etc. You become more of a detective in this stage. You have to think on the fly of all the things they might not have so you can ask relevant questions and get their buy in. Remember requirements are a process.
- A good way to find out just what they need is to spend a day or even a week with a superuser. Shadow them and see what they do in their system and how you can improve it. Ask them questions, ask them to detail their processes and write down their answers.
- Documenting requirements is not for your end users benefit, it is for the developers. Users don’t care about these documents anyway. All they care about is the final product working and making their life easier. Remember that you can get too specific in your documentation as well. This can cause problems and waste time. Don’t omit necessary items or steps but don’t detail them to the point your document grows 1000+ pages for no reason other than to look good on your desk.
- Dreaded scope creep. All projects are in danger of this. The users realize they need something they hadn’t thought of or more likely, they want some new added functionality but want you to keep your original due dates. Keep them to the schedule and categorize their new requests into buckets. if something is a new feature that wasn’t set up at the get go, mark it as such and give them the option to either have it go in the next phase of the project, or push the original date back. Letting them know the rules ahead of time, and making them feel they have a choice, when they really don’t keeps things professional, lets you keep your promises and lets you sleep instead of coding all night.
- Solving Impossible Puzzles – Sometimes things seem too overwhelming or can’t be done. There are ways to combat these and come out successful.
- Break the problem down into components so that you can wrap your head around it better.
- Go for a walk or sleep on the problem. A lot of times your mind figures things out subconsciously while your active brain is doing other things.
- Rubber duck or talk to someone else, explaining the problem.
- Working Together – Use your team to your advantage. The sum of a small team working well together is much greater than it’s individual programers.
Chp 9 – Pragmatic Projects
- Pragmatic Teams –
- Keep your teams small. Larger teams become too uncontrollable and confusing
- Remember you don’t want any broken windows (fix things before they become bigger problems)
- Don’t be the boiled frog. Don’t get complacent thinking someone else is working on a particular thing and then realizing too late no one did it.
- Keep knowledge up to date
- Maintain old systems
- Look at what works and what doesn’t and why
- Play with new tech whenever you can
- Continue to learn and improve your skills
- Coconuts Don’t Cut It – Keep assessing to make sure you are using the right technologies and languages for the project
- Pragmatic Starter Kit – There are things every project needs.
- Version control
- Continuous testing
- Unit testing – testing unit blocks of code
- Integration testing – testing how the code works in the overall application
- Validation – validating all rules
- Performance testing – is there a possibility your code will slow or crash the system in specific instances such as high user logins? Test for these senarios
- Delight Your Users – Your users don’t care how difficult something was to build etc. All they care about is if it works the way they want. Always wow them and keep the complaining to yourself. You will gain a reputation as a great coder and project lead.
- Pride and Prejudice – Sign your work in the end. Make sure everything you work on, you are proud to put your name on.
Recent Comments