Software Craftsmanship 

Software Craftsmanship



Navigate with Esc, and

bit.ly/jsCraftsmanship
Interaktive Version der Präsentation!

![tools](images/johannes.png) ### [JohannesHoppe.de](http://www.johanneshoppe.de/)

bit.ly/jsCraftsmanship
Interaktive Version der Präsentation!

# Prinzipien Wissen Werkzeuge Wiederholung
# Wissen Know the pitfalls ![pitfalls](images/banana_peel.png)
## Implied globals Forgetting var ```javascript contenteditable var foo = function() { bar = 1; }; ```
## Boolean type conversion To Truthy or to Falsy. That is the *only* question! ```javascript contenteditable var el = document.getElementById('does_not_exist'); if(el == false) { alert("shouldn't we see this message?!"); } ```
## Trailing comma works on my machine! ```javascript contenteditable var foo = { bar: "bar", baz: "baz", }; ```
## Return undefined señor developers wear mustaches { ```javascript contenteditable var foo = function() { return { x : "looks like C# now!" }; } ```
## Associative arrays they don't exist ```javascript contenteditable var x = []; x['foo'] = "bar"; ```
## try .. catch .. finally who cares about the reason? ```javascript contenteditable var foo = function() { try { doCrazyStuff; } catch (e) { return false; } return true; }; ```
## Hoisting declare upfront all variables ```javascript contenteditable var foo = "global"; var bar = function() { alert(foo); var foo = "local"; alert(foo); }; ```
## Eval ... and the job is done ```javascript contenteditable function poorMansJsonParser(text) { return eval("(" + text + ")"); } var text = ' { "hello" : "world" } '; var json = poorMansJsonParser(text); ```
## Eval is evil! Never ever! ```javascript contenteditable var text = ' function() { alert("hacked!"); })( '; ```
## Globals the mother of all antipatterns ```javascript contenteditable function foo() { return "bar"; } console.log(this['foo']()); ```
![kitteh](images/kitteh.jpg) Every time you clutter the global namespace, somewhere in the world a helpless kitten dies!
# Wissen Pretty Code ![tools](images/mustache.png)
## Globals reduce, minimize, delete or kill them ```javascript contenteditable (function() { "wtf?" })(); ```
## The switch-case syndrome a functional language wants functions! ```javascript contenteditable switch (something) { case 1: doFirst(); break; case 2: doSecond(); break; case 3: doThird(); break; } ```
## Lookup tables avoid the switch-case syndrome ```javascript contenteditable var methods = { 1: doFirst, 2: doSecond, 3: doThird }; if (methods[something]) { methods[something](); } ```
## Revealing Module Pattern ```javascript contenteditable fragment var myRevealingModule = function () { var _name = "Johannes"; function greetings() { console.log("Hello " + _name); } function setName(name) { _name = name; } return { setName: setName, greetings: greetings }; }(); ``` [» Documentation](http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript)
## Modul loaders use AMD (require.js) ```javascript contenteditable fragment define('test', ['jquery'], function() { return { saySomething : function() { alert("hello!"); } } }); require(['test'], function(t) { t.saySomething(); }); ```
## Events Publish/Subscribe Pattern ```javascript contenteditable var $events = $({}); $events.bind('somethingHappens', function() { alert("Something happened!"); }); $events.trigger('somethingHappens'); ```
# Werkzeuge ![tools](images/tool.png)
* Visual Studio 2010/2012 * [JScript Editor Extensions](http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed) * [Resharper 7.1](http://www.jetbrains.com/resharper/whatsnew/#javascript) * [JSHint](http://www.jshint.com/platforms/) * [Chutzpah](http://chutzpah.codeplex.com/) * [Firebug](https://getfirebug.com/) / F12
![Jasmine](images/jasmine_logo.png") _TDD with [Jasmine](http://pivotal.github.com/jasmine/)_
## Why Jasmine?
  •     BDD-style     similar to JSpec or RSpec,
    created by authors of jsUnit and Screw.Unit
  •  independent  from any browser, DOM,
    framework or host language
  •    integrates     into continuous build systems
## Jasmine Bootstrap ```html contenteditable small _LT_!DOCTYPE html_GT_ _LT_html_GT_ _LT_head_GT_ _LT_title_GT_Jasmine Spec Runner_LT_/title_GT_ _LT_link rel=_QUOT_stylesheet_QUOT_ href=_QUOT_lib/jasmine-1.3.1/jasmine.css_QUOT_ /_GT_ _LT_script src=_QUOT_lib/jasmine-1.3.1/jasmine.js_QUOT__GT__LT_/script_GT_ _LT_script src=_QUOT_lib/jasmine-1.3.1/jasmine-html.js_QUOT__GT__LT_/script_GT_ _LT_!-- include source files here... --_GT_ _LT_script src=_QUOT_src/Player.js_QUOT__GT__LT_/script_GT_ _LT_script src=_QUOT_src/Song.js_QUOT__GT__LT_/script_GT_ _LT_!-- include spec files here... --_GT_ _LT_script src=_QUOT_spec/SpecHelper.js_QUOT__GT__LT_/script_GT_ _LT_script src=_QUOT_spec/PlayerSpec.js_QUOT__GT__LT_/script_GT_ _LT_script_GT_ (function () { var htmlReporter = new jasmine.HtmlReporter(); var jasmineEnv = jasmine.getEnv(); jasmineEnv.addReporter(htmlReporter); jasmineEnv.specFilter = function (spec) { return htmlReporter.specFilter(spec); }; var currentWindowOnload = window.onload; window.onload = function () { if (currentWindowOnload) { currentWindowOnload(); } jasmineEnv.execute(); }; })(); _LT_/script_GT_ _LT_/head_GT_ _LT_body_GT_ _LT_/body_GT_ _LT_/html_GT_ ```
## Output
## Hello World ```javascript contenteditable var helloWorld = function() { return "Hello World!"; }; describe('helloWorld', function() { it('says hello', function() { expect(helloWorld()).toEqual("Hello World!"); }); }); jasmine.getEnv().execute(); ``` hint: press F12 and paste this code!
# Wiederholung
#
If I would have had time...
## You will never have time!
* __Learn__ TDD * __Improve__ by self reflection * __Improve__ by feedback of others * __Help__ others to improve * __Teach__ TDD * __Learn__ a new language
## Test-Driven Development 1. Write your tests 1. Watch them fail 1. Make them pass 1. Refactor 1. Repeat

see [Growing Object-Oriented Software, Guided by Tests](http://www.amazon.de/dp/0321503627), page 6
see [Working Effectively with Legacy Code](http://www.amazon.de/dp/0131177052), page 62 or many other
## 1. Write your test ```javascript contenteditable describe("saveFormat", function () { var original = '{0} - {1} - {2}'; it("should replace placeholders", function () { var expected = 'A - B - C'; var formated = saveFormat(original, 'A', 'B', 'C'); expect(formated).toEqual(expected); }); it("should encode injected content", function () { var expected = 'A - _AMP_lt;b_AMP_gt;TEST_AMP_lt;/b_AMP_gt; - C'; var formated = saveFormat(original, 'A', '_LT_b_GT_TEST_LT_/b_GT_', 'C'); expect(formated).toEqual(expected); }); }); ```
## 2. Watch them fail ```javascript contenteditable var saveFormat = function() { return "boo!"; }; jasmine.getEnv().execute(); ``` Demo
## 3. Make them pass ```javascript contenteditable var saveFormat = function(txt) { $(arguments).each(function (i, item) { if (i _GT_ 0) { item = ($('_LT_div/_GT_').text(item).html()); txt = txt.replace("{" + (i - 1) + "}", item); } }); return txt; }; jasmine.getEnv().execute(); ``` Demo
## 4. Refactor ```javascript contenteditable function htmlEncode(input) { return ($('_LT_div/_GT_').text(input).html()); } var saveFormat = function(txt) { $.each(arguments, function (i, item) { if (i _GT_ 0) { item = htmlEncode(item); txt = txt.replace("{" + (i - 1) + "}", item); } }); return txt; }; jasmine.getEnv().execute(); ``` Demo
## 5. Repeat ```javascript contenteditable function htmlEncode(input) { return ($('_LT_div/_GT_').text(input).html()); } var saveFormat = function() { var args = Array.prototype.slice.call(arguments); var txt = args.shift(); $.each(args, function (i, item) { item = htmlEncode(item); txt = txt.replace("{" + i + "}", item); }); return txt; }; jasmine.getEnv().execute(); ``` Demo
## Deep practice
[codekata.pragprog.com](http://codekata.pragprog.com) [katas.softwarecraftsmanship.org](http://katas.softwarecraftsmanship.org/)
# Danke! ![QR-Code http://bit.ly/slides_dwx](images/bit.ly__slides_dwx.png) [blog.johanneshoppe.de](http://blog.johanneshoppe.de/2013/06/dwx-developer-week/)

Created by Johannes Hoppe | Print PDF | GitHub