Lumiera
The new emerging NLE for GNU/Linux

The Clean Code Developer Initiative was initiated by Stefan Lieser and Ralph Westphal early in 2009. Largely inspired by the Book »Clean Code« — a Handbook of Agile Software Craftsmanship by Robert C. Martin, the Initiative aims at growing an attitude of professionalism amongst software developers. It is rooted in the Software Craftsmanship and Agile Movement.

Clean Code Developers take pride in what they do. They strive to write code which both clearly conveys its meaning to the reader and performs a given task with precision.

Professionalism isn’t a matter of pay-check or just booking the right education and training. It isn’t sufficient to deliver to the customer or make your boss happy. Professionalism is an attitude, it takes reflecting your results, to think about your working style, your methods, materials and tools. It’s about having an inner compass, a system of values to gauge your actions against. It’s not a fixed possession, you acquire this awareness gradually and it requires practising.

Guidelines

  • Build for Change

  • Care for Correctness

  • Work efficiently

  • Rethink your actions

The Path to Clean Code

Letting aside specific technologies or elaborated development methodologies — to guide you on your path through the software development jungle, a least common denominator of generally accepted principles and best practices is established.

As a help for understanding and practising, the Clean Code Developer Initiative grouped these into five levels or degrees (in allusion to martial arts training). We prefer here to use the term Path while still retaining the distinctive colour codes used by the original CCDI page.

Each of these paths focusses on a certain aspect of development — and does so by combining a set of well known principles and guidelines with some suitable practices. Each path builds upon the preceding path, but you can take on only one path a time.

And you really need to take on such a path personally — try to understand the principles actively, keep them up in your everyday work and try to adhere to the practices. It is recommended to stay on a single path for an extended period of time (at least 3 weeks) No path is inherently “better” than the preceding path — usually, when finished with blue, you start again with red.

Red Path — understanding

Principles
DRY — Don’t Repeat Yourself

don’t bore your readers by stating the same again and again — build viable abstractions instead. Avoid duplicated functionality, remove unnecessary data redundancy, automate repetitive tasks.

KISS — Keep it simple, stupid

“Everything should be made as simple as possible, but not simpler” (Einstein). Write code foremost to be understandable. Resist using an interesting solution, when there also is a straight forward (albeit boring) standard solution.

Avoid Preliminary Optimisation

distrust your own cleverness. “More computing sins are committed in the name of efficiency than for any other single reason – including blind stupidity” (W.A.Wulf). Defer improvements “for later”. Require an objective proof for performance problems, based on real-world data.

FCoI — Favour Composition over Inheritance

build up functionality from self-contained abstractions, instead of cleverly extending, bending or specialising. Avoid proliferation of special cases.

Practices
Boy Scout Rule

whenever you enter some area, leave it in somewhat better shape than you found it

Root Cause Analysis

never do “programming by coincidence”. Try to understand why something works or breaks. Never act based on assumptions. Don’t treat symptoms. Better don’t act unless you understand.

Use Version Management

use a revision control system. Create thematically consistent change sets, write clear commit messages, learn to handle branching and merging.

Simple Refactorings

apply the fundamental refactorings “_extract method_” and “_rename_” liberally.

Reflection

review your own achievements based on the principles (especially but not limited to those you’re focussing on currently). Partition your work into tasks which can be finished on one day. Take the time to reflect.

Orange Path — sharpening

Principles
SLA — Single Level of Abstraction

each piece of code should talk on a distinctive level of granularity. Don’t mix implementation details with invocation of high-level abstractions. Refactor code to balance the level of abstraction.

SRP — Single Responsibility Principle

every class or entity should deal with one topic solely, and do that well. What needs to be said for a given concern, should be found at a single location.

SoC — Separation of Concerns

decompose functionality into orthogonal concerns. Increase focussing and cohesion within a single concern, and decrease coupling amongst separate concerns.

Source Code Conventions

establish writing conventions based on readability. Code is more often read than written. Reason about the purpose of conventions, then stick to them. Especially focus on naming conventions and correct source code comments. Comments should not detail what you do, but the purpose why you do it.

Practices
Issue Tracking

capture problems and work items as well delineated issues. Track them in a structured way, establish ubiquitous procedures for assigning and resolving issues.

Automate Tests

verify correct integration of the parts by running tests automatically. Build a safety net allowing to perform refactorings while retaining correct operation.

Eager Reading

acquire an attitude of concern for the ongoing evolution of the coding craft. Read books, journals and blogs. Learn a new programming language every year.

Code Reviews

four eyes are better then two. Present and explain your code to other programmers. Establish practices like code reviews and pair programming.

Yellow Path — segregating

Principles
ISP — Interface Segregation Principle

keep interfaces focussed and confined to a set of operations likely to be used in conjunction. Avoid to tie clients to the details of a service implementation

Dependency Inversion

revert dependencies with respect to the naive logical meaning. Instead of implementing high-level functions through low-level functions, turn the latter into services and thus make both depend on interfaces.

Liskov Substitution Principle

the special case must be able to stand-in for the general concept in all respects. A subclass instance is required to take on all responsibilities outlined by the Interface. The special case must not extend and bend the meaning beyond what was outlined in the abstraction. An ellipse can’t be kind-of a circle.

Rule of Least Surprise

every piece of code should behave exactly in the way obvious from the names, the concepts and the general context. The reader should be able to get the essence of what’s going on already from the first coarse-grained view.

Information Hiding

every part — be it function, object, interface or subsystem — should expose only the bare minimum required to use it effectively.

Practices
Automated Unit Tests

cover individual components with tests in isolation. Break the reasoning in terms of contracts down to the implementation level

Mockups

build mock-ups, dummies, stubs and fakes to create a controlled environment for reasoning and test.

Code Coverage

base your reasoning and testing on coverage analysis (instructions, branches, decisions).

Advanced Refactorings

apply the more advanced types of refactoring techniques to rearrange and restructure code fluently. Ensure correctness through your stock of unit tests.

Community Participation

participate actively, beyond the local team. Report bugs, provide testcases, work with library developers, visit local user groups, participate in conferences.

Green Path — decoupling

Principles
OCP — Open Closed Principle

any class or functional unit should be open towards extensions, but closed against modifications. Extending it should not require changing the internals, nor tie the extension to these internals. Increase cohesion, decrease coupling.

Tell, don’t ask

invoke services instead of doing things yourselves. Don’t inspect state and operate from the outside. Respect Subsidiarity.

Law of Demeter

don’t write “train wreck code”. Talk to direct collaborators only. Within each scope, confine yourself to using the parameters, local methods, locally created objects, associated partners and global services.

Practices
Continuous Integration

integrate changes timely and frequently. Perform this integration process automatically, in a controlled and reproducible environment, perform the unit and integration test suites as part of this process.

Inversion of Control Container

use Dependency Injection to implement IoC. Use service locators, employ the DI patterns or use an existing DI container implementation or framework.

Code Metrices

use static analysis and similar quantitative measurements to monitor various aspects of a source base

Quality Measurments

observe instead of assuming. Monitor the code quality, measure performance, observe defect rates. Estimate efforts and verify your guesses after the fact. Identify impediments.

Learn by Teaching

share your experience and knowledge. Explaining something is the best way to understand it yourself.

Blue Path — balancing

Principles
Segregate Design and Implementation

clearly delineate planning and doing. Design must not duplicate implementation work, and implementation concerns must not interfere with architectural considerations. Otherwise implementation will supersede the design and the real system will end in chaos.

Implementation reflects Design

code in accordance with design. Traces of architecture should be visible down into individual implementation structures, names, organisation of the code base and the runtime structure. Never play tricks to undermine and thwart the design and create a second reality.

YAGNI — You Ain’t Gonna Need It

decide later and don’t do it, if in doubt. Question your own brilliant ideas — write them down, but defer implementation for later, because, well, you ain’t gonna need that crap. Don’t say “I can do that on a single afternoon” — be prudent: doing it seriously will be a major undertaking. Refrain from spending effort without a reason.

Practices
Continuous Delivery

extend the automated continuous integration into deployment and setup. Plan and test the steps towards an release, and finally automate them. Create a platform to roll out development snapshots, integration builds, release candidates and service updates.

Iterative Development

development is a learning process. Instead of achieving perfection through a single big bang, proceed in incremental steps and include feedback from the user or customer. Use each iteration for a retrospective and adjust your procedures.

Components and Contracts

employ the thinking in terms of components and contracts from the largest to the smallest. Each component establishes some kind of isolation, which helps to cut down complexity.

Test first

start from the usage situation. Each unit, class, component or subsystem has clients. Instead of detached planning, or worse, guessing what might be cool, work out the requirements and contract from an exemplary use in code. Transform this into a test before you even think about how to make it work.


References

Unfortunately, the original Clean Code Developer page with extensive explanations is written entirely in German. There was immediately much reception amongst the German speaking .NET and Java developers and others — yet it still seems to be not so well recognized in other countries.

The CodeScouts have prepared a full english translation of the Principles and Practices described on the original page. The translation is a bit crude at places — they used google translation as a starting point.

Robert C. Martin's Book »Clean Code« was the initial inspiration. Indeed, the whole initiative started out of excitement, controversies and discussions ignited by reading this book together.

Last but not least, many of the guidelines, rules, principles and practices can already be found in »The Pragmatic Programmer«, essential read anyway.