0% found this document useful (0 votes)
24 views

05 Clean Code Trang 1 45

Uploaded by

Trung Kiên
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

05 Clean Code Trang 1 45

Uploaded by

Trung Kiên
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

DESIGN PRINCIPLES AND PATTERNS

05. CLEAN CODE


Nguyen Thi Thu Trang
[email protected]
2

Content
1. Introduction Clean Code
Keep it Clean, Your Mother Doesn’t Work Here!

2. Meaningful Names
3. Clean Function/Method
4. Clean Class
5. Clean Test
3

1.1. What is Clean Code?


• Code must be easily readable
• Code must be easily understandable
• Code should be easily modified

… by anyone

Clean Code = Good Code


4

Why Clean Code?


Read code
• Programming is not what to 10%

tell the computer what to do


• Programming is what to tell to
another human what we want
the computer to do
• Unfortunately sometimes
the "other man" is ourselves
Write code
• Eventually we become authors 90%
Time programmers do at work
5

Why Clean Code? (2)


• There’s no such thing
as write-once code
• Bug Fixes
• Business Changes
• Enhancements
• New Functionality
6

What Prevents Clean Code?


• Number one reason:

“I’ll clean it up later”

• Pro Tip: “Later” never comes!


7

Going fast
”The only way to go fast, is to go well”
Robert C. Martin
• Don’t hack and skip testing just to finish at
the end of an iteration
• Write unit tests
• Fix the code
• Refactor
8

What is Bad Code (Code Smell)?


• Hard to read and understand
• Spaghetti code (things get wild within the component)
• Misleading

• Poor reusability
• It breaks when you change it
• Changes to component require inspecting/ modifying
more code

•è Low cohesion and Tight coupling


9

Review: Low Cohesion and Tight coupling


• Spaghetti code (things get wild within the
component)
• Poor reusability
• Changes to component require inspecting/
modifying more code
• Performance suffers
10

1.2. Code Smells and Refactoring


• Code smells (Bad smells):
Certain structures in the code
that suggest the possibility of
refactoring
• Refactoring means “to improve
the design and quality of
existing source code without
changing its external behavior”
Martin Fowler
• Unit tests guarantee that
refactoring preserves the behavior
Refactoring: The Typical Process
1. Save the code you start with
• Check-in or backup the current code
2. Prepare tests to assure the behavior after the
code is refactored
• Unit tests / characterization tests
3. Do refactoring one at a time
• Keep refactoring small
• Don't underestimate small changes
4. Run the tests and they should pass / else revert
5. Check-in (into the source control system)
1
1
Refactoring Tips
• Keep refactoring small
• One at a time
• Make a checklist
• Make a "later" / TODO list
• Check-in / commit frequently
• Add tests cases
• Review the results
• Pair programming
• Use tools/IDEs
• Visual Studio + add-ins / Eclipse + plugins / others 1
2
13

Java Refactorings in Eclipse


• Renaming resources
• Field, method, class, inner and anonymous class
• Moving to another package
• Class hierarchy modifications
• Make an interface/superclass from a class
• Code level mods
• Make a code segment a function
14

1.3. Main Principles for Clean Code


• Keep it simple: KISS principle
• Avoid duplication: DRY principle
• Avoid redundancy: YAGNI principle
• Boy scout rule
• Leave your code better than you found it
• Less coupling and more cohesion
• SOLID Principles (later)
• Law of Demeter
• Design Patterns (later)
15

D.R.Y Principle
• Don’t Repeat Yourself
• Applicable whenever we copy / paste a
piece of code
• Just use a method or a class
16

K.I.S.S Principle
• Keep It Simple and Stupid
• Whenever we want to implement a method to do
all things
17

Y.A.G.N.I principle
• You Ain’t Gonna Need It
• Don’t write methods which are not yet
necessary (may be you will never need
them)
• Unused classes, methods, parameters,
variables à remove them
• Somehow related with KISS
18

Law of Demeter
Karl Lieberherr i and colleagues
• Law of Demeter: An object should know as little as possible
about the internal structure of other objects with which it
interacts – a question of coupling
• Or… “only talk to your immediate friends”
• Closely related to representation exposure and
(im)mutability
• Bad example – too-tight chain of coupling between classes
general.getColonel().getMajor(m).getCaptain(cap)
.getSergeant(ser).getPrivate(name).digFoxHole();

• Better example
general.superviseFoxHole(m, cap, ser, name);
19

An object should only send messages to …


(More Demeter)

• itself (this) Guidelines: not strict rules!


But thinking about them
• its instance variables will generally help you
• its method's parameters produce better designs
• any object it creates
• any object returned by a call to one of this's methods
• any objects in a collection of the above

• notably absent: objects returned by messages sent to


other objects
20

S.O.L.I.D Principles
• SRP: The Single Responsibility Principle
• OCP: The Open Closed Principle
• LSP: The Liskov Substitution Principle
• ISP: The Interface Segregation Principle
• DIP: The Dependency Inversion Principle
21

Content
1. Introduction Clean Code
Keep it Clean, Your Mother Doesn’t Work Here!

2. Meaningful Names
3. Clean Function/Method
4. Clean Class
5. Clean Test
22

2.1. Use Intention-revealing Names


• A name of a variable, function/method, class should
reveal the intent
• Why it exists
• What it does
• How it is used

int d; // elapsed time in days

A name requires a comment è Does not reveal intent


23

Example
What is the purpose of this code?

• What kinds of things are in


theList?
• What is the significance of the zeroth
subscript of an item in theList?
• What is the significance of the value
4?
• How would we use the returned list?
24

Solution
• The simplicity of this code is not changed, but much more
meaningful

The power of choosing good names!


25

2.2. Avoid Disinformation


• Avoid false clues that obscure the meaning of
code
• For example: use accountList as variable name
but this variable is not actually a list
• Avoid giving similar names for different
variables:
• XYZControllerForEfficientHandlingOfStrings
• XYZControllerForEfficientStorageOfStrings
26

2.3. Make meaningful distinctions

What is the difference between two names: a1 and a2?


27

Avoid noise words


• 2 classes: ProductInfo & ProductData
• è Info and Data are noise words because they do not
reveal anything different
• 2 variables: zork & theZork
• How could we decide which variable should be used?

If names must be different, then they should


also mean something different!
28

2.4. Using pronounceable names

VS
29

2.5. Using searchable names


• Should give searchable names for a variable or constant
that are used in multiple places of code

Single letter and numeric constants are not easy to locate

VS
30

2.6. Class names


• Name of classes or objects should be noun or noun
phrase
• A class name should not be a VERB!
• Customer, Account, Address etc.
• Class name should also begin with a capitalized letter
31

2.7. Method names


• Methods should have verb or verb phrase names
• Accessors, mutators and predicates should be named
with prefix: get, set, is
• Should not capitalize the first letter of method name
• When constructors are overloaded, use static factory
methods with names that describe arguments
32

2.8. Add meaningful context


firstName
lastName
street
houseNumber form an address
city
state
zipcode
è They should belong to the class Address?
33

Practice: Clean code with meaningful


names
• Checking if the codebase are clean with
meaningful names
• If not, re-design and re-factor
34

Content
1. Introduction Clean Code
Keep it Clean, Your Mother Doesn’t Work Here!

2. Meaningful Names
3. Clean Function/Method
4. Clean Class
5. Clean Test
35

3.1. Do ONE Thing


• Functions should do one thing => Cohensive
They should do it well
They should do it only

• How to know what “one thing” is?


• A function is doing more than “one thing” if you
can extract another function from it with a name
that is not merely a restatement of its
implementation
• ONE Thing: ONE Level of Abstraction
36

ONE Level of Abstraction


• A function with these three steps does one,
two or three things?
• Determining whether the page is a test page
• If so, including setups and teardowns
• Rendering the page in HTML
public static String testableHtml(PageData pageData, 37
boolean includeSuiteSetup) throws Exception{
WikiPage wikiPage = pageData.getWikiPage(); //very high level
StringBuffer buffer = new StringBuffer();
if (pageData.hasAttribute("Test")){
if (includeSuiteSetup){ ... }
...
}
buffer.append(pageData.getContent());
HtmlUtil.java (v1)
if (pageData.hasAttribute("Test")){
WikiPage teardown = ...
...
buffer.append("\n"); //low level
... Multiple levels of
}
if (includeSuiteSetup) { abstraction
WikiPage suiteTeardown = ...
...
String pagePathName = PathParser.render(pagePath); //intermediate
...
}
pageData.setContent(buffer.toString());
return pageData.getHtml(); //very high level
}
38

HtmlUtil.java (v2)
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite) throws Exception{
boolean isTestPage = pageData.hasAttribute("Test"); //low
if (isTestPage){
WikiPage testPage = pageData.getWikiPage(); // high
StringBuffer newPageContent = new StringBuffer();
includeSetupPages(testPage, newPageContent, isSuite);
newPageContent.append(pageData.getContent();
includeTeardownPages(testPage, newPageContent, isSuite);
pageData.setContent(newPageContent.toString());
}
return pageData.getHtml(); Two levels of
}
abstraction
39

HtmlUtil.java (v3)
public static String renderPageWithSetupsAndTeardowns(
PageData pageData, boolean isSuite) throws Exception{
if (isTestPage(pageData))
includeSetupAndTeardownPages(pageData, isSuite);
return pageData.getHtml();
}

ONE level of abstraction


• You can’t extract another function from it
with a name that is not merely a
restatement of its implementation
Clean for Cohensive Functions/Methods
• Large repeating code fragments à extract
duplicated code in separate method
• Large methods à split them logically
• Large loop body or deep nesting à extract
method
• Method has weak cohesion à split into several
methods

4
0
41

3.2. Loosely Coupled Functions/Methods


• Avoid Flag arguments (Control coupling)
• Passing a boolean into a function is a truly terrible
practice: Function does one thing if the flag is true and
another if the flag is false
if (delPage(page) == E_OK) { 42
if (registry.deleteRef(page.name) == E_OK) {
if(configKeys.deleteKey(page.name.makeKey())
== E_OK){
logger.log("page deleted");
} else {
logger.log("configKey not deleted");
}
} else {
logger.log("deleteReference from registry failed"); }
}else {
logger.log("delete failed");
return E_ERROR;
}
try {
deletePage(page);
registry.deleteRef(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
43

3.2. (cont.)
• Extract Try/Catch Blocks
• Try/Catch mixes error processing with normal processing
Error Processing
• Extract bodies of try/catch out into separated functions

Nice Separation of functions!!!

the processes of fully deleting a page


44

3.2. (cont.)
• Prefer Exceptions to Returning Error Codes
(Control Coupling)

This method returns a special


value that indicates an error?
45

3.2. (cont.)
• Prefer Exceptions to Returning Error Codes
(Control Coupling) – Benefits:
1. No more code for checking various error codes
2. Exception classes can implement their own method,
i.e., error handling functionality
3. Error codes can’t be used in a constructor, since a
constructor must return only a new object

You might also like