Clean code Bites
Applying clean code
Roy Nitert
28-3-2012
© Sioux 2012 | Confidential | 2
Agenda
Why clean code What is clean code Examples:o SRPo Small methodso Descriptive nameso Parameterso DRY
© Sioux 2012 | Confidential | 3
Why clean code ?
So it is easier to understand (readability) and cheaper to modify (maintainability) software
The code you write will be read more times than it was written and by more people.
Focus on the small things that make us better programmers.
© Sioux 2012 | Confidential | 4
What is clean code ?
© Sioux 2012 | Confidential | 5
What is clean code ?
http://en.wiktionary.org/wiki/clean_code
Noun
clean code (plural clean codes)
(idiomatic) software code that is formatted correctly and in an organized manner so that another coder can easily read or modify it.
© Sioux 2012 | Confidential | 6
What is clean code ?
Characteristics of clean code: Small methods and classes Descriptive names Not too many parameters in methods (and no flags) No obvious or irrelevant comments (code must be
self describing) No redundancy (DRY: don’t repeat yourself) No magic numbers Single responsibility principle (SRP) Uniform coding style
© Sioux 2012 | Confidential | 7
SRP: Single Responsibility Principle
every object should have a single responsibility, and that responsibility should be entirelyencapsulated by the class.
a class or module should haveone, and only one, reason to change
If class names have ‘manager’ or ‘processor’ in them, they probably have multiple responsibilities
the "S" in "SOLID" stands for the single responsibility principle (“Principles Of OOD”, Robert C. Martin)
© Sioux 2012 | Confidential | 8
SRP example
Public class DashboardManager {
public Component getLastFocusedComponent();
public void setLastFocused(Component lastFocused);
public int getMajorVersionNumber();
public int getMinorVersionNumber();
public int getBuildNumber();
}
© Sioux 2012 | Confidential | 9
SRP example
Public class FocusedComponent {
public Component getLastFocusedComponent();
public void setLastFocused(Component lastFocused);
Public class Version {
public int getMajorVersionNumber();
public int getMinorVersionNumber();
public int getBuildNumber();
}
© Sioux 2012 | Confidential | 10
Small methods
They should be very very small Should do one thing, do it well, do it only One level of abstraction Should read like a narrative Should not have sections Blocks within if, else and while
statements should be one line long
© Sioux 2012 | Confidential | 11
Small methods example
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite
) throws Exception {
boolean isTestPage = pageData.hasAttribute(“Test”);
if (isTestPage) {
WikiPage testPage = pageData.getWikiPage();
StringBuffer newPageContent = new StringBuffer();
includeSetupPages(testPage, newPageContent, isSuite);
newPageContent.append(pageData.getContent());
includeTeardownPages(testPage, newPageContent, isSuite);
pageData.setContent(newPageContent.toString());
}
return pageData.getHTML();
}
© Sioux 2012 | Confidential | 12
Small methods example
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite
) throws Exception {
if (isTestPage(pageData))
includeSetupAndTeardownPages(pageData, isSuite);
return pageData.getHTML();
}
© Sioux 2012 | Confidential | 13
Descriptive names
Names make software readable Helps clarify the design in your mind Use long names for long scopes Avoid encodings
© Sioux 2012 | Confidential | 14
Descriptive names example
Public int x() {
int q = 0;
int z = 0;
for (int kk = 0; kk < 10; kk++) {
if (l[z] == 10) {
q += 10 + (l[z + 1] + l[z + 2]);
z += 1;
} else if (l[z] + l[z + 1] == 10) {
q += 10 + l[z + 2];
z += 2;
} else {
q += l[z] + l[z + 1];
z += 2;
}
}
return q;
}
© Sioux 2012 | Confidential | 15
Descriptive names example
Public int score() {
int score = 0;
int frame = 0;
for (int frameNumber = 0; frameNumber < 10; frameNumber++) {
if (isStrike(frame)) {
score += 10 + nextTwoBallsForStrike(frame);
frame += 1;
} else if (isSpare(frame)) {
score += 10 + nextBallForSpare(frame);
frame += 2;
} else {
score += TwoBallsInFrame(frame);
frame += 2;
}
}
return score;
}
© Sioux 2012 | Confidential | 16
Parameters / arguments
Small number: Zero is best, followed by one, two or three
More than three is questionable Output arguments are counterintuitive Boolean arguments (flags) loudly declare than
the function does more than one thing Simpler is easy to understand and easy to test Reduce number of arguments by creating
objects out of them
© Sioux 2012 | Confidential | 17
Parameters example
Circle makeCircle(double x, double y, double radius);
public void AlignTaskCanBeStopped(bool useRealXps);
AlignTaskCanBeStopped(true);
© Sioux 2012 | Confidential | 18
Parameters example
Circle makeCircle(Point center, double radius);
public void AlignTaskCanBeStoppedWith RealXps();
public void AlignTaskCanBeStoppedWith SimulatedXps();
© Sioux 2012 | Confidential | 19
Don’t repeat yourself
Duplication DRY principle (Dave Thomas) Once, and only once (Kent Beck) Duplication is a missed opportunity for abstraction Examples:o Identical code (copy/paste)o Switch/case (or if/else) chainso Similar algorithms
Design patterns and OO itself are strategies for eliminating duplication
© Sioux 2012 | Confidential | 20
DRY example
public void scaleToOneDimension( float desiredDimension, float imageDimension) {
if (Math.abs(desiredDimension – imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);
RenderOp newImage = ImageUtilities.getScaledImage( image, scalingFactor, scalingFactor);
image.dispose();
System.gc();
image = newImage;
}
public synchronized void rotate(int degrees) {
RenderOp newImage = ImageUtilities.getRotatedImage( image, degrees);
image.dispose();
System.gc();
image = newImage;
}
© Sioux 2012 | Confidential | 21
DRY example
public void scaleToOneDimension( float desiredDimension, float imageDimension) {
if (Math.abs(desiredDimension – imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);
replaceImage(ImageUtilities.getScaledImage( image, scalingFactor, scalingFactor));
}
public synchronized void rotate(int degrees) {
replaceImage(ImageUtilities.getRotatedImage( image, degrees));
}
private void replaceImage(RenderedOp newImage) {
image.dispose();
System.gc();
image = newImage;
}
© Sioux 2012 | Confidential | 22
Applying clean code
Know how to write clean code Think about these small improvements
during:o New developmento Code reviewso Changing codeo Fixing bugs
So code will be easier to understand and cheaper to modify
© Sioux 2012 | Confidential | 23
Conclusion
Write code as if the person who is going to maintain it, is a psychopath who knows
where you live.
© Sioux 2012 | Confidential | 24
Questions?