This appendix contains a summary of all the principles and practices outlined in this book. The main purpose of this appendix is to help understand how critical each of the practices described in this book is to overall success and to help get started on a new project. In particular, I would like to highlight the keystone practices, which are the practices that make the largest contribution toward achieving the overall principles or mindset for sustainable development.
Keystone Species in a Natural Ecosystem
One of my favorite books in the area of natural biology is called Krakatau: The Destruction and Reassembly of an Island Ecosystem [Thornton 1996]. On August 27, 1883, the island of Krakatau was virtually obliterated by a volcanic explosion. The island was literally reduced to a lifeless rock. This book is about Dr. Ian Thornton's visits over many years to the island and his observations as the island slowly and gradually came back to life from virtually nothing to a thriving and complete ecosystem.
One aspect of his analysis that I find fascinating is his identification of keystone species. These are the species of plants and animals that, if they disappeared, would cause the entire ecosystem to apart, or, if they were absent, then the ecosystem would not develop as it should. In the case of Krakatau, one of these species was the fig tree. It is fascinating to read how, once the fig tree became established on the island, the pace of change on the island accelerated.
I think the notion of a keystone species in an ecosystem carries over to the idea of keystone practices for sustainable software development. As I've outlined throughout this book, the complexity of the ecosystem that software inhabits dictates a mindset or principles that lead to success in both the short and long term. And critical to the desired mindset are a set of practices that act as keystones for the approach to software development. Hence, while it is inevitable that practices change over time and that the exact set of practices employed is going to depend on the team and the circumstances of its project, certain practices are going to change more than others, while others form the foundation that all the other practices are built around. If it were possible to start from a clean slate (like Krakatau), then given the mindset required for sustainability as a starting condition, some practices are going to be obvious starting points.
Keystone practices are identified with the icon:
1. No "Broken Windows"
Bad code should never be tolerated because one mess leads to another, and another, and another, . . .
2. Be Uncompromising about Defects
For sustainability, defect backlogs must be avoided at all costs, starting from the early days of a project.
3. "Barely Sufficient" Documentation
Although this practice is important, I've worked on teams that produced lots of documentation and still got a good product to market. As long as the focus is on producing a working product and not the documents, and as long as the majority of effort goes into the product and not the documents, then sustainability can still result.
4. Continuous Integration
Teams that delay integration are simply delaying the time when they will have to deal with the inevitable problems. The more often integration occurs, the faster problems are uncovered.
5. Nightly Builds
Having a nightly build that works is the first level of reassurance that the product is working.
Prototyping is a simple and effective way to reduce risk and better understand a problem before having to solve it live.
7. Don't Neglect Performance
Performance is one of those aspects of a product that can't be neglected for long. You can probably get by without paying attention to performance for a while but at some point you're going to have to invest in it.
8. Zero Tolerance for Memory and Resource Leaks
This is a keystone practice only if you are using a programming language where programmers are responsible for memory and resource management.
9. Coding Standards and Guidelines
How badly you need standards and guidelines is going to depend on the experience level of the team and the degree of similarity in the working habits of team members. Coding standards and guidelines can help many teams have useful discussions about good and bad code.
10. Adopt Standards (Concentrate on Your Value-Add)
You can reinvent the wheel and still complete a project, but you're still wasting effort. This is one of those mindsets that becomes more important with experience, as you learn to use what is available to you as long as it is good enough and stifle the temptation to build it yourself.
11. Internationalize From Day One
Many projects don't care about supporting multiple languages. However, for those projects that do, there are simple things you can do in the early days of the project that will save wasted effort later.
12. Isolate Platform Dependencies
If portability between platforms is a concern for your project, make sure you isolate the dependencies, preferably through platform-independent abstractions so that platform issues are not exposed to the majority of the code. If platform-specific code is strewn everywhere, then the code is harder to maintain and more error-prone, and this makes it hard to keep the product in a working state.
1. Ruthless Testing
Most projects rely too much on manual testing and having people perform repetitive tasks that should be automated and performed on a regular basis by computers.
2. Use Available Tools
There are tools available that, if used wisely, can boost productivity. Teams should use the tools that are available to them to help prevent problems while constantly being on the lookout for new tools.
3. Pair Programming and Code Reviews
This practice helps catch defects while increasing the understanding of team members in the code they are collectively working on. However, the danger is that these not get out of control, which happens if pair programming is mandated or code reviews are distributed too widely.
4. Lightweight Root-Cause Analysis
This can be an extremely valuable practice, although it can also get out of control. The team needs to carefully use this one.
1. Design Vision
Having a simple and easily understood design vision helps the team make daily design decisions that fit within the long-term goals of the project. Sustainability can be compromised if the team does not consider the mid to long term in their daily decisions.
2. Guiding Principles
Guiding principles reinforce the design vision and help the team keep principles that are important to sustainability in mind.
3. Simple Design
Simplicity is vital for sustainable development because simplicity tends to make software easier to modify and less brittle over time.
Continual disciplined refactoring, with an eye toward cleaning up code while maintaining the desired behavior, is important for sustainability because it allows the team to evolve its software with confidence.
5. Design Patterns
Design patterns are a tool that every developer should be aware of and understand when to use them and how to use them properly. At their best, they can save a great deal of effort. At their worst, they can contribute to making software overly complex and brittle.
6. Frequent Rapid Design Meetings
Collaboration about design, as frequently as possible, is where design starts. Having a forum to talk about good design and good code and not just problems helps everyone on the team.
7. Commitment to Re-Architecture
(Especially for large development efforts) A commitment to re-architecture is a keystone practice on projects that involve large teams and large amounts of code that must change over a number of years. On these larger projects, being willing to make difficult decisions to re-architect portions of the system can make the difference between sustainability and unsustainability.
8. Design for Reuse
(Especially for large development efforts) Designing for reuse is a keystone practice on projects that involve large teams and large amounts of code that change over a number of years. This is because the costs of duplicated effort are magnified the greater the effort, not only in initial design and development time but also in ongoing maintenance as changes are made that must be carefully made in multiple places.
1. Iterative Development
Iterative development is a key underpinning of sustainable development. By breaking the project down into small manageable chunks of time, the team is able to reduce risk, continually monitor its progress, and make course corrections as requiredeven if no changes are ever made to the scheduled features.
2. Release Planning
(For most projects) Release planning is an important aspect of projects that are going to take more than some number of months or are released to customers on a regular basis. For these projects, having a clear idea of what is going to be in a release contributes to sustainability because it helps teams plan architectural changes that support the release and that make future change easier.
3. Daily Standup Meetings
(Especially for small teams) Some form of daily collaboration is important for people to work effectively together. And having a team that works well together is important for sustainability.
Daily standup meetings work best in small teams where team members are all in the same location and meet face-to-face every day.
In large teams, daily collaboration is still required, but it is difficult to achieve. This is where team members should consider experimenting with every means at their disposal to find something that will work for them.
Frequent lightweight retrospectives are crucial to help teams learn and continually improve what they are doing and how they are working. Sustainability is virtually impossible without this continual learning and improvement.
5. Coaching and Team Development
Coaching is finding ways to bring out the best in people and getting them to work together without telling them what to do and how to do it. Both coaching and team development (through professional development and having some understanding of the business) are vital for sustainable development, because people need to perform at their best.
6. Make Key Metrics Visible
Measuring the key metrics for a project and making them visible gives teams a simple and visual means of understanding how they are doing. The dangers of metrics are that they become the focal point of efforts to the exclusion of all else and also that there are too many metrics to be useful.