Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Clean Code

No description
by

Mohammed Elrashidy

on 11 August 2016

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Clean Code

Clean Code
Agenda
Clean Code
Naming
Functions
Comments
Formatting
Objects and Data Structure
Classes
Bad Code
"It was the bad code that brought the company down"
That happens every time when company grows with bad code
The Total Cost of Owning a Mess
Bad Code and Productivity
The Grand Redesign in the Sky
- Teams inform managers that they can not continue with this code
- Management does not want to expand resources
- But Management can not deny that terrible productivity
- A new tiger team is selected
- Everyone wants to be on this green field project
- New Team build new system and also keep changes
- New system may take years
- Tigers gone and current members need to redesign this mess

Clean Code will save money, time and effort
Why We Write Bad Code??
Most managers want good code, even when they don't act like that. Defending the schedule is their job. It’s your job to defend the clean code.
Mess to make the deadline
You will not make the deadline by making the mess. Indeed, the mess will slow you down instantly, and
will force you to miss the deadline. The only way to make the deadline (the only way to go fast) is to keep the code as clean as possible at all times.
The Art of Clean Code?
- writing clean code is a lot like painting a picture
- But being able to recognize good art from bad does not mean that we know how to paint

To write Clean Code, you need the (code-sense), some of us born with it, some of us have to fight to acquire it

A programmer without “code-sense” can look at a messy module and recognize the mess but will have no idea what to do about it
Clean Code
elegent
We Are Authors
The @author field of a Javadoc tells us who we are

Bob enters the module.
He scrolls down to the function needing change.
He pauses, considering his options.
Oh, he’s scrolling up to the top of the module to
check the initialization of a variable.
Now he scrolls back down and begins to type
Ooops, he’s erasing what he typed!
He types it again.
He erases it again!
He types half of something else but then erases that!
He scrolls down to another function that calls the function
he’s changing to see how it is called.
He scrolls back up and types the same code he just erased.
He pauses.
He erases that code again!
He pops up another window and looks at a subclass.
What We Really Did?
time spent reading vs. writing is well over 10:1
You cannot write code if you cannot read the surrounding
code.

The code you are trying to write today will be hard or easy
to write depending on how hard or easy the surrounding
code is to read.

So if you want to go fast, if you want to get done quickly,
if you want your code to be easy to write,
make it easy to read.
Clean Code
Meaningful Names
Use Intention-Revealing Names
int d; // elapsed time in days
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
1. What kinds of things are in theList?
2. What is the significance of the zeroth subscript of an item in theList?
3. What is the significance of the value 4?
4. How would I use the list being returned?
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
Avoid Disinformation
Do not refer to a grouping of accounts as an accountList unless it’s actually a List
int a = l;
if ( O == l )
a = O1;
else
l = 01;
Also avoid long similar names

XYZControllerForEfficientHandlingOfStrings
XYZControllerForEfficientSteaningOfStrings
readability
effiecient
care
no duplication
simple and direct
was made for the problem
Make Meaningful Distinctions
public static void copyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i];
}
}
Info & Data
a, an, the like theZork
Variable
NameString
Customer & CustomerObject
Use Pronounceable Names
class DtaRcrd102 {
private Date genymdhms; (gen-yah-muddahims)
private Date modymdhms;
private final String pszqint = "102";
};

to

class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;;
private final String recordId = "102";
};
Use Searchable Names
for (int j=0; j<34; j++) {
s += (t[j]*4)/5;
}
int realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[j] *realDaysPerIdealDay;
int realTaskWeeks = (realdays WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
Class Names
Classes and objects should have noun or noun phrase names
like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name
of a class.
A class name should not be a verb.
Method Names
Methods should have verb or verb phrase names like postPayment, deletePage, or save.
Don’t Be Cute
For example, don’t use the name whack() to mean kill().
Don’t tell little culture-dependent jokes like eatMyShorts()
to mean abort().
Say what you mean. Mean what you say.
Pick One Word per Concept
Pick one word for one abstract concept and stick with it
Controller and a Manager and Driver in the same code base.
What is the essential difference between a DeviceManager
and a Protocol-Controller?
Why are both not controllers or both not managers?
The name leads you to expect two objects that have very
different type as well as having different classes.
Don’t Pun
Avoid using the same word for two purposes.
Using the same term for two different ideas is essentially a pun.
Function
Small
The second rule of functions is that they should be smaller than that
Frequently changed requirements
Schedule is too tight to do right things
Stupid managers and intolerant customers
NO
It is our fault, We are not professional !!
Do the right thing even Manager wants the opposite
WAIT
“If I don’t do what my manager says, I’ll be fired.”
The first rule of functions is that they should be
small.
Do One Thing
FUNCTIONS SHOULD DO ONE THING.
THEY SHOULD DO IT WELL.
THEY SHOULD DO IT ONLY.
Function RenderPageWithSetupsAndTeardowns, we check to see whether
the page is a test page and if so, we include the setups and teardowns.
In either case we render the page in HTML.
Does this Function do one thing??
Yes. Because the three called functions it does in the same level of
abstraction
So, it should not be any sections in any function
One Level of Abstraction per Function
Reading Code from Top to Bottom: The Stepdown Rule
We want every function to be followed by those at the next level of abstraction so that we can read the program, descending one level of abstraction at a time as we read down the list of functions.
It is hard, but will guarantee keeping functions short and do one thing
Switch Statements
How to make it short and do one thing?
public Money calculatePay(Employee e)
throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
What about adding new role?
What about new function like isPayday(Employee e, Date date)??
public abstract class Employee {
public abstract boolean isPayday();
public abstract Money calculatePay();
public abstract void deliverPay(Money pay);
}
public interface EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r);
}
public class EmployeeFactoryImpl implements EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) {
switch (r.type) {
case COMMISSIONED:
return new CommissionedEmployee(r) ;
case HOURLY:
return new HourlyEmployee(r);
case SALARIED:
return new SalariedEmploye(r);
}
}
}
ABSTRACT FACTORY
Use Descriptive Names
Don’t be afraid to make a name long.
A long descriptive name is better than a short enigmatic name.
A long descriptive name is better than a long descriptive comment.
Use a naming convention that allows multiple words to be easily read in the function names, and then make use of
those multiple words to give the function a name that says what it does.
Function Arguments
Ideal Number
zero (niladic).
Next comes one (monadic),
Followed closely by two (dyadic).
Three arguments (triadic) should be avoided
where possible.
More than three (polyadic) requires very special
Test every combination of arguments
Ordering Problem
Common Monadic Forms
Asking a question about that argument
boolean fileExists(“MyFile”)
operating on that argument, transforming it
into something else and returning it.
InputStream fileOpen(“MyFile”) transforms a file name String into an InputStream return value
Event (No output returns)
void passwordAttemptFailedNtimes(int attempts).
Do not use flag argument
Argument Objects / Lists
When a function seems to need more than
two or three arguments
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
String.format("%s worked %.2f hours.", name, hours);
public String format(String format, Object... args)
Verbs and Keywords
Function Should work like verbs,
example for monadic functions
write(name) or better writeField(name)
example for dyadic function
assertEquals
assertExpectedEqualsActual(expected, actual)
It will solve ordering problem
Don’t Repeat Yourself
Duplication may be the root of all evil in software. Many principles and practices have been created for the purpose of controlling or eliminating it
Command Query Separation
Functions should either do something or answer something, but not both.
Either your function should change the state of an object, or it should return some information about that object
public boolean set(String attribute, String value);
if (set("username", "unclebob"))
Very Confusing!!
Comment
“Don’t comment bad code—rewrite it.”
Comments Do Not Make Up for Bad Code
Clear and expressive code with few comments is far superior to cluttered and complex code with
lots of comments.
Rather than spend your time writing the comments that explain the mess you’ve made, spend it cleaning that mess.
Explain Yourself in Code
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG)
&& (employee.age > 65))
Or this?
if (employee.isEligibleForFullBenefits())
Good Comments
Legal Comments
// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later
Informative Comments
// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile( "\\d*:\\d*: \\d* \\w*, \\w* \\d*, \\d*");
Clarification
public void testCompareTo() throws Exception
{
WikiPagePath a = PathParser.parse("PageA");
WikiPagePath ab = PathParser.parse("PageA.PageB");
WikiPagePath b = PathParser.parse("PageB");
WikiPagePath aa = PathParser.parse("PageA.PageA");
WikiPagePath bb = PathParser.parse("PageB.PageB");
WikiPagePath ba = PathParser.parse("PageB.PageA");
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
assertTrue(a.compareTo(b) == -1); // a < b
assertTrue(aa.compareTo(ab) == -1); // aa < ab
assertTrue(ba.compareTo(bb) == -1); // ba < bb
assertTrue(b.compareTo(a) == 1); // b > a
assertTrue(ab.compareTo(aa) == 1); // ab > aa
assertTrue(bb.compareTo(ba) == 1); // bb > ba
}
Warning of Consequences
// Don't run unless you
// have some time to kill.
TODO Comments
//TODO-MdM these are not needed
// We expect this to go away when we do the checkout model
protected VersionInfo makeVersion() throws Exception
{
return null;
}
Amplification
A comment may be used to amplify the importance of
something that may otherwise seem inconsequential.
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));
Bad Comments
Redundant Comments
/**
* The lifecycle event support for this component.
*/
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
/**
* The container event listeners for this Container.
*/
protected ArrayList listeners = new ArrayList();
/**
* The Loader implementation with which this Container is
* associated.
*/
protected Loader loader = null;
Journal Comments
Sometimes people add a comment to the start of a module every time they edit it.
These comments accumulate as a kind of journal, or log, of every change that has ever been made.
I have seen some modules with dozens of pages of these run-on journal entries.
Noise Comments
/** The day of the month. */
private int dayOfMonth;
No, really !!
Use a Function or a Variable instead of comments
// does the module from the global list <mod> depend on the
// subsystem we are part of?
if (smodule.getDependSubsystems().contains
(subSysMod.getSubSystem()))

This could be rephrased without the comment as

ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))
Closing Brace Comments
while ((line = in.readLine()) != null) {
lineCount++;
charCount += line.length();
String words[] = line.split("\\W");
wordCount += words.length;
} //while
May be it is good for long function, but very bad in short functions and our functions are small
Commented-Out Code
this.bytePos = writeBytes(pngIdBytes, 0);
//hdrPos = bytePos;
writeHeader();
writeResolution();
//dataPos = bytePos;
if (writeImageData()) {
writeEnd();
}
There was a time, back in the sixties, when
commenting-out code might have been useful.
But we’ve had good source code control systems for a very long time now.
Those systems will remember the code for us. We don’t have to comment it out any more.
Just delete the code. We won’t lose it. Promise.
Formatting
First of all, let’s be clear. Code formatting is important. It is too important.
Code formatting is about communication, and
communication is the professional developer’s first order of business.
The Purpose of Formatting
Vertical Formatting
The Newspaper Metaphor
We would like a source file to be like a newspaper article. The name should be simple but explanatory.
The name, by itself, should be sufficient to tell us whether we are in the right module or not.
The topmost parts of the source file should provide the high-level concepts and algorithms.
Detail should increase as we move downward, until at the end we find the lowest level functions and details in the source file.
Vertical Openness Between Concepts
package fitnesse.wikitext.widgets;

import java.util.regex.*;

public class BoldWidget extends ParentWidget {
public static final String REGEXP = "'''.+?'''";
private static final Pattern pattern = null;

public BoldWidget(ParentWidget parent, String text) throws Exception {
super(parent);
Matcher match = pattern.matcher(text);
match.find();
addChildWidgets(match.group(1));
}

public String render() throws Exception {
StringBuffer html = new StringBuffer("<b>");
html.append(childHtml()).append("</b>");
return html.toString();
}
}
Vertical Distance
Variables should be declared as close to their usage as possible.
Instance variables, on the other hand, should be declared at the top of the class.
This should not increase the vertical distance of these variables, because in a well-designed class, they are used by many, if not all, of the methods of the class.
Dependent Functions. If one function calls another, they should be vertically close, and the caller should be above the callee,
Conceptual Affinity
Certain bits of code want to be near other bits. They have a certain conceptual affinity.
The stronger that affinity, the less vertical distance there should be between them.
public class Assert {
static public void assertTrue(String message, boolean condition) {
if (!condition)
fail(message);
}

static public void assertTrue(boolean condition) {
assertTrue(null, condition);
}
....
Horizontal Formatting
Horizontal Openness and Density
private void measureLine(String line) {
lineCount++;
int lineSize = line.length();
totalChars += lineSize;
lineWidthHistogram.addLine(lineSize, lineCount);
recordWidestLine(lineSize);
}
Horizontal Alignment
public class FitNesseExpediter
{
private Socket socket;
protected InputStream input;
private OutputStream output;
}
This kind of alignment is not useful. The alignment seems to emphasize the wrong things and leads eyes away from the true intent.
The problem will be the length of lists not the lack of alignment.
Indentation
public class FitNesseServer implements SocketServer { private FitNesseContext context; public FitNesseServer(FitNesseContext context) { this.context = context; } public void serve(Socket s) { serve(s, 10000); } public void serve(Socket s, long requestTimeout) { try { FitNesseExpediter sender = new FitNesseExpediter(s, context);
sender.setRequestParsingTimeLimit(requestTimeout); sender.start(); }
catch(Exception e) { e.printStackTrace(); } } }
public class FitNesseServer implements SocketServer {
private FitNesseContext context;
public FitNesseServer(FitNesseContext context) {
this.context = context;
}

public void serve(Socket s) {
serve(s, 10000);
}

public void serve(Socket s, long requestTimeout) {
try {
FitNesseExpediter sender = new FitNesseExpediter(s, context);
sender.setRequestParsingTimeLimit(requestTimeout);
sender.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Breaking Indentation
public class CommentWidget extends TextWidget
{
public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
public CommentWidget(ParentWidget parent, String text)
{super(parent, text);}
public String render() throws Exception {return ""; }
}
public class CommentWidget extends TextWidget {
public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
public CommentWidget(ParentWidget parent, String text) {
super(parent, text);
}
public String render() throws Exception {
return "";
}
}
Team Rules
Every programmer has his own favorite formatting rules, but if he works in a team,
then the team rules.
Objects and Data Structures
Data Abstraction
public class Point {
public double x;
public double y;
}
public interface Point {
double getX();
double getY();
void setCartesian(double x, double y);
double getR();
double getTheta();
void setPolar(double r, double theta);
}
Data/Object Anti-Symmetry
These two examples show the difference between objects and data structures.
Objects hide their data behind abstractions and expose functions that operate on that data.
Data structure expose their data and have no meaningful functions.
public class Square {
public Point topLeft;
public double side;
}

public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException
{
if (shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
}
else if (shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
}
throw new NoSuchShapeException();
}
}
public class Square implements Shape {
private Point topLeft;
private double side;
public double area() {
return side*side;
}
}

public class Rectangle implements Shape {
private Point topLeft;
private double height;
private double width;

public double area() {
return height * width;
}
}
Hard to add new data structure
Hard to add new fuctions
The Law of Demeter
The Law of Demeter says that a method (f) of a class (C) should only call the methods of these:
C
An object created by f
An object passed as an argument to f
An object held in an instance variable of C
Active Record
Active Records are special forms of DTOs.
They are data structures with public variables; but they typically
have navigational methods like save and find.
Typically these Active Records are direct translations from database tables, or other data sources.
How to add logic ??
The solution, of course, is to treat the Active Record as a data
structure and create separate objects that contain the business
rules and that hide their internal data (which are probably just
instances of the Active Record).
Classes
Class Organization
Following the standard Java convention:

Variables
public static constants
private static
private instance
Functions
public functions
private utilities used by any public function should called after it

Small
The first rule of is that they should be small.
The second rule of is that they should be smaller.
The same first and second rules of Functions
Functions design Classes
With functions we count physical lines.
With classes we count responsibilities.
The name of a class should describe its responsibilities it
The more ambiguous the class name, the more
likely it has too many responsibilities. like (Processor or Manager or Super)
We should also be able to write a brief description of
the class in about 25 words, without using the words
“if,” “and,” “or,” or “but.”
The Single Responsibility Principle
Many developers fear that a large number of small,
single-purpose classes makes it more difficult to
understand the bigger picture and navigate between
them.
Actually it is not true, it will be easy when you applied SRP, you will know directly where to go and what to change
Cohesion
Classes should have a small number of
instance variables. Each of the methods of a
class should manipulate one or more of those variables. In general the more variables a
method manipulates the more cohesive that method is to its class.
A class in which each variable is used by each method is maximally cohesive.
Thank You
Questions b2a w Ked :)
Full transcript