-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchapter_3.html
More file actions
231 lines (216 loc) · 7.58 KB
/
Copy pathchapter_3.html
File metadata and controls
231 lines (216 loc) · 7.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Clean Code Summary</title>
</head>
<body>
<a href="index.html">Home</a>
<h1>Chapter 3: Functions</h1>
<h2>Functions Attribut</h2>
<ol>
<li>Small
<ul>
<li>Function should be two, or three, or four lines long, transparently obvious,
<br>told a story and led you to the next in a compelling order.</li>
</ul>
</li>
<li>Blocks and Indenting
<ul>
<li>Blocks within if statements, else statements, while statements, and
so on should be one line long.<br> Probably that line should be a function call.</li>
<li>Functions should not be large enough to hold nested structures.<br>
Therefore, the indent level of a function should not be greater than one or two.</li>
</ul>
</li>
<li>Do One Thing
<ul>
<li>Functions should do one thing. they should do it well.<br>they should do it only.</li>
<li>One level of abstraction below the stated name of the function.</li>
</ul>
</li>
<li>Has Descriptive Names
<ul>
<li>Choose function name that tell exactly what the function do.</li>
<li>Be consistent in your names. Use the same phrases, nouns,<br> and verbs in the function
names you choose for your modules</li>
</ul>
</li>
<li>Have No Side Effects
<ul>
<li>Function should do one thing, but it also does other hidden
things <br>
examples:
<ul>
<li>make unexpected changes to the variables of its own class.</li>
<li>make unexpected changes to the parameters passed into the function or to system globals.</li>
</ul>
</li>
</ul>
</li>
<li>Command Query Separation <br>
<ul>
<li>Functions should either do something or answer something, but not both. <br>
example: <code>public boolean set(String attribute, String value);</code> <br>
This leads to odd statements like this:
<code>if (set("username", "unclebob"))...</code> <br>
Is it asking whether the “username” attribute was previously set to “unclebob”? <br> Or is it asking whether the
“username” attribute was successfully set to “unclebob”? <br>
The real solution is to separate the command from the query<br>
<code><pre>if (attributeExists("username")) {
setAttribute("username", "unclebob");...}</pre> </code></li>
</ul>
</li>
</ol>
<h2>Function Arguments</h2>
<ul type="circle">
<li>The ideal number of arguments for a function is
zero (niladic).<br>Next comes one (monadic), followed
closely by two (dyadic). <br>Three arguments (triadic)
should be avoided where possible. <br>More than three
(polyadic) requires very special justification—and then shouldn’t be used anyway.
<ul>
<li>Common Monadic Forms (Single Argument Function):
<ol>
<li>Asking a question about that argument.<br>
example: boolean fileExists(“MyFile”){}
</li>
<li>Transforming the argument into something else and RETURN it.<br>
example:
<code><pre>
InputStream fileOpen(“MyFile”){
InputStream stream;
//body
return stream;
}
</pre></code>
</li>
<li>Flag Argument
<ul>
<li>Passing a boolean into a function is a terrible practice<br>
because it does one thing if the flag is true and another if false <br>
instead we should split the function into two <br>
examples: void whenTrue(){} and void whenFalse(){}
</li>
</ul>
</li>
</ol>
</li>
<li>Dyadic Functions (Double Argument Function)
<ul>
<li>There are times, where two arguments are appropriate.<br>
example: Point p = new Point(0,0); is reasonable <br>
because thay are ordered components of a single value
</li>
<li>Should think of mechanims to convert them into monads. <br>
example of convert writeField(output-Stream, name) into monadic: <ol>
<li>Make the writeField method a member of outputStream so that you can say <br>
outputStream.writeField(name).</li>
<li>Make the outputStream a member variable of the current
class so that you don’t have to pass it.</li>
<li>Extract a new class like FieldWriter
that takes the outputStream in its constructor and has a write method.</li>
</ol></li>
</ul>
</li>
<li>Triadic Functions (Triple Argument Function)
<ul>
<li>When a function seems to need three or more arguments, likely some of
arguments should be wrapped into a class of their own.<br>
example: the difference between the two following declarations:
<pre>
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
</pre>
</li>
</ul>
</li>
</ul>
</li>
<li>Output Arguments
<ul>
<li>Output arguments should be avoided. <br> If your function must change the state
of something, have it change the state of its owning object.
<br>example: when you see this function call <code>appendFooter(s);</code><br>
Does this function append s as the footer to something? <br> Or does it append some footer
to s? Is s an input or an output? <br>
so we have to see the function declaration <code>void appendFooter(StringBuffer report)</code><br>
it would be better for <code>appendFooter</code> to be invoked as <br>
<code>report.appendFooter();</code>
</li>
</ul>
</li>
</ul>
<h2>Switch Statement in Functions</h2>
<ul type="circle">
<li>Bury the switch statement in the basement of an ABSTRACT FACTORY<br>
example:<code><pre>
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);
}}}</pre></code>
</li>
</ul>
<h2>Exceptions in Functions</h2>
<ul type="circle">
<li>Prefer Exceptions to Returning Error Codes
<ul type="square">
<li>This lead to deeply nested structures, when you return an error code, <br>
you create the problem that the caller must deal with the error immediately <br>
example: <code><pre>
if (deletePage(page) == E_OK) {
if (configKeys.deleteKey(page.name.makeKey()) == E_OK){
logger.log("page deleted");
} else {logger.log("configKey not deleted");}
} else {logger.log("delete failed")};
return E_ERROR;</pre></code>
should be
<pre>try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
catch (Exception e) {
logger.log(e.getMessage());
}</pre>
</li>
</ul>
</li>
<li>Extract Try/Catch Blocks
<ul>
<li>Extract the bodies of the try and catch blocks out into functions of their own. <br>
example:
<pre>public void delete(Page page) {
try {
deletePageAndAllReferences(page);
}
catch (Exception e) {
logError(e);
}
}</pre>
</li>
<li>Function that handles
errors should do nothing else. if the keyword
try exists in a function, <br> it should be the very first word in the function and that there
should be nothing after the catch/finally blocks</li>
</ul>
</li>
</ul>
</body>
</html>