0% found this document useful (0 votes)
34 views62 pages

Clean Code: A Handbook of Agile Software Craftsmanship 1st Edition PDF

The document discusses the problems associated with using switch statements in functions that handle different employee types, highlighting issues like size, multiple responsibilities, and violation of design principles. It proposes using an abstract factory pattern to encapsulate the switch statement and create polymorphic objects, thereby improving code structure. Additionally, it emphasizes the importance of using descriptive names for functions to enhance code readability and maintainability.

Uploaded by

tatev64099
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views62 pages

Clean Code: A Handbook of Agile Software Craftsmanship 1st Edition PDF

The document discusses the problems associated with using switch statements in functions that handle different employee types, highlighting issues like size, multiple responsibilities, and violation of design principles. It proposes using an abstract factory pattern to encapsulate the switch statement and create polymorphic objects, thereby improving code structure. Additionally, it emphasizes the importance of using descriptive names for functions to enhance code readability and maintainability.

Uploaded by

tatev64099
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

Find the full original copyable PDF textbook in the link

below:

Visit Full Copyable PDF


38 Chapter 3: Functions

Consider Listing 3-4. It shows just one of the operations that might depend on the
type of employee.

Listing 3-4
Payroll.java
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);
}
}

There are several problems with this function. First, it’s large, and when new
employee types are added, it will grow. Second, it very clearly does more than one thing.
Third, it violates the Single Responsibility Principle7 (SRP) because there is more than one
reason for it to change. Fourth, it violates the Open Closed Principle8 (OCP) because it
must change whenever new types are added. But possibly the worst problem with this
function is that there are an unlimited number of other functions that will have the same
structure. For example we could have
isPayday(Employee e, Date date),
or
deliverPay(Employee e, Money pay),
or a host of others. All of which would have the same deleterious structure.
The solution to this problem (see Listing 3-5) is to bury the switch statement in the
basement of an ABSTRACT FACTORY,9 and never let anyone see it. The factory will use the
switch statement to create appropriate instances of the derivatives of Employee, and the var-
ious functions, such as calculatePay, isPayday, and deliverPay, will be dispatched poly-
morphically through the Employee interface.
My general rule for switch statements is that they can be tolerated if they appear
only once, are used to create polymorphic objects, and are hidden behind an inheritance

7. a. http://en.wikipedia.org/wiki/Single_responsibility_principle
b. http://www.objectmentor.com/resources/articles/srp.pdf
8. a. http://en.wikipedia.org/wiki/Open/closed_principle
b. http://www.objectmentor.com/resources/articles/ocp.pdf
9. [GOF].
Use Descriptive Names 39

Listing 3-5
Employee and Factory
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) throws InvalidEmployeeType;
}
-----------------
public class EmployeeFactoryImpl implements EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
switch (r.type) {
case COMMISSIONED:
return new CommissionedEmployee(r) ;
case HOURLY:
return new HourlyEmployee(r);
case SALARIED:
return new SalariedEmploye(r);
default:
throw new InvalidEmployeeType(r.type);
}
}
}

relationship so that the rest of the system can’t see them [G23]. Of course every circum-
stance is unique, and there are times when I violate one or more parts of that rule.

Use Descriptive Names


In Listing 3-7 I changed the name of our example function from testableHtml to
SetupTeardownIncluder.render. This is a far better name because it better describes what
the function does. I also gave each of the private methods an equally descriptive name
such as isTestable or includeSetupAndTeardownPages. It is hard to overestimate the value
of good names. Remember Ward’s principle: “You know you are working on clean code
when each routine turns out to be pretty much what you expected.” Half the battle to
achieving that principle is choosing good names for small functions that do one thing.
The smaller and more focused a function is, the easier it is to choose a descriptive
name.
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.
Thank you for reading. To get the full copyable version:

CLICK HERE

You might also like