What is software craftsmanship?
In a previous blog post I attempted to define some of the fundamental concepts of what it is that I do on a daily basis. In the process of defining said foundations, I stumbled and stubbed my toe on another concept. Hidden inside the other, not unlike the layers of a matryoshka doll. The concept of software craftsmanship.
Software craftsmanship is a bottom up approach to software development by emphasizing the coding skills of the developers themselves. Traditionally software engineering practictioners were encouraged to see themselves as part of a well defined statistical analysis and mathematical rigor of an engineer with the benefits of introducing professionalism, predictability, precision, and mitigated risk.
The reason that this approach is fundamentally flawed is unquestionable. Software engineering as a field of study is far too immature and is constantly in a state of flux.
For civil engineering there exists well defined and well understood ways for constructing bridges and buildings that is safe for people to use and inhabit. A person who designs a bridge can be certain that the people constructing that bridge know how to read the blueprint, and what all the symbols and formulae mean.
No such generally accepted blueprints exist for software engineering. Everything can be done in a multitude of ways with different methods and ideology at its core.
Not unlike the guild traditions of medieval europe software development is a craft that has developed a body of wisdom, most of which isn’t taught at universities nor in certification classes. Most developers arrive at these tricks of the trade by independent experimentation, or more recently from learning from their peers and mentors.
Tools of the Software Craftsman
Learning how to use the tools of the trade is a core concept for producing quality code. Here is a list of some of the tools used to increase the quality, extendability, reliability of code.
- Use a version control system, like subversion, mercurial or git
Source control is like a time machine for your code, you can always go back in time.
- Use a continuous integration tool like cruise control
Continuous integration implements a continuous process of applying quality control to daily or nightly builds.
- Have a centralized bug tracking system like RT or BugTrac
This is essential to maintaining software.
- For web development, use an automated build and deploy script
If you don’t have an automated build and deploy script you may have problems
- Design software to be easily tested (Test Driven Development)
Loose coupling promotes software that is more modular, and is easier to extend and maintain.
- Refactor early, refactor often
Just as you would maintain a 747, fix the root of the problem when it needs it.
- Be pragmatic with project management
Good, fast, cheap, pick TWO.
- Be aware of technical debt
Technical debt is a balancing act, be sure to pay off your debts before they crush you.
- DRY – Dont repeat yourself
Knowledge must have a single, unambiguous, authoritative representation within a system.
- YAGNI – You Aint Gonna Need It
Implement features when you actually need them, not when you forsee you need them.
- Fix broken windows
Fix broken design and poor code whenever you see them.
- Reduce cyclomatic complexity
Reducing nested brackets will reduce cyclomatic complexity and increase readability and maintainability.
- Estimate before you start
This will help you to spot potential problems up front
- Iterate your project schedule with code
Use experience gained with the project to redefine the project time scales.
- Use an ubiquitous language
Design and code in a common language that your users understand.
- Use exceptions for exceptional circumstances
Handle anticipated problems in code. Reserve exceptions for exceptional things.
- Refactor to patterns
See Gang of Four Design Patterns at the bottom of this essay.
- Design independent, well-defined components.
- Keep your code decoupled.
- Avoid global state or global data.
- Refactor similar functions.
Law of Demeter for Functions
An object’s method should call only methods belonging to:
- Any parameters passed in
- Objects it creates
- Component objects
Uncle Bobs S.O.L.I.D. principles of Object Oriented Design
Gang of Four Design Patterns for Object Oriented Design (OOD).
- Abstract Factory – groups object factories that have a common theme
- Builder – constructs complex objects by separating construction and representation
- Factory Method – creates objects without specifying the exact class to create
- Prototype – creates objects by cloning an existing object
- Singleton – restricts object creation for a class to only one instance
- Adapter – allows classes with incompatible interfaces to work together by wrapping its own interface around that of an existing class
- Bridge – decouples an abstraction from its implementation so that the two can vary indepenently
- Composite – composes zero-or-more similar objects so that they can be manipulated as one object
- Decorator – dynamically overrides/adds behavior in an existing method of an object
- Facade – provides a simplified interface to a large body of code
- Flyweight – reduces the cost of creatingand manipulating a large numer of similiar objects
- Proxy – provides a placeholder for another object to control access, reduce cost, and reduce complexity
- Chain of responsibility – delegates commands to a chain of processing objects
- Command – creates objects which encapsulate actions and parameters
- Interpreter – implements a specialized language
- Iterator – accesses the elements of an object sequentially without exposing its underlying representation.
- Mediator – allows loose coupling between classes by being the only class that has detailed knowledge of their methods
- Memento – provies the ability to restore an object to its previous state (undo)
- Observer – is a publish/subscribe pattern which allows a number of observer objects to see an event
- State – allows an object to alter its behavior when its internal state changes
- Strategy – allows one of a family of algorithms to be selected on the fly at runtime
- Template method – defines the skeleton of an algorithm as an abstract base class, allowing its subclasses to provide concrete behavior
- Visitor – separates an algorithm from an object structure by moving the hierarchy of methods into one object
Hunt, Thomas (1999). The Pragmatic Programmer: From Journeyman to Master. Addison-Wesley Professional. ISBN 9780201616224.
McBreen (1991). Software Craftsmanship: The new imperative. Addison-Wesley Professional. ISBN 9780201733860
Wampler, Martin (2008). Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall. ISBN 9780132350884
McConnel (2004). Code Complete: A Practical Handbook of Software Construction. Microsoft Press. ISBN 9780735619678
Gang of Four (GOF). Gamma, Helm, Johnson, Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional. ISBN 9780201633610