The path of the Clean Code Developer begins with the red level. From here, the first part of the Clean Code Developer building blocks must be incorporated into daily work and practiced again and again. The red level is designed so that every developer can start here with minimal effort. Changes to the project conditions should hardly be necessary. This means that anyone can start their journey as a Clean Code Developer "quietly".
Table of contents
Principles
Don't Repeat Yourself (DRY)
Any duplication of code or actions encourages inconsistencies and errors.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
The DRY principle is: Don't Repeat Yourself - Do not repeat yourself. It has been true since the beginning of software development - otherwise there would be no subroutines and no data normalization. Nevertheless, it is probably the most disregarded principle. Because nothing is easier than repeating code by copying and pasting. This happens all too often, especially when things need to be done quickly.
Clean code developers therefore practise observing this principle at all times. They are aware of when they are repeating code or other artifacts. They recognize repetitions that they themselves or others have created. They clean up repetitions by refactoring - if no other principles or restrictions speak against it.
Keep it simple, stupid (KISS)
If you do more than the simplest thing, you keep the customer waiting and make the solution unnecessarily complicated.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
Or to put it in Albert Einstein's words: "Everything should be made as simple as possible, but not simpler.". For the code to be changeable, it must be understandable. A simple, clear and easy-to-understand solution should therefore always be preferred. If you no longer understand your own code after a short time, alarm bells should ring. However, it is even more important that other developers can also quickly understand the code. Regular reviews and pair programming help with this. They serve to check whether the simplest solution has actually been used.
There is a temptation to strive for a complicated solution, especially when it comes to technical details. The familiar, obvious is sometimes too "boring" - and a complicated solution has already crept in. If the simple solution also works, it should be given priority. The same applies to data structures. If a IEnumerable is sufficient, no ICollection or even IList can be used.
Beware of Premature Optimization
Optimizations always cost a lot of effort. Those who exercise caution often save valuable resources for what really benefits the customer.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.
The focus is always on the comprehensibility of code. However, optimized code is often anything but readable. By reducing it to what is absolutely necessary in the shortest possible form, it may fulfill the functional and non-functional requirements of the customer - but it usually no longer reflects them in an understandable way. This is counterproductive in terms of the usually desired longevity of software. Donald Knuth wrote as early as 1974: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." (Knuth, Donald. Structured Programming with go to Statements, ACM Journal Computing Surveys, Vol 6, No. 4, Dec. 1974. p.268.)
The pathfinder rule is therefore not meant to mean that we should always strive for code optimization. Rather, it refers to the opposite: comprehensibility and changeability.
So if the clean code developer's fingers are twitching because he thinks he can still get a little bit of performance out of it through optimization, then he should at least think twice. On the one hand, this would worsen comprehensibility, but on the other hand, it is likely that such optimization is not necessary for several reasons. If the performance weakness is not just selective and a special case, the next major refactoring will probably take care of it anyway, because then it is based on a fundamental structural problem. Or the next hardware generation will iron out the performance kink. Or the customer doesn't feel bothered by it at all. In any case, the customer must have requested the optimization. No code change without the benefit expected by the customer. Because they are only willing to pay for it.
The rule of deciding against optimization when in doubt is therefore based on an even more fundamental one: YAGNI - You ain't gonna need it. In its full form, however, it is only part of the blue degree.
PS: If, despite all warnings and concerns, performance optimization is unavoidable, then it should only ever be started on the basis of a detailed analysis with a profiler. Because only those who have used a profiler to locate performance bottlenecks in a comprehensible manner can check during and after optimization whether and to what extent they have widened them.
Favour Composition over Inheritance (FCoI)
Composition promotes the loose coupling and testability of a system and is often more flexible.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
Object-oriented programming (OOP) has two very well-known candidates for the reuse of functionality: Inheritance (whitebox - reuse) and composition (blackbox - reuse). If functionality is reused by deriving it from a class, the subclass is dependent on the parent class. In many cases, this makes a system unnecessarily complex, less testable and makes it more difficult to exchange functionality at runtime. CCD has provided the Liskov Substitution Principle (LSP) for correct derivation, which must be followed.
During composition, one class uses another. If a clearly defined interface is used, this promotes decoupling. Different implementations can also be easily exchanged. So before you tackle Liskov substitution, Favour Composition over Inheritance calls for you to ask yourself whether you can give priority to composition.
„Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation". (Gang of Four 1995:19)
Integration Operation Segregation Principle (IOSP)
Deep hierarchies of functional dependencies are a clear symptom of poorly changeable code. They reduce comprehensibility and make automated tests such as refactoring more difficult.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
By mixing behavior-generating instructions (logic) in methods with calls to other methods from the same code base, it is no longer clear how the overall behavior is created; the instructions are smeared across a possibly very deep hierarchy. In addition, methods with such a mixture tend to grow indefinitely.
The IOSP counters this with a clear separation:
- Either a method only contains logic, i.e. transformations, control structures or I/O or, more generally, API calls. Then it is called Operation called.
- Or a method does not contain any logic, but only calls from other methods in the same code base. Then it becomes Integration called.
This strict differentiation leads to several positive effects:
- Methods tend to be very short. This is because more than 10, 20 or 30 lines of pure logic or exclusively method calls "don't feel good". As a mixture is not permitted, additional small methods are extracted.
- Short methods that only contain logic are easy to test because they have no dependencies.
- Short methods that only contain logic are comparatively easy to understand. The method name can really have a meaningful effect.
- Short methods that only integrate are very easy to understand and describe "at a glance" what is happening.
- The correctness of integrations can be checked very easily by visual inspection. It is only necessary to determine whether processing steps are basically arranged in the correct order. The rest is done by the compiler - or the test coverage of the operations.
- Integrations can be easily extended by "interposing" additional methods to meet new requirements. Comprehensibility is retained in the process.
The IOSP can be applied "off the cuff" by any developer of good will. Compliance with it is easy for anyone to check. Integrations and operations differ significantly in terms of form. Further details, in particular on the distinction from the Dependency Inversion Principle (DIP), can be found here, for example.
Practices
Boy Scout Rule
Every engagement with an object makes it at least a little bit better. Without any bureaucratic planning. Foundation and grassroots approach for more quality.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
The Clean Code Developer value system cannot be established all at once. It takes time. Especially since a Clean Code Developer rarely works on a greenfield site and alone, it is difficult to apply the principles to an entire code base. We therefore believe that it is important not to set goals that are too high. It is much more realistic and motivating to strive for only small progress - but continuous progress.
For us, the pathfinder rule is therefore part of the foundation of clean code development. It can also be found in Clean Code and reads: Always leave a place in a better condition than you found it.
Applied to software development, this means that clean code developers always leave code in a "better state" than they found it. After the work is done, the code is therefore more in line with the Clean Code Development value system than before.
What a Clean Code Developer has done for this depends on the situation/code - and is of course also determined by the level at which he is working. In the red level, for example, a clean code developer makes sure that code that was not yet in the version management repository is now also stored there. And they make sure that repetitions of any kind - i.e. violations of the DRY principle - are "ironed out".
Where a clean code developer identifies suboptimal features in terms of the CCD value system, he or she constantly strives to improve them. In small steps. And, of course, he tries to avoid suboptimalities from the outset. As I said: always at the stage of development.
This maxim stands at the beginning of the development of the Clean Code Developer, bearing in mind the Broken Windows Theory. According to her, the deterioration of quality in the general sense begins with little things that go unnoticed for long enough.
However, if clean code developers work according to the pathfinder rule, there are no "broken windows" in the first place - existing ones are repaired one by one. The pathfinder rule consistently closes "cracks and bumps" in the code on the basis of the CCD value system so that no further "deposits" can accumulate. It thus proactively counteracts code erosion. We consider this to be so fundamental that we have included it in the red grade.
Root Cause Analysis
Treating symptoms may bring quick relief - but in the long term it costs more effort. If you look beneath the surface of problems instead, you end up working more efficiently.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
The rule from day one as a clean code developer should be to always search intensively for the true root of the problem. Clean code developers are not satisfied with a symptom cure. Example: The sorting of data in memory is too slow. A superficial cure would now be to speed up individual instructions or instruction blocks. Perhaps the use of unsafe code would be tried, perhaps parallelization. However, a closer analysis of the problem would reveal that a suboptimal algorithm is the root of the problem. Hard-to-understand optimizations at a low level of abstraction can therefore be avoided. A better algorithm is the clean solution.
Root problem analysis is therefore a service in terms of comprehensibility and effort. Because if the root problem is known, the cleanup is usually less time-consuming than a symptom cure. When the clean code developer encounters a problem, the first thing they do is pause to give themselves a chance to look behind the symptoms.
Root Cause Analysis is also known as Five Why's. This term comes from the terminology of the Toyota Production System (TPS). The basic idea: ask "Why?" at least five times.
Version Control System
Fear of damaging a "running system" paralyzes software development. With version management, such fears are unfounded. Development can proceed quickly and boldly.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Team |
An essential requirement for every clean code developer is to place their code under the protection of a version control system. Whether this is Mercurial, Git, Subversion, VSS, TFS or Vault is irrelevant. We just think that no work on code should be carried out today without maintaining it in a version control system. The reason for this is quite simple: a version control system frees you from fear. And freedom from fear is necessary in order to boldly implement the principles and practices of the CCD value system.
A version control system takes away the fear of making something wrong and thus breaking it. If code is kept in it, any CCD can change the code at will without having to worry about destroying an existing version. Nothing is lost. The version control system is like a time machine for code.
This makes a version control system the very best basis for all learning. Because learning means making mistakes. With a version control system as a safety net, we can all afford to make mistakes. Therefore: The first prerequisite for starting clean code development is the constant use of a version control system.
Where this is not possible in the project, we see the foundation for clean code development absent. We would also not understand why the use of a version control tool should not be possible. There are no costs involved and the training required for the simplest functions is minimal. CCD does not prescribe any particular use of a version control system, only that one must be used.
See also under Tools.
Simple refactorings
Improving code is easier if you know typical improvement techniques. Their application scenarios make you aware of weak points in your own code. As recognized patterns, they strengthen the courage to apply them.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
In order to always leave code a little better than you found it, more or less major interventions are necessary. Thanks to the version control system, a clean code developer can do this without fear. But how do they make their work as easy as possible?
The key word is "refactoring". Martin Fowler has the Refactoring in his book of the same name as a fundamental technique for increasing code quality. In it, he defines a number of code change patterns to clean up "code smells", i.e. suboptimal structures or general disregard for principles.
For the red degree, this primarily involves refactoring Extract method relevant in order to comply with the DRY principle. Clean code developers use this to extract code that occurs multiple times into a method that is called at the repetition locations instead.
As a second refactoring, when working on the red degree, the Rename be used where necessary. It fits in with the pathfinder rule, as cryptic names are a frequently encountered "uncleanliness" in source code.
Refactorings can be applied manually, but there is also tool support. Modern IDEs such as Visual Studio offer some refactoring patterns, further tools are listed in our Tool list.
"Refactoring" and "clean code" are part of the Required reading of every Clean Code Developer from the red level upwards.
For further information see also refactoring-legacy-code.net.
Daily Reflection
No improvement, no progress, no learning without reflection. But reflection only takes place under the pressure of day-to-day business if it is also planned.
Changeability | |
---|---|
Correctness | |
Production efficiency | |
Continuous improvement | |
Single Developer |
Personal development is at the heart of CCD. So it's all about change: with each day, the CCD value system should manifest itself a little more in the Clean Code Developer's everyday project life. This is the Clean Code Developer's pathfinder rule applied to themselves.
However, such a path of change is not easy to follow alone. So how do you stay on course? How to measure progress?
Without wanting to establish a "control system", we believe that this involves two things:
- Small-scale planning
- Reflection after each step
Regardless of project management guidelines, clean code developers should organize their work in such a way that it consists of tasks that can be completed in one working day. This is the only way to take stock at the end of each day. We believe this is important so that work is not carried over into the evening. It has no place there; it is for relaxation.
However, such small planning steps not only make everyday working life more satisfying, because success or failure can be decided every day. The sheer possibility of making a decision in the evening Have I completed all my tasks? How did I complete my tasks? - also allows reflection on compliance with the Clean Code Developer value system.
In order to consistently develop into a clean code developer, the developer should account for whether they have considered all aspects of the value system relevant to them at each level after each working day. For the red level, this means asking questions such as: Do I really manage all code fragments in the version control system? Have I consistently applied the DRY principle? Have I generally left code in a better state than I found it?
If he is reluctant to answer one of these questions with a yes or even a no, then of course that's no bad thing. No matter how hard you try, it doesn't always work out that you can put your good intentions into practice.
Nevertheless, or precisely because of this, the following must be done:
- Either the clean code developer now makes improvements until he no longer perceives a violation of principles in relation to his daily work.
- Or he adds the recognized violations of principles to his to-do list for the next day.
The Clean Code Developer can help with reflection. Bracelet be. We are aware that wearing a colorful silicone wristband is not everyone's cup of tea. Those who have no problem with this can use the wristband as part of their personal reflection. If the Clean Code Developer cannot or does not want to clean up the violation of principles or add it to their work list, they should switch the wristband they are wearing from one arm to the other. In this way, he makes it clear that he recognizes a difference between the target of his grade and what he has achieved. This should not be misunderstood as a defeat or even as "penance". Rather, it is about haptic support for the learning process.
If a Clean Code Developer has not had to change their wristband for 21 days after completing their work, they can move on to work on the next grade. For the red level, this is the orange degree.