The Path to Craftsmanship:
Principles, Patterns, and Practices
By Robert C. Martin
The last several decades have seen a remarkable growth in our knowledge of software craftsmanship. During the '60s and '70s software was a kind of black art. We had successes and failures but had very little idea of what made a project fail or succeed. Repeatability was hard to come by.
During the 60's and 70s we learned the principles of modular programming and structured programming. We learned that goto might not be such a good idea, and that large software systems could be functionally decomposed through the agency of structured analysis.
During the '80s and '90s we learned the principles of objects, which gave us another suite of tools for hiding information and managing dependences. We learned the importance of decoupling and componentization, and the principles that govern them.
During the late '90s we also learned that there were repeatable patterns of good design, and we began the effort of cataloging and publishing them. These patterns spanned a huge gap, ranging from solutions at the code level to solutions at the architecture level.
As the millennium turned there was a revolution of practices. It began with Extreme Programming and grew into the Agile movement. The practices that have come out of this movement have changed the way software projects are planned, estimated, managed, and executed. They have affected the hour by hour behavior of programmers, testers, and managers.
The upshot of this progression of principles, patterns, and practices is that we can now define the craft of software development. We now know what it take to repeatably succeed at software development. We have the principles that govern the structure of our software, the patterns of design and architecture that have been shown to work in previous systems, and the practices that govern the behaviors of teams to get projects done.
The problem now is to spread this knowledge of principles, patterns, and practices, the definition of our craft, to software developers in general. We want the craft to permeate the industry. A reasonable curriculum to achieve this goal is:
- A language course such as Java, C++, or C#
These courses have a two-fold purpose. Firstly they teach the details of a programming language. More importantly, however, they introduce some of the important practices and principles of our craft. They provide an introduction to one of the most crucial of all the practices in our craft: Test Driven Development. They also inculcate the principles of decoupling and dependency management from the very beginning. These courses do not go into depth on these issues. Rather they teach the language syntax and semantics in the environment of the craft. The practices and principles are simply part of the instructional background to be absorbed by the students as they learn the language. These courses are not necessarily for people who don't know the language already. Students who already know the language being taught will learn a great deal from these courses in terms of details, and in terms of the principles and practices of the craft.
- Advanced Object Oriented Design (AOOD)
This course takes the logical next step in the direction of principles and patterns. It strongly focusses on the principles of object oriented design, dependency management, and componentization. It teaches principles of OOD such as The Open Closed Principle (OCP), The Liskov Subtitution Principle (LSP), The Dependency Inversion Principle (DIP). It also teaches component partitioning principles such as The Acyclic Dependencies Principle (ADP), the Stable Dependencies Principle (SDP), and the Stable Abstractions principle. The course goes on to teach the most useful of the last decade's worth of design patterns at every level, from low level design to architecture. These include patterns such as Visitor, Decorator, Template Method, Abstract Factory, Table Data Gateway, Model View Controller, Model View Presenter, Front Controller, Page Controller, and many others. The end result of this course is a deep grounding in the important principles and patterns of our craft, initial experience in applying these principles and patterns in exercises, and connection to the portals, books, and blogs where these ideas are currently being developed and extended. Of course all of this is taught with the context of practices being reinforced in the background.
- Agile/XP Immersion
This course brings together programmers, testers, project managers, QA, and business analysts to learn the practices of our craft. The practices are taught in lecture format, and then practiced by an extended and grueling mock project. Programmers and non programmers are taught though a mixture of lectures and exercises. Some lectures are combined, and some separate the business and technical people. Topics include planning, estimating, managing, course correction, prioritizing, unit testing, acceptance testing, refactoring. Of course the principles and patterns are reinforced throughout. This course is team based. This means that whole teams participate. The course gives the team a place to adopt and refine their practices, and to start to gel. The mock project produces real code, real tests, and is driven by real schedules. In the end, they will deliver something that executes. This course is a breadth first exploration of all the practices of our craft; but does not go into great depth.
This course goes deep into the technical practices of our craft, while keeing the principles and patterns in close context. The practices of Test Driven Development and Refactoring are explored through lecture and exercise in very deep detail. The specific design pattern that pertain to TDD, and the principles that drive refactoring are stressed. Unit testing and acceptance testing are covered, along with the motivation and guidance of continuous integration.
- Agile Planning/Estimating/Management
This course goes deep into the non-technical practices of our craft. Students include programmers, managers, business analysts, technical leads, QA/Testers, etc. Students are taught the strategies and techniques of planning, estimating, and prioritizing software development practices. Much attention is paid to continuous planning and course correction, reporting, and driving a project to the best possible outcome.
These courses round out the circle of principles, patterns, and practices that define the craft of software development.