29
Clean Code Chapter 3. Author: Felix Chen

Clean Code�Chapter 3. (1)

Embed Size (px)

Citation preview

Page 1: Clean Code�Chapter 3. (1)

Clean CodeChapter 3.Author: Felix Chen

Page 2: Clean Code�Chapter 3. (1)

Categories1. Small!2. Block And Indenting

Page 3: Clean Code�Chapter 3. (1)
Page 4: Clean Code�Chapter 3. (1)
Page 5: Clean Code�Chapter 3. (1)

Small!1. the first rule should be small2. the second rule should be that they should be smaller than that.

Page 6: Clean Code�Chapter 3. (1)

Block And Indenting1. This implies that the blocks within if statements, else statements, while

statements, and so on should be one line long. Probably that line should be a function call. If you do so, you can obtain two benefits: a. Enclosing function smallb. Add documentary valuesc. Block can have a nicely descriptive name

Page 7: Clean Code�Chapter 3. (1)

1. Functions should do one thing, They should do it well. They should do it only.a. One level of abstraction per functionb. Tell whether a particular expression is an essential concept

2. One level of abstraction per function:a. Higher: getHtml();b. Middle: String pagePathName = PathParser.render(pagePath) c. Lower: .append(“\n”)

3. The Stepdown Rule: includeSetupsAndTeardownsIfTestPage()a. To include the setups and teardowns, we include setups, then we include the test page

content, and then we include

i. To include the setups, we search the suite setup if this is a suite, then we include the regular setup1. To include the suite setup, we search the parent hierarchy for the SuiteSetUp ...

a. To search the parent

Do One Thing

Page 8: Clean Code�Chapter 3. (1)

SOLID1. Single Responsibility Principle, SRP2. Open/Closed Principle, OCP3. Liskov Substitution Principle, LSP4. Interface Segregation Principle, ISP5. Dependency Inversion Principle, DIP

Page 9: Clean Code�Chapter 3. (1)

Single Responsibility Protocol, SRP1. Each responsibility is an axis of change. That change will be manifest through a change in responsibility amongst the

classes.2. More than one responsibility, then there will be more than one reason for it to change.3. Rectangle has two methods, 1) Draws the rectangle, 2) Computes the area of the rectangle.4. GeometricRectangle and ComputationalGeometryApplication classes are rendered cannot affect the

ComputationalGeometryApplication.

Page 10: Clean Code�Chapter 3. (1)

Open/Closed Principle, OCPA class is closed, since it may be compiled, stored in a library, baselined, and used by client classes. But it is also open, since any new class may use it as parent, adding new features. When a descendant class is defined, there is no need to change the original or to disturb its clients.

1. OCP belongs to an abstract coupling.2. Run Time Type Identification (RTTI)

Page 11: Clean Code�Chapter 3. (1)

Liskov Substitution Principle, LSPFunctions that use pointers or references to base classes must be able to use objects of derived classes without knowing it:

1. Liskov Substitution Principle becomes an extension to OCP.2. Violations of LSP are also meant to violations of OCP.3. LSP depends on abstract coupling. Heavily depends on preconditions and postconditions.

a. Preconditions: A contract that must be satisfied before a method can be invoked.b. Postconditions: It must be true upon method completion.c. Here is an example:

i. public class InvalidAmountException extends Exception {...}, this class inherits from java base Exception class. And can be thrown if the amount we try to deposit is less than zero. Create a new class, public abstract deposit (int amt) throws InvalidAmountException {...}. A developer can not use the following way to write a class, public void deposit (int amt) throws Exception {...} which is not allowed.

4. The (o instanceof A_class) should not happen in a class file.

Page 12: Clean Code�Chapter 3. (1)

Liskov Substitution Principle, LSP1. Supertype-Subtype relations between types (classes) defining a taxonomic hierarchy, where

a. For a subsumption relation: a subtype, subclass has a type-of (is-a) relationship with its supertype, superclass2. Whole/Entity/Container-part/Constituent/Member

a. For an aggregation relation (Iterator):i. a whole has a has-a relationship with its part

b. For a composition relation:i. a constituent has a part-of relationship with its entity.

c. For a containment:i. a member has a member-of relationship with its container

3. Type-Token relations between classes and instances, wherea. an object has an instance-of relationship with its class

4. Composition is dynamic binding (run time binding), whereas inheritance is static binding (compile time binding)5. UML diagram:

Page 13: Clean Code�Chapter 3. (1)

Liskov Substitution Principle, LSP1. PersistentSet::Add:

template <class T>void PersistentSet::Add (const T& t){

// using const will postpone the error to the runtime // ,throw bad_castPersistentObject &p =

dynamic_cast<PersistentObject &>(t);itsThirdPartyPersistentSet.add(p);

}

2. The logic flaw is a. Either the decision to pass a PersistentSet into the failed functionb. or it is the decision to add an object to the PersistentSet that is not derived from PersistentObject.

Page 14: Clean Code�Chapter 3. (1)

Liskov Substitution Principle, LSP4. template <class T>

void PersistentSet::Add(const T& t) {

// this will generate a compiler error if t is not derived from PersistentObject.itsThirdPartyPersistentSet.Add(t);

}

Page 15: Clean Code�Chapter 3. (1)

Interface Segregation Principle, ISPNo client should be forced to depend on methods it does not use. ISP splits interface into smaller and more specific ones.

1. Can employ the object form of the Adapter pattern to the TimedDoor problem..2. Drives from TimerClient and delegates to the TimedDoor. 3. TimedDoor wants to register a timeout request with the Timer. It creates a DoorTimerAdapter and registers it with the

Timer.4. Adapter calls TimedDoor by TimeOut which is inherited from TimerClient.

Page 16: Clean Code�Chapter 3. (1)

Interface Segregation Principle, ISP5. Separation through Multiple Inheritance, (author prefers to use this way rather than adapter design pattern, except

that DoorTimerAdapter is necessary)a. TimedDoor inherits from both Door and TimerClient.b. class TimedDoor: public Door, public TimerClient

{ public :

virtual void TimeOut (int timeOutId);};

Page 17: Clean Code�Chapter 3. (1)

Dependency Inversion Principle, DIP1. High level modules should not depend upon low level modules. Both should depend upon abstractions.2. Abstractions should not depend upon details. Details should depend upon abstractions.3. Let us talk a look at the two diagrams shown in this slide:

a. Figure 3: Simple Layers will cause a problem because dependency is transitive. b. Figure 4: Lower level layers are represented by an abstract class. The actual layers are derived from these

abstract classes. Not only is the transitive dependency of Policy Layer upon Utility Layer broken, but even the direct dependency of Policy Layer upon Mechanism Layer is broken.

Page 18: Clean Code�Chapter 3. (1)

Switch StatementCan make sure (polymorphism):

1. switch statement is buried in a low-level class2. It is never repeated.

Page 19: Clean Code�Chapter 3. (1)

Abstract Design Pattern v.s. Switch Statementpublic abstract class Employee { public abstract boolean isPayday(); public abstract Money calculatePay(); public abstract void deliveryPay(Money pay)}-----------------------public interface EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;}----------------------public class EmployeeFactoryImpl implements EmployFactory { public Employee makeEmpoyee(EmployeeRecord r) throws InvalidEmployeeType { switch (r.type) { ... } }}

Page 20: Clean Code�Chapter 3. (1)

Use Descriptive NamesModern IDEs like Eclipse or Intellij make it trivial to change names.

1. Don’t be afraid to make a name long2. Don’t be afraid to spend time choosing a name.3. Be consistent in your names

Page 21: Clean Code�Chapter 3. (1)

Function Arguments1. Zero argument (niladic), One argument (monadic), Two arguments (dyadic),

Three arguments (triadic) should be avoided!2. More than three requires very special justification.

Page 22: Clean Code�Chapter 3. (1)

Monadic 1. boolean fileExists(“MyFile”), transforms a file name String into an InputString

return value.2. void passwordAttemptFailedNtimes(int attempts), single argument function is

an event, but no output argument.3.

Page 23: Clean Code�Chapter 3. (1)

Flag Arguments1. Flag arguments are ugly. 2. loudly proclaim that this function does more than one thing.3. If you encounter this situation, you can extract the statements, like so, it

replaces render(boolean isSuite) into the followings: a. renderForSuite()b. renderForSingleTest()

Page 24: Clean Code�Chapter 3. (1)

Dyadic Functions1. A function with two arguments is harder to understand than a monadic

function.a. changes writeField(outputStream, name) to outputStream.writeField(name) by adding

writeField(name) into outputStream class.

2. Point p = new Point(0,0), two arguments are appropriate.3. assertEquals(expected, actual) are problematic. Why?

Page 25: Clean Code�Chapter 3. (1)

Triadic Function1. Functions that take three arguments are significantly harder to understand

than dyads.2. assertEquals(message, expected, actual).3.

Page 26: Clean Code�Chapter 3. (1)

Output Arguments1. appendFooter(StringBuffer report), you would not like to use report as an

output argument.2. Arguments are most naturally interpreted as inputs to a function.3. Output arguments should be avoided.4. Use this to act as an output argument.

Page 27: Clean Code�Chapter 3. (1)

Command Query Separation1. Functions should either do something or answer something, but not both.2. Use two methods to replace one method. As follows,

a. attributeExists(“username”)b. setAttribute(“username”,”unclebob”)

c. Here is an example:

if (attributeExists(“username”)) { setAttribute(“username”, “unclebob”);}

Page 28: Clean Code�Chapter 3. (1)

Extract Try/Catch Blocks

Original After:

Page 29: Clean Code�Chapter 3. (1)

References1. Clean Code, Book by Robert Cecil Martin

2. Java Design: Objects, UML, and Process