PageRenderTime 25ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/craftmanship/functions/index.html

https://github.com/JeroenDeDauw/slides
HTML | 467 lines | 382 code | 79 blank | 6 comment | 0 complexity | 2d805fa7cece0c9ccfa164cc7fd9e384 MD5 | raw file
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Clean functions</title>
  6. <meta name="description" content="How to create clean functions">
  7. <meta name="author" content="Jeroen De Dauw">
  8. <meta name="apple-mobile-web-app-capable" content="yes" />
  9. <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  11. <link rel="stylesheet" href="css/reveal.min.css">
  12. <link rel="stylesheet" href="css/theme/default.css" id="theme">
  13. <!-- For syntax highlighting -->
  14. <link rel="stylesheet" href="lib/css/zenburn.css">
  15. <!-- If the query includes 'print-pdf', use the PDF print sheet -->
  16. <script>
  17. document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
  18. </script>
  19. <!--[if lt IE 9]>
  20. <script src="lib/js/html5shiv.js"></script>
  21. <![endif]-->
  22. </head>
  23. <body>
  24. <div class="reveal">
  25. <!-- Any section element inside of this container is displayed as a slide -->
  26. <div class="slides">
  27. <section>
  28. <h2>Clean functions</h2>
  29. <p>
  30. Caturday will not be stopped!<br />
  31. <img src="img/Willnotbestopped.gif" alt="Y U NO LOAD">
  32. </p>
  33. </section>
  34. <section>
  35. <h2>Clean functions</h2>
  36. <p>
  37. Presentation by <a href="https://twitter.com/JeroenDeDauw">@JeroenDeDauw</a><br /><br />
  38. bit.ly/clean-functions
  39. </p>
  40. </section>
  41. <section data-state="blackout">
  42. <h2>Function size and naming</h2>
  43. </section>
  44. <section>
  45. <h3>How big should a function be?</h3>
  46. <ol>
  47. <li class="fragment">It should be SMALL</li>
  48. <li class="fragment">It should be SMALLER than that</li>
  49. </ol>
  50. <br /><br />
  51. <blockquote class="fragment">
  52. A function should do one thing.<br />
  53. It should do it well, and it should do it only.
  54. </blockquote>
  55. </section>
  56. <section>
  57. <p>4 - 5 lines</p>
  58. </section>
  59. <section>
  60. <h3>What is "one thing"?</h3>
  61. <p class="fragment">
  62. One level of abstraction
  63. </p>
  64. <pre class="fragment"><code contenteditable class="PHP">
  65. function onFirstPost() {
  66. $messageText = $this->getWelcomeMessageBody();
  67. if ($this->addFooter()) $messageText.=$this->getWelcomeMessageFooter();
  68. $this->emailer->send( $messageText );
  69. foreach ( $this->getReviewers() as $reviewer ) {
  70. $this->reviewerNotifier->notify( $reviewer );
  71. }
  72. }
  73. </code></pre>
  74. <pre class="fragment"><code contenteditable class="PHP">
  75. function onFirstPost() {
  76. $this->sendWelcomeMessage();
  77. $this->notifyReviewers();
  78. }
  79. </code></pre>
  80. </section>
  81. <section>
  82. <p>
  83. Predicates of if and while statements
  84. </p>
  85. <pre><code contenteditable class="PHP">
  86. if ( $foo === 'bar' && ( $user->isAllowed( '' ) || $baz )
  87. && $this->bah() ) {
  88. $this->sendWelcomeMessage();
  89. }
  90. </code></pre>
  91. <pre class="fragment"><code contenteditable class="PHP">
  92. if ( $this->isFirstPost() ) {
  93. $this->sendWelcomeMessage();
  94. }
  95. </code></pre>
  96. </section>
  97. <section>
  98. <p>
  99. Bodies of control structures
  100. </p>
  101. <pre><code contenteditable class="PHP">
  102. if ( $this->isFirstPost() ) {
  103. $this->sendWelcomeMessage();
  104. }
  105. </code></pre>
  106. <pre><code contenteditable class="PHP">
  107. foreach ( $this->getReviewers() as $reviewer ) {
  108. $this->notifyReviewer( $reviewer );
  109. }
  110. </code></pre>
  111. </section>
  112. <section>
  113. <p>
  114. How much indenting / nesting?
  115. </p>
  116. </section>
  117. <section>
  118. <p>
  119. Name length rule
  120. </p>
  121. <pre><code contenteditable class="PHP">
  122. $user->remove();
  123. function remove() {
  124. // ...
  125. $this->removePostsFromDatabase();
  126. // ...
  127. }
  128. </code></pre>
  129. </section>
  130. <section>
  131. <p>
  132. Well written prose
  133. </p>
  134. <pre><code contenteditable class="PHP">
  135. if ( $this->isFirstPost() ) {
  136. $this->sendWelcomeMessage();
  137. $this->notifyReviewers();
  138. }
  139. </code></pre>
  140. <pre class="fragment"><code contenteditable class="PHP">
  141. function notifyReviewers() {
  142. foreach ( $this->reviewers as $reviewer ) {
  143. $reviewer->notify( $this->post );
  144. }
  145. }
  146. </code></pre>
  147. </section>
  148. <section>
  149. <h3>Big functions</h3>
  150. <ul>
  151. <li>Have multiple functional areas</li>
  152. <li class="fragment">Functions define scopes</li>
  153. <li class="fragment">Have variables used throughout</li>
  154. <li class="fragment">That is what classes are for</li>
  155. <li class="fragment">Group of functions that use a common set of variables</li>
  156. </ul>
  157. </section>
  158. <section>
  159. <h3>Panic! Lots of small functions!</h3>
  160. <ul>
  161. <li class="fragment">Function call overhead</li>
  162. <li class="fragment">Long time to write all those functions</li>
  163. </ul>
  164. </section>
  165. <section>
  166. <h3>Silly!</h3>
  167. <p>
  168. Well named methods, classes and namespaces act like signposts
  169. </p>
  170. </section>
  171. <section>
  172. <p>
  173. So what makes small functions unsettling?
  174. </p>
  175. </section>
  176. <section>
  177. <p>
  178. The landscape metaphor
  179. </p>
  180. </section>
  181. <section>
  182. <p>
  183. Long functions are familiar.<br />
  184. Like landscapes, we recognize the landmarks
  185. </p>
  186. </section>
  187. <section>
  188. <h3>New people</h3>
  189. <ul>
  190. <li class="fragment">Do not recognize anything</li>
  191. <li class="fragment">Can only start wandering around aimlessly</li>
  192. </ul>
  193. </section>
  194. <section>
  195. <h3>New people + signposts</h3>
  196. <ul>
  197. <li>Establish themselves quickly</li>
  198. <li>Start being productive fast</li>
  199. </ul>
  200. </section>
  201. <section>
  202. <h3>The bedroom metaphor</h3>
  203. <ul>
  204. <li class="fragment">Everything lying around at some place well known to you</li>
  205. <li class="fragment">Mom gets upset and forces you to clean room</li>
  206. <li class="fragment">You rebel and put things back</li>
  207. <li class="fragment">Part of growing up is realizing this does not work in teams</li>
  208. </ul>
  209. </section>
  210. <section>
  211. <h3>Call time overhead</h3>
  212. <ul>
  213. <li class="fragment">Nanosecond</li>
  214. <li class="fragment">Compilers are good at optimizing</li>
  215. <li class="fragment">Time better spend on real performance issues</li>
  216. </ul>
  217. </section>
  218. <section>
  219. <blockquote>
  220. I'm sorry I had to write you such a long letter,<br />
  221. but I did not have time to write you a short one
  222. </blockquote>
  223. <p>-- Blaise Pascal</p>
  224. <br />
  225. <ul>
  226. <li class="fragment">Takes time and effort</li>
  227. <li class="fragment">Places burden of breaking down on ALL readers</li>
  228. <li class="fragment">You are a reader as well</li>
  229. </ul>
  230. </section>
  231. <section>
  232. <h3>Example from gerrit</h3>
  233. <ul>
  234. <li><a href="https://gerrit.wikimedia.org/r/#/c/78365/2/lib/resources/jquery.wikibase/jquery.wikibase.entityselector.js">Step 0, wrong direction</a></li>
  235. <li><a href="https://gerrit.wikimedia.org/r/#/c/78365/3/lib/resources/jquery.wikibase/jquery.wikibase.entityselector.js">Step 1, first split</a></li>
  236. <li><a href="https://gerrit.wikimedia.org/r/#/c/78365/4/lib/resources/jquery.wikibase/jquery.wikibase.entityselector.js">Step 2, second split</a></li>
  237. </ul>
  238. </section>
  239. <section data-state="blackout">
  240. <h2>Function arguments</h2>
  241. </section>
  242. <section>
  243. <h3>How many?</h3>
  244. <ul>
  245. <li class="fragment">Ideally none, the fewer the better</li>
  246. <li class="fragment">Arguments are hard to understand</li>
  247. <li class="fragment">More then 3 requires very special justification</li>
  248. </ul>
  249. </section>
  250. <section>
  251. <section>
  252. <h3>Flag arguments</h3>
  253. <p class="fragment">
  254. Make functions do multiple things!
  255. </p>
  256. <pre class="fragment"><code contenteditable class="PHP">
  257. renderHtml( true );
  258. </code></pre>
  259. </section>
  260. <section>
  261. <pre><code contenteditable class="PHP">
  262. function renderHtml( $userIsLoggedIn ) {
  263. // ...
  264. if ( $userIsLoggedIn ) {
  265. // ...
  266. }
  267. // ...
  268. }
  269. </code></pre>
  270. <pre class="fragment"><code contenteditable class="PHP">
  271. function renderHtmlForLoggedInUser() {
  272. }
  273. function renderHtmlForAnonUser() {
  274. }
  275. </code></pre>
  276. <pre class="fragment"><code contenteditable class="PHP">
  277. renderHtmlForLoggedInUser();
  278. </code></pre>
  279. </section>
  280. </section>
  281. <section>
  282. <h3>Argument objects</h3>
  283. <pre><code contenteditable class="PHP">
  284. function drawCircle( $x, $y, $radius ) {}
  285. </code></pre>
  286. <pre><code contenteditable class="PHP">
  287. function drawCircle( Point $center, $radius ) {}
  288. </code></pre>
  289. </section>
  290. <section>
  291. <h3>Output arguments</h3>
  292. <pre><code contenteditable class="PHP">
  293. appendFooter( $report );
  294. </code></pre>
  295. <pre><code contenteditable class="PHP">
  296. $report->appendFooter();
  297. </code></pre>
  298. </section>
  299. <section data-state="blackout">
  300. <h2>Side effects</h2>
  301. </section>
  302. <section>
  303. <p>Either do something OR answer something, not both!</p>
  304. </section>
  305. <section>
  306. <pre><code contenteditable class="Java">
  307. public boolean set( String attributeName, String value );
  308. </code></pre>
  309. <pre class="fragment"><code contenteditable class="Java">
  310. if ( set( "username", "NyanCat" ) )
  311. </code></pre>
  312. </section>
  313. <section>
  314. <p>Same for returning error codes. Error handling is one thing.</p>
  315. </section>
  316. <section data-transition="linear">
  317. <h3>Conclusion</h3>
  318. <ul>
  319. <li>Small!</li>
  320. <li class="fragment">Small well named functions act like signposts</li>
  321. <li class="fragment">Classes hide in big functions</li>
  322. <li class="fragment">Functions do one thing, extract till you drop</li>
  323. <li class="fragment">Minimize arguments</li>
  324. <li class="fragment">Command query separation</li>
  325. </ul>
  326. </section>
  327. <section data-state="blackout" data-transition="linear">
  328. <h3>These slides</h3>
  329. <p>CC BY-SA 3.0, <a href="https://twitter.com/#!/JeroenDeDauw">Jeroen De Dauw</a></p>
  330. <p>
  331. <a href="https://github.com/JeroenDeDauw/slides/">Clone from GitHub</a>
  332. or view at <a href="http://bit.ly/clean-functions">bit.ly/clean-functions</a>
  333. </p>
  334. <div class="fragment">
  335. <br />
  336. <h3>Attribution</h3>
  337. <p>Slide engine: <a href="http://lab.hakim.se/reveal-js/">reveal.js</a>, Copyright (C) 2014 Hakim El Hattab</p>
  338. <small>
  339. <br />
  340. A lot of the material in these slides is based on works by Robert C. Martin.<br />
  341. In particular his book
  342. <a href="http://www.goodreads.com/book/show/3735293-clean-code">Clean Code</a>
  343. , and
  344. <a href="http://www.cleancoders.com/">Clean Coders</a>
  345. video series.
  346. </small>
  347. </div>
  348. </section>
  349. <section data-state="blackout" data-transition="linear">
  350. <h3>Instead of me</h3>
  351. <img height="290px" src="img/clean-code.jpg" />
  352. <img height="290px" src="img/clean-coder.jpg" />
  353. <img height="290px" src="img/fowler-enterprise.jpg" />
  354. <img height="290px" src="img/legacy-code.jpg" />
  355. </section>
  356. <section data-state="blackout">
  357. <img src="img/i-has-question-lolcat.jpg" />
  358. </section>
  359. </div>
  360. </div>
  361. <script src="lib/js/head.min.js"></script>
  362. <script src="js/reveal.min.js"></script>
  363. <script>
  364. // Full list of configuration options available here:
  365. // https://github.com/hakimel/reveal.js#configuration
  366. Reveal.initialize({
  367. controls: true,
  368. progress: true,
  369. history: true,
  370. center: true,
  371. theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
  372. transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
  373. // Optional libraries used to extend on reveal.js
  374. dependencies: [
  375. { src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
  376. { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
  377. { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
  378. { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
  379. { src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
  380. { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
  381. // { src: 'plugin/leap/leap.js', async: true }
  382. // { src: 'plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } }
  383. // { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
  384. ]
  385. });
  386. </script>
  387. </body>
  388. </html>