<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>BEKK Open</title>
	
	<link>http://open.bekk.no</link>
	<description>Et innblikk i hva som skjer i BEKK</description>
	<lastBuildDate>Fri, 29 Jun 2012 12:59:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BekkOpen" /><feedburner:info uri="bekkopen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Wordfeud for WP7 og Windows 8</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/GIKiFhcKui8/</link>
		<comments>http://open.bekk.no/wordfeud-for-wp7-og-windows-8/#comments</comments>
		<pubDate>Fri, 29 Jun 2012 12:59:19 +0000</pubDate>
		<dc:creator>Jonas Follesø</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[konferanse]]></category>
		<category><![CDATA[mobil]]></category>
		<category><![CDATA[ndc2012]]></category>
		<category><![CDATA[windows 8]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=9148</guid>
		<description><![CDATA[I løpet av utviklingen av Wordfeud for WP7 og Windows 8 høstet vi mange erfaringer rundt hvordan designe for Metro, hvordan oppnå størst grad av kodegjenbruk på tvers av WP7 og Windows 8, samt erfaringer rundt test- og release-planlegging for Windows Marketplace. Disse erfaringene delte vi på årets NDC, i form av foredraget ”Bringing Wordfeud to WP7 and Windows 8”.]]></description>
			<content:encoded><![CDATA[<p>I løpet av det siste året har BEKK utviklet en rekke spennende applikasjoner for våre kunder til Windows Phone 7 plattformen. En av disse er Wordfeud for Windows Phone 7, og senere Windows 8. Prosjektet ble gjennomført som et samarbeid mellom Bertheussen IT, Nokia, Microsoft og BEKK, hvor BEKK var ansvarlig for utviklingsteamet.</p>
<p>Wordfeud for Windows Phone ble lansert 01. Februar, samtidig som Nokia lanserte sin Lumia 800. Spillet ble umiddelbart en av de mest nedlastede appene på Marketplace, og er fortsatt på topp 5 listen i blant annet <a title="Windows Phone Marketplace Top List Norway" href="http://www.windowsphone.com/nb-NO/apps?list=top" target="_blank">Norge</a>, <a title="Windows Phone Marketplace Top List Sverige" href="http://www.windowsphone.com/sv-SE/apps?list=top" target="_blank">Sverige</a>, <a title="Windows Phone Marketplace Top List Danmark" href="http://www.windowsphone.com/da-DK/apps?list=top" target="_blank">Danmark</a>, <a title="Windows Phone Marketplace Top List Nederland" href="http://www.windowsphone.com/nl-NL/apps?list=top" target="_blank">Nederland</a>. Spillet har fått en rangering på 4.5 av 5 i snitt, basert på over 1250 anmeldelser fra sluttbrukere.</p>
<p><img class="alignnone size-full wp-image-9154" title="Wordfeud WP7 Nokia Lumia 800" src="http://open.bekk.no/wp-content/uploads/2012/06/WordfeudNokia.jpg" alt="Wordfeud for Windows Phone 7" width="500" height="465" /></p>
<p>Etter suksessen med Wordfeud for Windows Phone 7, bestemte Bertheussen IT og Microsoft seg for å bruke Wordfeud som en av lanseringsappene på Windows 8. I april begynte vi jobben med å tilpasse Wordfeud for Windows 8 plattformen, og spillet ble gjort tilgjengelig på Windows Marketplace samtidig som Microsoft lanserte Windows 8 Release Preview i begynnelsen av Juni. Dette er den første Norske applikasjonen utviklet for Windows 8 sitt nye Metro grensesnitt.</p>
<p><img class="alignnone size-full wp-image-9151" title="Wordfeud Windows 8" src="http://open.bekk.no/wp-content/uploads/2012/06/WordfeudWin8Blog.jpg" alt="Wordfeud for Windows 8" width="720" height="437" /></p>
<p>I løpet av utviklingen av Wordfeud for WP7 og Windows 8 høstet vi mange erfaringer rundt hvordan designe for Metro, hvordan oppnå størst grad av kodegjenbruk på tvers av WP7 og Windows 8, samt erfaringer rundt test- og release-planlegging for Windows Marketplace. Disse erfaringene delte vi på årets NDC, i form av foredraget ”Bringing Wordfeud to WP7 and Windows 8”. Foredraget er nå tilgjengelig som video – og du kan se det i sin helhet nedenfor.</p>
<p><iframe src="http://player.vimeo.com/video/43548884?byline=0&amp;portrait=0&amp;color=6da6ae" frameborder="0" width="700" height="393"></iframe></p>
<p><a href="http://vimeo.com/43548884">Jonas Follesø &#8211; Bringing Wordfeud to WP7 and Windows 8</a> from <a href="http://vimeo.com/ndcoslo">NDCOslo</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<h3>Bringing Wordfeud to WP7 and Windows 8</h3>
<p><em>This winter a development team from BEKK has worked closely with Bertheussen IT, Microsoft and Nokia to bring the massively popular game Wordfeud to WP7 and Windows 8. In this sessions Jonas will share lessons learned while porting the game, and showcase how the game takes advantage of the various unique features of each platform.</em></p>
<p><em>The sessions will cover a range of topics such as; how to port an iOS designed application to the Metro design language, why taking advantage of Live Tiles is important, how to use operating system features such as Charms, Lock Screen Apps, Launchers &amp; Choosers and more.</em></p>
<p><em>The session will also cover the more technical aspects of architecting an application for maximum code reuse across Windows Phone 7 and Windows 8. Jonas will demonstrate 4 different techniques for enabling reuse of code.</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/GIKiFhcKui8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/wordfeud-for-wp7-og-windows-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/wordfeud-for-wp7-og-windows-8/</feedburner:origLink></item>
		<item>
		<title>OWASP Top 10 for JavaScript – A5: Cross Site Request Forgery (CSRF)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/jgAYG5lNoWk/</link>
		<comments>http://open.bekk.no/owasp-top-10-for-javascript-a5-cross-site-request-forgery-csrf/#comments</comments>
		<pubDate>Wed, 27 Jun 2012 18:39:33 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Sikkerhet]]></category>
		<category><![CDATA[CSRF]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[owasp]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=9136</guid>
		<description><![CDATA[The vulnerability known as <a href="https://www.owasp.org/index.php/Top_10_2010-A5">A5 - Cross-Site Request Forgery (CSRF)</a> has many names including session riding and one-click attack. It's a blind attack in the sense that the attacker is not directly attacking the application, but rather tricks a user into doing the attack for him.  In this article we'll look at what's going on, how to fix it and also look at an attack specific to single page web applications.]]></description>
			<content:encoded><![CDATA[<p>The vulnerability known as <a href="https://www.owasp.org/index.php/Top_10_2010-A5">A5 &#8211; Cross-Site Request Forgery (CSRF)</a> has many names including session riding and one-click attack. It&#8217;s a blind attack in the sense that the attacker is not directly attacking the application, but rather tricks a user into doing the attack for him. In this article we&#8217;ll look at what&#8217;s going on, how to fix it and also look at an attack specific to single page web applications.</p>
<p>This is the risk rating from OWASP:</p>
<table style="font-size: 90%;margin: 1em;border: 1px solid #DDD">
<tbody>
<tr>
<th width="16.5%"> Threat Agents</th>
<th width="16.5%"> Attack Vectors</th>
<th colspan="2" width="33%"> Security Weakness</th>
<th width="16.5%"> Technical Impacts</th>
<th width="16.5%"> Business Impacts</th>
</tr>
<tr>
<td> ______</td>
<td><b>Exploitability<br />AVERAGE</b></td>
<td><b>Prevalence<br />WIDESPREAD</b></td>
<td><b>Detectability<br />EASY</b></td>
<td><b>Impact<br />MODERATE</b></td>
<td>______</td>
</tr>
<tr valign="top">
<td>Consider anyone who can trick your users into submitting a request to your website. Any website or other HTML feed that your users access could do this.</td>
<td>Attacker creates forged HTTP requests and tricks a victim into submitting them via image tags, XSS, or numerous other techniques. If the <u>user is authenticated</u>, the attack succeeds.</td>
<td colspan="2"><a href="/index.php/CSRF" title="CSRF" class="mw-redirect">CSRF</a> takes advantage of web applications that allow attackers to predict all the details of a particular action.</p>
<p>Since browsers send credentials like session cookies automatically, attackers can create malicious web pages which generate forged requests that are indistinguishable from legitimate ones.</p>
<p>Detection of CSRF flaws is fairly easy via penetration testing or code analysis.</td>
<td>Attackers can cause victims to change any data the victim is allowed to change or perform any function the victim is authorized to use</td>
<td>Consider the business value of the affected data or application functions. Imagine not being sure if users intended to take these actions.</p>
<p>Consider the impact to your reputation.</td>
</tr>
</tbody>
</table>
<h3>The problem</h3>
<p>When a server receives a POST request, there is no secure HTTP or browser specific way in which the server can know how the request was created. Consider a form posting data a given URI of the server. The different fields in that form and their corresponding values are normally formatted in the <code>application/x-www-form-urlencoded</code> and <code>multipart/form-data</code>.</p>
<p>Additionally the browser will include a set of headers. The <code>Cookie</code> header includes any cookies for the given url. The <code>Referer</code> header contains the url of the page the request originated from. The <code>Origin</code> header contains the domain name, port and schema of the request the request originated from, but has no path information.</p>
<p>Consider a website A that has no CSRF-protection. A user logged in to site A, is tricked by the attacker into visiting his site B. Javascript on site B automatically builds and submits a form to site A in a hidden iframe. Now because the user is already logged in on site A and the request is headed for site A, the browser will happily include the users cookies for site A. This includes the session cookie. So the server on site A, will see an incoming request with a valid session. And because it trusts the session it will happily accept the request and perform the required action.</p>
<p>For a relatively new list of high value targets having this vulnerability, see Egor Homakov&#8217;s blog post: <a href="http://homakov.blogspot.no/2012/03/hacking-skrillformer-moneybookers.html">&#8220;A few CSRF-like vulnerable examples&#8221;</a>.</p>
<h3>Attempted solutions</h3>
<p>There are many ways developers have tried to mitigate this vulnerability.</p>
<h4>GET vs. POST</h4>
<p>The first kinds of CSRF attacks often used GET requests. The attacker would typically add an <code>img</code> tag pointing to a url that performed some action. An example could be:
</p>
<pre>&lt;img src="http://victimserver.com/add_friend?userid=123" style="visibility: hidden" &gt;</pre>
<p>While using GET requests for state changing operations is considered bad practice, as explained above, POST requests are just as vulnerable to CSRF.
</p>
<h4>The <code>Referer</code> header</h4>
<p>When looking at the headers above, the first thing that might strike you, is to use the <code>Referer</code> header. But this is probably not the best choice. This header contains path information and is often blocked/removed in firewalls, browser plugins etc. for privacy reasons. Most browsers also strip it when moving between schemas, so a post from https to http would probably result in the header being stripped out.
</p>
<h4>The <code>Origin</code> header</h4>
<p>While the <code>Origin</code> header does not have the same privacy issues as the <code>Referer</code> header, it lacks support in older browsers. It may be a suitable defense in the future, it may not be the best choice for now.</p>
<h3>Working solutions</h3>
<p>Here are two of the most popular approaches.</p>
<h4>The token approach</h4>
<p>The token approach has quickly become a popular way of mitigating CSRF. Ruby on Rails and ASP.NET MVC both use this approach (authentication_token / anti_forgery_token). The server generates a cryptographically random value &#8211; a token or nonce &#8211; and sticks that token in the user&#8217;s session. The token is also included as a hidden field in any form generated by the server. When a POST request comes back to the server, the server can check that the token included in the request, is the same as the token in the user&#8217;s session. Because the attacker cannot possibly guess this token, any POST request originating from the attacker&#8217;s server, would have the wrong token.</p>
<h4>The double-submitted cookie</h4>
<p>This approach is somewhat similar to the token approach in the sense that it&#8217;s using a cryptographically random value. But instead of sticking this value in the user&#8217;s session, the token is set as a cookie. Javascript in the browser will read out the token from the cookie and add it as a hidden field in the form. Upon receiving a request, the server can now check if the value in the incoming cookie is the same as the value included in the POST body as a form field.</p>
<p>This relies on the Same Origin Policy blocking the a web page on the attacker&#8217;s server from accessing the token cookie, and thus from including the correct value as a hidden field in the form.</p>
<h3>What about Javascript based single page web apps</h3>
<p>Javascript based applications typically make use of XHR requests for submitting POST requests. In addition many applications built on frameworks like backbone.js, will read and submit pure JSON-objects instead of using the <code>application/x-www-form-urlencoded</code> and <code>multipart/form-data</code> encodings.</p>
<p>If we decide to use the token based approach, we typically make a request to the server in order to get a JSON containing the token. In later POST request, we simply include it as a header. This can easily be achieved when using jQuery:</p>
<pre>$("body").bind("ajaxSend", function(elm, xhr, s){
	if (s.type == "POST") {
		xhr.setRequestHeader('X-CSRF-Token', csrf_token);
	}
});</pre>
<p>If you are using REST services supporting PUT and DELETE, you can easily modify the above code to also send the token for those methods.</p>
<p>If you are on node, there is a server side library for csrf protection in <a href="http://www.senchalabs.org/connect/csrf.html">Connect</a>.</p>
<h3>CS#RF &#8211; Cross Site Hash Request Forgery</h3>
<p>Consider an application where we have applied the token and jQuery based mitigation above and it works as intended. Our app includes the tokens on POST requests. Also consider that the application is using hash based navigation. Let&#8217;s use the <a href="https://github.com/eoftedal/WebRebels2012/tree/master/railsapp">Conference application</a> as an example with regards to routing. This application the following routes:</p>
<ul>
<li><code>#/talk/1</code> &#8211; show the given talk</li>
<li><code>#/talk/1/edit</code> &#8211; open the given talk in edit mode</li>
<li><code>#/talk/1/delete</code> &#8211; delete the given talk</li>
</ul>
<p>The first link will show the talks title, description etc. as HTML. Nothing special there.</p>
<p>The second one will open the talk in edit mode, allowing the user to update the title or description. Upon saving the changes, the Javascript will extract the values from the form, stick them inside a JSON object, and submit it back to the server while automatically including our CSRF token. So the protection works as expected.</p>
<p>But the last route can be problematic. If it simply opens a confirmation page and then posts the request to the server when the user confirms the deletion, then we&#8217;re all right. But if triggering that route is enough for the request to be submitted, we&#8217;re in trouble. An attacking site can simply open a hidden iframe pointing to that route, and trick an innocent victim into visiting the page. Our javascript will happily submit the request including the CSRF token, just like we programmed it to. In that respect action triggering routes (routes that actuallly cause server side state changes) are similar to the problem with GET request as described under &#8220;GET vs. POST&#8221;. </p>
<h3>Mitigation summarized</h3>
<p>All of these need to be implemented</p>
<ul>
<li>Reject GET requests on state changing operations</li>
<li>Include cryptographically random token in each state changing request (POST, DELETE, PUT)</li>
<li>Don&#8217;t let routes directly change data</li>
</ul>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/jgAYG5lNoWk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/owasp-top-10-for-javascript-a5-cross-site-request-forgery-csrf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/owasp-top-10-for-javascript-a5-cross-site-request-forgery-csrf/</feedburner:origLink></item>
		<item>
		<title>OWASP Top 10 for Javascript – A4: Insecure Direct Object References</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/LhFBL-DxXFA/</link>
		<comments>http://open.bekk.no/owasp-top-10-for-javascript-a4-insecure-direct-object-references/#comments</comments>
		<pubDate>Wed, 20 Jun 2012 20:06:51 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[Sikkerhet]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[owasp]]></category>
		<category><![CDATA[top 10]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=9113</guid>
		<description><![CDATA[How do A4 &#8211; Insecure Direct Object References apply to Javascript? Well, it all depends on how the system was formed, but this is very likely to become a problem in pure JavaScript apps. Read on for an explanation of why. But first, this is the risk rating from OWASP: Threat Agents Attack Vectors Security [...]]]></description>
			<content:encoded><![CDATA[<p>How do <a href="https://www.owasp.org/index.php/Top_10_2010-A4">A4 &#8211; Insecure Direct Object References</a> apply to Javascript? Well, it all depends on how the system was formed, but this is very likely to become a problem in pure JavaScript apps. Read on for an explanation of why.</p>
<p>But first, this is the risk rating from OWASP: </p>
<table style="font-size: 90%;margin: 1em;border: 1px solid #DDD">
<tbody>
<tr>
<th width="16.5%"> Threat Agents</th>
<th width="16.5%"> Attack Vectors</th>
<th colspan="2" width="33%"> Security Weakness</th>
<th width="16.5%"> Technical Impacts</th>
<th width="16.5%"> Business Impacts</th>
</tr>
<tr>
<td> ______</td>
<td><b>Exploitability<br />EASY</b></td>
<td><b>Prevalence<br />COMMON</b></td>
<td><b>Detectability<br />EASY</b></td>
<td><b>Impact<br />MODERATE</b></td>
<td>______</td>
</tr>
<tr valign="top">
<td>Consider the types of users of your system. Do any users have only partial access to certain types of system data?</td>
<td>Attacker, who is an authorized system user, simply changes a parameter value that directly refers to a system object to another object the user isn&#8217;t authorized for. Is access granted?</td>
<td colspan="2">Applications frequently use the actual name or key of an object when generating web pages. Applications don&#8217;t always verify the user is authorized for the target object. This results in an insecure direct object reference flaw. Testers can easily manipulate parameter values to detect such flaws and code analysis quickly shows whether authorization is properly verified.</td>
<td>Such flaws can compromise all the data that can be referenced by the parameter. Unless the name space is sparse, it&#8217;s easy for an attacker to access all available data of that type.</td>
<td>Consider the business value of the exposed data.</p>
<p>Also consider the business impact of public exposure of the vulnerability.</td>
</tr>
</tbody>
</table>
<h3>The anatomy of a typical single page app</h3>
<p>A single page web application &#8211; and especially those built using backbone.js &#8211; tend to have be composed of a single base HTML page (this single page), a set of javascript models, routers and views, a set of templates for the views and a set of server side services providing data. The service side services will typically be REST based and deliver JSON.</p>
<p>If both the client side and server side is implemented using JavaScript, we can imagine having the same data representation on both the server side and client side. It will be the same data object, serialized as JSON when being transferred between browser and server. On the client side, a framework like backbone.js will wrap the data object inside a model augmenting it with functionality. The same thing may or may not be done on the server side.</p>
<p>If the server side is also using a document oriented NoSQL-database, we can even imagine having the same data model stored in the data store. No need for grumpy old ORM-frameworks to transfer data back and forth from one model to the other.</p>
<p>While having the same model in every part of the application has obvious positive sides like simplification and consistency, it also introduces problems, especially if we don&#8217;t take care how we implement our server side services.</p>
<p>Consider an application for Call for Papers for a conference. The application accepts suggestions from registered users, and organizers (admins) can approve talks. In fact I created such a system for demonstrating the kind of problem I&#8217;m about to explain and you can <a href="https://github.com/eoftedal/WebRebels2012/tree/master/railsapp">find it on Github</a>. A typical talk suggestion could look something like this:</p>
<pre style="font-family: monospace">{
	"id"		: 1,
	"title"		: "funnybone.vbs",
	"description"	: "A backbone.js implementation in vbscript"
}</pre>
<h3>Classical Insecure Direct Object References</h3>
<p>The classic problem occurs because the server side fails to check the users access to the object he/she is editing. So in the Call for Papers app, what happens if on speaker tries to alter another speakers talk? While this may not be possible to due to access control checks in the client side javascript, there is nothing stopping a determined attacker from simply changing the code from the javascript console in order to have his/her way. So while having these controls in place is a good thing from a usability perspective, we also need to implement access control on the server side. These kinds of attack have earlier been performed on photo sites (I think there was even one in Facebook) and even online backing applications where one user could access other user&#8217;s accounts. The most famous of the recent ones, is probably <a href="http://www.smh.com.au/it-pro/security-it/super-bad-first-state-set-police-on-man-who-showed-them-how--770000-accounts-could-be-ripped-off-20111018-1lvx1.html">Patrick Webster&#8217;s disclosure to First State Super Annuation</a> where he demonstrated a problem in their website allowing him to download other peoples&#8217; documents. </p>
<h3>Mass assignment/overposting</h3>
<p>We forgot about something in the model above. If admins should be allowed to approve talks, we probably need some fields for that too. So lets go ahead and add that:</p>
<pre style="font-family: monospace">{
	"id"		: 1,
	"title"		: "funnybone.vbs",
	"description"	: "A backbone.js implementation in vbscript",
	"approved"	: false
}</pre>
<p>While having this field on the client side is good as it allows us to display which talks have been approved and not, it also creates a potential security issue. If a speaker is able to update a talk, what will stop that speaker from also updating the <code>approved</code> field. A malicious speaker could do this even if this fields has no corresponding UI element.<img src="http://eoftedal.github.com/WebRebels2012/presentation/images/egor.png" style="float: right;margin: 10px 0px 10px 10px"> He could simply add that element in firebug, or modify the JSON using an interception proxy (like OWASP Zap) on its way back to the client. The attacker could even add fields that are not present in the JSON, but which the attacker assumes are available in the database. He could try to add a <code>role</code> field when creating or updating his user account. Or modifying timestamps <a href="http://chrisacky.posterous.com/github-you-have-let-us-all-down">like Egor Homakov demonstrated on Github</a>(see image on the right). This is often referred to as mass assignment or overposting, and is not only a problem in javascript based application. It&#8217;s a weakness in how data is mapped to objects on the server side.</p>
<p>It&#8217;s obvious that in order to stop the above mentioned speaker from approving his own talk, we can not use client side code. This needs to be fixed on the server side. The server needs to know which fields it should support updates for given the current user role.</p>
<h3>Schema injection</h3>
<p>There is another problem that can also occur if the server side does not filter the incoming JSON. If the JSON is simply converted to a client side object containing exact same fields, and then those fields are dumped into a document database or key value store, what happens if the attacker add 1000 new fields? Or 1 million new fields? Now we suddenly have a simple object for a talk, taking several MBs or even GBs of disk space/memory. As the name implies this problem might as well have been mentioned under A1 &#8211; Injection, but seemed a better fit here.</p>
<h3>Mitigation</h3>
<ul>
<li>Perform server side access control</li>
<li>Perform server side filtering of received data and rejected unwanted parts</li>
</ul>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/LhFBL-DxXFA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/owasp-top-10-for-javascript-a4-insecure-direct-object-references/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/owasp-top-10-for-javascript-a4-insecure-direct-object-references/</feedburner:origLink></item>
		<item>
		<title>OWASP Top 10 for JavaScript – A3: Broken Authentication and Session Management</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/tW0FdcilHec/</link>
		<comments>http://open.bekk.no/owasp-top-10-for-javascript-a3-broken-authentication-and-session-management/#comments</comments>
		<pubDate>Fri, 15 Jun 2012 15:52:47 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[BEKK]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=9047</guid>
		<description><![CDATA[In this post I&#8217;ll describe how OWASP Top 10: A3 &#8211; Broken Authentication and Session Management applies to javascript based applications. Problems around broken authentication and session management can happen for a number of reasons. The end result is the same. The attacker is somehow able to log in as another user, and get hold [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I&#8217;ll describe how <a href="https://www.owasp.org/index.php/Top_10_2010-A3">OWASP Top 10: A3 &#8211; Broken Authentication and Session Management</a> applies to javascript based applications. Problems around broken authentication and session management can happen for a number of reasons. The end result is the same. The attacker is somehow able to log in as another user, and get hold of content which the user should not have access too.</p>
<p>This is the risk rating from OWASP:</p>
<table style="font-size: 90%;margin: 1em;border: 1px solid #DDD">
<tbody>
<tr>
<th width="16.5%"> Threat Agents</th>
<th width="16.5%"> Attack Vectors</th>
<th colspan="2" width="33%"> Security Weakness</th>
<th width="16.5%"> Technical Impacts</th>
<th width="16.5%"> Business Impacts</th>
</tr>
<tr>
<td> ______</td>
<td><b>Exploitability<br />AVERAGE</b></td>
<td><b>Prevalence<br />COMMON</b></td>
<td><b>Detectability<br />AVERAGE</b></td>
<td><b>Impact<br />SEVERE</b></td>
<td>______</td>
</tr>
<tr valign="top">
<td>Consider anonymous external attackers, as well as users with their own accounts, who may attempt to steal accounts from others. Also consider insiders wanting to disguise their actions.</td>
<td>Attacker uses leaks or flaws in the authentication or session management functions (e.g., exposed accounts, passwords, session IDs) to impersonate users.</td>
<td colspan="2">Developers frequently build custom authentication and session management schemes, but building these correctly is hard. As a result, these custom schemes frequently have flaws in areas such as logout, password management, timeouts, remember me, secret question, account update, etc. Finding such flaws can sometimes be difficult, as each implementation is unique.</td>
<td>Such flaws may allow some or even all accounts to be attacked. Once successful, the attacker can do anything the victim could do. Privileged accounts are frequently targeted.</td>
<td>Consider the business value of the affected data or application functions.</p>
<p>Also consider the business impact of public exposure of the vulnerability.</td>
</tr>
</tbody>
</table>
<h2>Session fixation</h2>
<p>Session fixation is an attack where the attacker is able to somehow preset the session id of antoher user. When that user logs in the attacker already has the valid session id and can use that to log in. Typically this is happening in applications that make the session ID a part of the URL:<br />
<code>http://examples.com/;JSESSIONID=12312312312312321</code><br />
This is a bad pattern. SessionIDs should never be a part of URLs. Furthermore it&#8217;s important to always change the session ID when the authentication/autorization level is changing &#8211; typically during login/logout.</p>
<p>For javascript based web apps this typically means checking to see how the server based session components handle sessions. So typically you will want to check that whatever session framework and authentication framework you use, they should replace the sessions upon login and should not accept session IDs in URLs.</p>
<h2>Session stealing</h2>
<p>If the attacker steals the session of another user, the attacker can now access whatever the user has access to, because from the server side the two is the same. There are typically two ways of stealing sessions:</p>
<ul>
<li>Sniffing and open wireless network</li>
<li>Cross Site Scripting</li>
</ul>
<p>A few years back lots of websites like twitter and Facebook would only protect the login with https when the username and password was transferred. After the login, the connection would go back to http. This is a bad pattern. After login the session ID becomes a temporary replacement for your username and password, and thus we want to protect from anyone listening in. To achieve this we can make sure the browser never sends our session cookie over http, but setting the <code>Secure</code> flag on the cookie. This will instruct the browser never to send the cookie in http requests.</p>
<p>The next thing we need to do is to protect the application from Cross Site Scripting as explained in <a href="?blogid=127">A2 &#8211; Cross Site Scripting</a>. If an attacker can insert script into our page, the attacker could access <code>document.cookie</code> and steal the session cookie from there. A secondary protection mechanism we can use there, is to set the HttpOnly flag on the session cookie. This will instruct the browser not to make the session cookie available to javascript through <code>docment.cookie</code>. The browser will still send it in requests back to the server, but it will just not be available directly in JS.</p>
<h2>Session guessing</h2>
<p>It&#8217;s of key importance that the server side component generating session IDs is using a cryptographically secure random function to do so. If the attacker is able to predetermine what the next session id is, the attacker could simply try different session IDs, and would at some point find a valid authenticated session, because a user logged in and got that very same session ID. I recently tested Node.js <a href="http://www.senchalabs.org/connect/">Connect</a>&#8216;s session ID generation using <a href="http://portswigger.net/burp/">Burp Suite</a>&#8216;s sequencer, and Connect seems to do a decent job (the rating from Burp Suite was: Excellent).</p>
<h2>Session timeout</h2>
<p>Sessions should always time out after a certain period of time. Some sites use a sliding expiration, where the user is logged out if the user with the active session has been inactive for some time. Other sites use an absolute expiration, where the login is valid for a maximum of say 30 minutes. For high value sites like online banking it&#8217;s probably a good idea to use both a sliding and absolute timeout. The rationale behind session timeout, is the fact that a session should be a temporary replacement for the username and password, not a permanent one. There are a couple of reasons why this is important.</p>
<p>If the user leaves his device or computer unattended for some time, a time out will make it harder for any attacker stealing the device to reuse the existing sessions. This can of course be partially mitigated by automatically locking the device or computer after a given period of inactivity, but this will not stop a determined attacker.</p>
<p>The second reason is if the session is somehow stolen, not having an absolute expiration, will allow the attacker to use that session as long as he wants &#8211; or at least until the user logs out (which many users rarely do).</p>
<h2>Client side only sessions</h2>
<p>Some frameworks promote client side only sessions. The way this works is that the user will log in on the server side, the server will issue a cookie which holds the session data, and send that back to the client. The benefit is of course that the javascript on the client side is now able to see and use the data in the cookie. It also frees up resources on the server, which no longer needs to maintain copies of all sessions. In a clustered backend, there is also no need to synchronize the session, as it&#8217;s now being sent on every request.</p>
<p>However in my opinion the drawbacks outweigh the positive aspects. First of all we need to make sure the client side code cannot change the session data, because the server now inherently has to trust this cookie in later decisions. This could easily lead to a broken authentication scenario, where the user logs in as user &#8220;joesmith&#8221; and then changes the username in session to be &#8220;admin&#8221;. What this means, is that the cookie needs to be signed by the server and only the server should be allowed to change it. And this can be a bit hard to get right. Naive approaches of using something like <code>MD5(secret key + data)</code> has been proven susceptible to length extensions attacks. Typically the developer should use something like HMAC. And we have to make sure to check the signature on the server side on each and every request to the server.</p>
<p>The next problem is the ability to have the session timeout. A naive approach of setting a timeout for the cookies is of course insufficient. This timeout can easily be increased by the attacker. So the timeout timestamp needs to live inside the signed session data, and be checked on the server side for each and every request.</p>
<p>As described under session stealing, we usually want to set the HttpOnly flag in order to protect are sessions from being stolen from javascript. This of course will not work if we also want to have benign access to that data from the client side code.</p>
<p>The biggest problem is however that there really is <em>no way to log a user out</em>. If the server side has no concept of which sessions exist, neither can it mark one as logged out. If the attacker is at some point able to steal a valid session, that session is valid in itself because of the signature, and thus the server will happily accept it until it expires. So a logout would typically mean deleting the cookie on the client side, and that&#8217;s of course not sufficient if anyone else has a copy.</p>
<p>The last problem with client side sessions in cookies is that there is a limit on the size of the session. If you put too much data there, the server will no longer be able to respond, because the header size limit is exceeded. From javascript that means every request will result in an error and there is nothing the server can do to help the client fix the problem.</li>
<h2>Session logout</h2>
<p>In addition to the logout problem mentioned in the previous section, there are other logout related problems as well. Simply deleting the session cookie on the server side is not sufficient. The session should always be terminated on the server side.</p>
<p>Also HTML5 allows us to store more data on the client side in the Web Storage. This can greatly improve performance, but can also lead to some problems. First of all, if I&#8217;m logged in and my private data is stored in Web Storage, what happens to that data when I log out. Will the next user on the same device or computer see my data? Typically the application will use either localStorage or sessionStorage or both. In my opinion localStorage should be used for generic data like compiled JS templates or other things you may want to cache, while sessionStorage could be use for private information. However we will still need to clear out the sessionStorage during logout (and session timeout if possible). The reason is that the sessionStorage is not tied to the authenticated session in any way. SessionStorage simply means it&#8217;s deleted when the browser is shutdown or restarted, which a lot of users never do unless they have to (due to a reboot or browser upgrade).</p>
<h2>Mitigations</h2>
<ul>
<li>Avoid client-side only sessions unless you absolutely have to</li>
<li>Use session timeouts</li>
<li>Protect your sessions from tampering and leaks</li>
<li>Clean up session and affiliated data server side and client side on log out</li>
<li>Use a cryptographically secure random generator for session IDs</li>
<li>Don&#8217;t put and/or accept session IDs in URLs</li>
</ul>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/tW0FdcilHec" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/owasp-top-10-for-javascript-a3-broken-authentication-and-session-management/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/owasp-top-10-for-javascript-a3-broken-authentication-and-session-management/</feedburner:origLink></item>
		<item>
		<title>Why business should care about Continuous Delivery</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/LUOQLTrojxw/</link>
		<comments>http://open.bekk.no/why-business-should-care-about-continuous-delivery/#comments</comments>
		<pubDate>Mon, 11 Jun 2012 10:43:20 +0000</pubDate>
		<dc:creator>Sveinung Dalatun</dc:creator>
				<category><![CDATA[Kvalitet og testing]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[kontinuerlige leveranser]]></category>
		<category><![CDATA[kvalitet]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=9006</guid>
		<description><![CDATA[At its core, Continuous Delivery is about delivering features to customers as soon as they are ready. This rapid delivery has several benefits for both business and development. First and foremost it lets us adapt continuously and rapidly to customer feedback and changes in the market—it enables us to gain insights from real usage. As a result we have a better basis for knowing if we are building the right product.]]></description>
			<content:encoded><![CDATA[<p>At its core, Continuous Delivery is about delivering features to customers as soon as they are ready. This rapid delivery has several benefits for both business and development. First and foremost it lets us adapt continuously and rapidly to customer feedback and changes in the market—it enables us to gain insights from real usage. As a result we have a better basis for knowing if we are building the right product.</p>
<p>A lot have been said and written about the technical aspects of continuous delivery—why it reduces overhead for development by automating everything that can be automated. This blog post, however, will focus on three core <em>business</em> aspects of delivering continuously.</p>
<h2>Smaller deltas of change means lower risk</h2>
<p>We call the amount of changes between two deploys the <em>delta of change</em>. Reducing this delta means that less can go wrong when a new version is deployed. Why? Both from a technical and business perspective it is far easier to pinpoint the problem when there are less changes in the product. By delivering fewer changes at a time we can be more certain that we are actually delivering the <em>right thing</em>.</p>
<p>When releasing fewer changes it is also easier for business to understand the impact of each additional change. This enable us to learn more about customers and not waste money building features that don&#039;t add value.</p>
<p>Also, fewer changes means that we can deploy more often. And deploying more often means shorter feedback loops. And shorter feedback loops means we will learn more about customers.</p>
<h2>Shorter feedback loops</h2>
<p>There is a feedback loop between the team developing the product and the customers using it: The development and delivery of the product, the customers usage of it, the interpretation of this usage, and the final decision regarding possible changes to the product and the strategy. Delivering continuously shortens the feedback loop, which enables us to learn more—and more rapidly—about our customers and making the correct decisions faster.</p>
<p>The developers of a product often have several layers between them and the customer. Smaller code changes delivered often means shorter feedback loops, which will increase the developers understanding of what the customer wants. This improvement can lead to improved decisions and technical innovations that are more aligned with what the user needs. The more you know your customers, the easier it is to build the right thing.</p>
<h2>Increased responsiveness</h2>
<p>By continuously delivering small changes rapidly you can be more responsive with regards to customers, the market, and your competitors. Increased responsiveness means that you are able to adapt faster to customer needs and market changes. For example, the faster you are able to deliver on a customer request the happier and more satisfied the customer will be.</p>
<p>Why keep a feature that is already developed and ready for production just lay around waiting to be deployed in a year? Or for that matter, in a month or a week? A feature only adds value after being delivered to the customers, if not it&#039;s only <em>inventory waste</em>.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/LUOQLTrojxw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/why-business-should-care-about-continuous-delivery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/why-business-should-care-about-continuous-delivery/</feedburner:origLink></item>
		<item>
		<title>Emotional design spreads like wildfire</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/A_Otzl-cBAA/</link>
		<comments>http://open.bekk.no/emotional-design-spreads-like-wildfire/#comments</comments>
		<pubDate>Sat, 09 Jun 2012 10:04:04 +0000</pubDate>
		<dc:creator>Lillian Ayla Ersoy</dc:creator>
				<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8966</guid>
		<description><![CDATA[For years now we have built systems and web pages from the bottom up, never asking what is important for the people that use these applications. The solution involved a reliable and functional system, but pleasure and enjoyment was never apart of this equation. The world has changed and we are trying to reform the [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-8983" title="People_concert" src="http://open.bekk.no/wp-content/uploads/2012/06/People_concert2.jpg" alt="" width="750" height="255" /></p>
<p>For years now we have built systems and web pages from the <span style="color: #000000;">bottom up</span>, never asking what is important for the people that use these applications. The solution involved a reliable and functional system, but pleasure and enjoyment was never apart of this equation.</p>
<p>The world has changed and we are trying to reform the prior world of systematic digital solutions. Emotional and well-designed solutions are the success factors in order to gain a leading market share in your industry or to just be the best at what you do.</p>
<h3>Take banking for example</h3>
<p>In the past, banks used a huge chunk of money to hire the right people and open ¨shops¨ in several places. They provided personal service to there clients with physical contact and warm faces. So what happened to the online bank?</p>
<blockquote><p>What happened to creating an online welcoming place where people enjoy there banking experience and receive personal attention?</p></blockquote>
<p>The traditional way of designing an online bank was to make the services accessible online without thinking about the user experience. This translated into getting the system up as fast as possible. It should be secure and functional. There was zero interest in making this system enjoyable.</p>
<h3>Times have changed</h3>
<p>There are many factors involved when people choose their bank. Good rates, low costs and local offices have been some of the major influential factors. However the visual identity and online/mobile experience is a growing factor that people care about. When customers see that there product or service cares about them, they react. They show loyalty. Apple and Starbucks are great examples that have created a visual and emotional connection to there clients where <span style="color: #000000;">every detail counts.</span></p>
<h3>So how do we get there</h3>
<p>A good design and technical team is essential. We are not talking about one Interaction Designer that makes some wireframes and then passes it on to the programmers.</p>
<blockquote><p>We are talking about a team that builds off each other and works closely with the client and organization. This team consists of at least one Interaction Designer, a Graphic Designer, one or several Programmers and a Copywriter.</p></blockquote>
<p>The innovation happens when this team works closely together with the client and are given the freedom to transform an existing product into what it should be.  The interaction designer works with the emotional and user experience aspects. The graphic designer makes the product visually appealing. The programmers work closey with the designers and discuss alternative solutions to the problem. The copywriter creates meaningful and personal communication that shapes the user experience.</p>
<h3>The wildfire effect</h3>
<p>This is a phenomenon that happens when the client sees change. They suddenly see how their products can be and become proud owners of innovation and design. Pride and happiness spreads like wildfire in an organization. They start to understand the importance of good design and creating digital emotional experiences for their customers.</p>
<p>Online services become the new form for advertising. If your product or service is that good, then word of mouth is your number one source for gaining new customers. The amount of money that was invested in your product has now created a return on investment and the amount of money needed in advertising is reduced.</p>
<blockquote><p>Good things happen when we are able to turn a systematic rigid application into a welcoming and delightful user experience. It all starts when we switch our focus to the people using the product and create a<a href="http://blog.beacontechnologies.com/tag/emotional-power-of-design/" target="_blank"><br />
top-down strategy</a> where design and communication are equally important as technical functionality.</p></blockquote>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/A_Otzl-cBAA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/emotional-design-spreads-like-wildfire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/emotional-design-spreads-like-wildfire/</feedburner:origLink></item>
		<item>
		<title>OWASP Top 10 for JavaScript – A2: Cross Site Scripting – XSS</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/y6Sel8YF0OM/</link>
		<comments>http://open.bekk.no/owasp-top-10-for-javascript-a2-cross-site-scripting-xss/#comments</comments>
		<pubDate>Thu, 31 May 2012 06:38:36 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[Sikkerhet]]></category>
		<category><![CDATA[owasp]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8951</guid>
		<description><![CDATA[Cross site Scripting - or XSS - is probably one of the most common and one of the most difficult problems to fully mitigate. At first it seems simple, but as contexts grow in complexity and the amount of code grows, it get's harder to discover all the different sinks.]]></description>
			<content:encoded><![CDATA[<p>Cross site Scripting &#8211; or XSS &#8211; is probably one of the most common and one of the most difficult problems to fully mitigate. At first it seems simple, but as contexts grow in complexity and the amount of code grows, it get&#8217;s harder to discover all the different sinks.</p>
<p>This is the risk rating from OWASP:</p>
<table style="font-size: 90%;margin: 1em;border: 1px solid #DDD">
<tbody>
<tr>
<th width="16.5%"> Threat Agents</th>
<th width="16.5%"> Attack Vectors</th>
<th colspan="2" width="33%"> Security Weakness</th>
<th width="16.5%"> Technical Impacts</th>
<th width="16.5%"> Business Impacts</th>
</tr>
<tr>
<td> ______</td>
<td><b>Exploitability<br />AVERAGE</b></td>
<td><b>Prevalence<br />VERY WIDESPREAD</b></td>
<td><b>Detectability<br />EASY</b></td>
<td><b>Impact<br />MODERATE</b></td>
<td>______</td>
</tr>
<tr valign="top">
<td>Consider anyone who can send untrusted data to the system, including external users, internal users, and administrators.</td>
<td>Attacker sends text-based attack scripts that exploit the interpreter in the browser. Almost any source of data can be an attack vector, including internal sources such as data from the database.</td>
<td colspan="2"><a href="/index.php/Cross-site_Scripting_%28XSS%29" title="Cross-site Scripting (XSS)"> XSS</a> is the most prevalent web application security flaw. XSS flaws occur when an application includes user supplied data in a page sent to the browser without properly validating or escaping that content. There are three known types of XSS flaws: 1) <a href="https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29#Stored_XSS_Attacks" title="Cross-site Scripting (XSS)"> Stored</a>, 2) <a href="https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29#Reflected_XSS_Attacks" title="Cross-site Scripting (XSS)"> Reflected</a>, and 3) <a href="https://www.owasp.org/index.php/DOM_Based_XSS" title="DOM Based XSS"> DOM based XSS</a>.</p>
<p>Detection of most XSS flaws is fairly easy via testing or code analysis.</td>
<td>Attackers can execute scripts in a victim’s browser to hijack user sessions, deface web sites, insert hostile content, redirect users, hijack the user’s browser using malware, etc.</td>
<td>Consider the business value of the affected system and all the data it processes.</p>
<p>Also consider the business impact of public exposure of the vulnerability.</td>
</tr>
</tbody>
</table>
<h2>Traditional XSS</h3>
<p>We traditionally talk about two types of XSS &#8211; reflected and stored. In reflected XSS, the attack is a part of the URL like this one:<br />
<code>http://www.insecurelabs.org/Search.aspx?query="&gt;&lt;script&gt;alert(1)&lt;/script&gt;</code><br />
You can test that one <a>here</a>. In reflected XSS, the attacker has to trick the user into opening the URL somehow &#8211; typically by employing iframes, phishing or shortened URLs.</p>
<p>In stored, or persistent, XSS, the attacker is able to store the attack string in the database. Since the attack is not dependent on the exact URL being visited anymore, the attacker can simply wait for a victim to visit the otherwise legit page. An example could be the commenting section here: <a href="http://www.insecurelabs.org/Talk/Details/5">http://www.insecurelabs.org/Talk/Details/5</a>.</p>
<h2>Twists on traditional XSS</h2>
<p>Single page webapps are usually loading a static HTML-layout, which is the exact same file for all users, and then data and private information is loaded using JSON services. If there is HTML-tags inside our JSON-data we would normally expect the browsers not to render this content, but rather treat application/json as, well, JSON. However this is not always the case. Some browser, and especially IE, tends to try to second guess the content-type given by the server. This is called content-sniffing, and is in place because at some point in time servers tended not to send the correct content-type, and thus browsers could help the developers and end user by checking &#8220;what the content <em>really</em> was&#8221;.</p>
<p>I built a small <a href="http://erlend.oftedal.no/blog/research/json/testbench.html">test bed</a> for showing how this works. You will see a green check if the browser treats the content as HTML (and thus allows scripting). It is expected that this happens if we return the JSON with Content-Type text/html, but not with any of the others. Well maybe an empty Content-Type could be excused, but if the browser says application/json, the browser should definitely not treat the contents as HTML.</p>
<h2>DOM-based XSS</h2>
<p>It&#8217;s expected that DOM-based XSS will be more commons in apps reying heavily on JavaScript, than what has been seen in traditional apps. DOM-based XSS occurs because user input is unsafely handled in javascript running on the page. We will address a few examples on this type of XSS. Some of these attacks never reach the server side, and thus cannot be detected by server side code.</p>
<h3>Insecure writes</h3>
<p>Insecure writes happens when user input is written to the DOM without first being sanitized. Data can come in through user input in the browser, or it can be loaded through JSON from the server (which would mean it was a stored DOM-based XSS attack). Insecure writes means we are either outputting the data directly in the DOM using <code>.innerHTML</code> or through unsafe jQuery functions like:</p>
<ul class="twocolumn" style="font-family: monospace">
<li>$.after()</li>
<li>$.append()</li>
<li>$.appendTo()</li>
<li>$.before()</li>
<li>$.html()</li>
<li>$.insertAfter()</li>
<li>$.insertBefore()</li>
<li>$.prepend()</li>
<li>$.prependTo()</li>
<li>$.replaceAll()</li>
<li>$.replaceWith()</li>
<li>$.unwrap()</li>
<li>$.wrap()</li>
<li>$.wrapAll()</li>
<li>$.wrapInner()</li>
<li>$.prepend()</li>
</ul>
<h3>Insecure code execution</h3>
<p>As mentioned in <a href="http://open.bekk.no/owasp-top-10-for-javascript-a1-injection/">A1 &#8211; Injection</a> the use of insecure functions in JavaScript can cause insecure code execution. More specifically this means using functions that build JavaScript from strings:</p>
<ul style="font-family: monospace">
<li>eval(string)</li>
<li>new Function(string)</li>
<li>setTimeout(string, time)</li>
<li>setInterval(string, time)</li>
</ul>
<p>In addition to these we find API specific functions like <code>$.globalEval(string)</code>. As we can easily imagine dynamically building code containing user input is probably not a good idea, and is very likely to lead to problems down the road. JSHint, which is a common tool for quality checks on JavaScript, agrees: <q>eval is evil</q>.</p>
<h3>Insecure use of APIs</h3>
<p>Insecure use of jQuery can also lead to unexpected XSS. As mentioned in <a href="http://ma.la/jquery_xss/">jQuery XSS</a> something as simple as this can lead to XSS:<br />
<code>$(location.hash)</code><br />
This can be exploited with:<br />
<code>http://example.com/some/page#&lt;img src=insecure onerror=alert(1)&gt;</code>
</p>
<p>The next one is a bit more subtle (courtesy of <a href="http://sec.omar.li/2012/05/overview-of-dom-xss.html">An overview of DOM XSS</a>):</p>
<pre>hash = location.hash.substring(1);
if (!$('a&#091;name|="' + hash + '"&#093;')[0]) {
    // not important
}
</pre>
<p>An input of <code>"] &lt;img src=insecure onerror=alert(1)&gt;</code> would actually work here.
</p>
<p>While the examples above jQuery specific, it is very likely that there are similar problems in other frameworks.</p>
<h3>Insecure use of document.location</h3>
<p>Allowing user input to be directly assigned to <code>document.location</code>, can easily lead to XSS in the form of <code>javascript:</code> URLs. The following example is from twitter back in september 2010 (I <em>highly</em> recommend you read the full blog post here: <a href="http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html">Minded Security Blog: A Twitter DomXss, a wrong fix and something more</a>):<br />
<code>(function(g){var a=location.href.split("#!")[1];if(a){g.location=g.HBR=a;}})(window);</code><br />
The code above, extracts whatever comes after <code>#!</code> in the url, and asigns it to <code>window.location</code>. The intention was to allow a url of <code>http://twitter.com/#!/webtonull</code> to be redirected to <code>http://twitter.com/webtonull</code>. However consider the following url:<br />
<code>http://twitter.com/#!javascript:alert(1)</code>
</p>
<h3>Persistent client side XSS</h3>
<p>If the XSS vector is persisted in Web Storage, and later rendered in an insecure way, we call it a persistent client side XSS. As the name implies this attack will never reach the server, but still trigger every time the vulnerable page is loaded in the given browser.</p>
<h2>XSS when using templates</h2>
<p>Templating from frameworks like Mustache.js and <a href="http://underscorejs.org/">underscore.js</a> etc. allow javascript frameworks to clearly seperate view from data. They normally provide a set of tags for allowing coding and data output. The set from underscore.js looks like:</p>
<ul>
<li><code>&lt;% %&gt;</code> &#8211; view logic (JavaScript code)</li>
<li><code>&lt;%= %&gt;</code> &#8211; data output (no escaping)</li>
<li><code>&lt;%- %&gt;</code> &#8211; data output (HTML escaping)</li>
</ul>
<p>The HTML escaping escapes <code>&amp;, &lt;, &gt;, ", '</code> and <code>/</code>. I don&#8217;t intend to pick on underscore.js. This is one of the better escaping functions I&#8217;ve seen. But we need to remember to use the HTML escaping tag. And there are contexts where this will not work, simply because HTML escaping is not the correct escaping.
</p>
<p><b>Quoteless HTML attributes</b><br />
Template code:<br />
<code>&lt;img title=&lt;%- title %&gt; ...&gt;</code><br />
Attack:<br />
<code>&lt;img title=<span class="error">something onclick=alert(1)</span> ...&gt;</code>
</p>
<p><b>HTML comments</b> &#8211; courtesy of <a href="http://html5sec.org/#133">http://html5sec.org/#133</a><br />
Template code:<br />
<code>&lt;!-- &lt;%- title %&gt; --&gt;</code><br />
Attack:<br />
<code>&lt;!-- <span class="error">` I'm now outside the comment in IE6-8</span> --&gt;</code>
</p>
<p><b>Inside script tags</b>, but you are not using those in a javascript app, right?<br />
Template code:<br />
<code>&lt;script&gt;<br />
var id = &lt;%- id %&gt;<br />
&lt;/script&gt;</code><br />
Attack:<br />
<code>&lt;script&gt;<br />
var id = <span class="error">1;alert(/XSS/.source)</span>;<br />
&lt;/script&gt;</code>
</p>
<p><b>Inside javascript event handlers</b>, but you are not using those in a javascript app, right?<br />
Template code:<br />
<code>&lt;img onmouseover="showToolTip('&lt;%- title %&gt;')" ...&gt;</code><br />
Attack:<br />
<code>&lt;img onmouseover="showToolTip('<span class="error">&amp;<span>#039;</span>);alert(&amp;<span>#039;</span>XSS</span>')" ...&gt;</code>
</p>
<p><b>Insecure use of URLs</b><br />
Template code:<br />
<code>&lt;a href="&lt;%- url %&gt;" ...&gt;</code><br />
Attack:<br />
<code>&lt;a href="<span class="error">javascript:alert(1)</span>" ...&gt;</code>
</p>
<p>The above list is not complete. There are a lot more weird contexts. See <a href="http://html5sec.org/">http://html5sec.org/</a> and the OWASP cheat sheets listed below.</p>
<h2>Third-party javascript</h2>
<p>When you are adding direct links to third-party javascript files, instead of putting the files locally on your server, you have to remember that you are now allowing XSS from the domain hosting that file. That&#8217;s regardless of whether you are loading a javascript library or &#8220;just&#8221; using JSONP to load data. Consider a <code>script</code> tag like this:<br />
<code>&lt;script src="http://example.com/example.js"&gt;&lt;/script&gt;</code><br />
Now if example.com goes rougue or is hacked, example.js could start delivering malware to your users or silently stealing their credentials when they log in.
</p>
<p>Another thing to consider any security vulnerabilities in downloaded libraries. When you are pulling in some third party script, you should also make sure you later stay up to date, and follow any announcements from the developers of that library.</p>
<h2>Mitigation</h2>
<ul>
<li><b>Default to secure methods</b> &#8211; use <code>$.text()</code> instead of <code>$.html()</code></li>
<li><b>Default to escaping output</b> &#8211; use <code>&lt;%- %&gt;</code> instead of <code>&lt;%= %&gt;</code></li>
<li><b>Check your templating framework&#8217;s escaping code</b> &#8211; is it as thorough as underscore.js or does it escape fewer characters?</li>
<li><b>Prefer frameworks with secure defaults</b></li>
<li><b>Set the correct Content-Types and use proper JSON escaping</b></li>
<li><b>Beware of XSS contexts</b> &#8211; make sure you are not using the wrong/insufficient escaping for the contexts</li>
<li><b>Avoid sticking user data in insecure functions like <code>eval</code></b></li>
<li><b>Beware when using user data with APIs like jQuery</b> &#8211; test it</li>
<li><b>Use automated tests with XSS attacks</b> &#8211; test your code and templates using automated javascript tests and bad data</li>
<li><b>Read and learn the OWASP XSS cheat sheets by heart</b></li>
<li><b>Use <a href="https://github.com/chrisisbeef/jquery-encoder">jQuery encoder</a> for complex contexts</b></li>
</ul>
<h2>Resources</h2>
<ul>
<li><a href="https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet">OWASP XSS Prevention Cheat Sheet</a></li>
<li><a href="https://www.owasp.org/index.php/Abridged_XSS_Prevention_Cheat_Sheet">OWASP Abridged XSS Prevention Cheat Sheet</a></li>
<li><a href="https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet">OWASP DOM-Based XSS Prevention Cheat Sheet</a></li>
<li><a href="http://sec.omar.li/2012/05/overview-of-dom-xss.html">An overview of DOM XSS</a></li>
<li><a href="http://ma.la/jquery_xss/">jQuery XSS</a></li>
<li><a href="http://html5sec.org/">HTML5 Security Cheatsheet</a></li>
<li><a href="https://github.com/chrisisbeef/jquery-encoder">jQuery encoder</a></li>
</ul>
<h2>Missing anything?</h2>
<p>Contact me on <a href="http://twitter.com/webtonull">twitter</a> or add a comment below, and I&#8217;ll be happy to add (with attribution).</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/y6Sel8YF0OM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/owasp-top-10-for-javascript-a2-cross-site-scripting-xss/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/owasp-top-10-for-javascript-a2-cross-site-scripting-xss/</feedburner:origLink></item>
		<item>
		<title>OWASP Top 10 for JavaScript – A1: Injection</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/g12XkcikxWo/</link>
		<comments>http://open.bekk.no/owasp-top-10-for-javascript-a1-injection/#comments</comments>
		<pubDate>Tue, 29 May 2012 21:03:28 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Sikkerhet]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[owasp]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8936</guid>
		<description><![CDATA[Injection problems usually occur whenever unsanitized user data is concatenated with a static template to build a structure (typically a query of some kind).]]></description>
			<content:encoded><![CDATA[<p>Injection problems usually occur whenever unsanitized user data is concatenated with a static template to build a structure (typically a query of some kind).</p>
<p>This is the risk rating from OWASP:</p>
<table>
<tbody>
<tr>
<th width="16.5%"> Threat Agents</th>
<th width="16.5%"> Attack Vectors</th>
<th colspan="2" width="33%"> Security Weakness</th>
<th width="16.5%"> Technical Impacts</th>
<th width="16.5%"> Business Impacts</th>
</tr>
<tr>
<td> ______</td>
<td><b>Exploitability<br />EASY</b></td>
<td><b>Prevalence<br />COMMON</b></td>
<td><b>Detectability<br />AVERAGE</b></td>
<td><b>Impact<br />SEVERE</b></td>
<td>______</td>
</tr>
<tr valign="top">
<td>Consider anyone who can send untrusted data to the system, including external users, internal users, and administrators.</td>
<td>Attacker sends simple text-based attacks that exploit the syntax of the targeted interpreter. Almost any source of data can be an injection vector, including internal sources</td>
<td colspan="2">Injection flaws occur when an application sends untrusted data to an interpreter. Injection flaws are very prevalent, particularly in legacy code, often found in SQL queries, LDAP queries, XPath queries, OS commands, program arguments, etc. Injection flaws are easy to discover when examining code, but more difficult via testing. Scanners and fuzzers can help attackers find them.</td>
<td>Injection can result in data loss or corruption, lack of accountability, or denial of access. Injection can sometimes lead to complete host takeover.</td>
<td>Consider the business value of the affected data and the platform running the interpreter. All data could be stolen, modified, or deleted. Could your reputation be harmed?</td>
</tr>
</tbody>
</table>
<h2>Server side vulnerabilities</h2>
<p>When you are accessing a database of some kind there is always the chance of SQL- or NoSQL-injection. To avoid these problems, we should of course avoid building queries by string concatenation. Look for parameterized alternatives. If you are using node.js with mysql, there you could use client.query() with parameters like:<br />
<code>client.query('SELECT id, user_name FROM user WHERE email=?', [email], ...)</code>
</p>
<p>In javascript based backends there is a far bigger problem than SQL. JSHint tells us that <q>eval is evil</q>, and I tend to agree. Unsafe use of <code>eval</code> &#8211; sticking unsanitized user data inside <code>eval</code> statements &#8211; can lead to full compromize of the server.</p>
<p>Bryan Sullivan of Adobe did a talk at Blackhat USA 2011 called <a href="http://www.youtube.com/watch?v=3Vwr24MCCVg">Attacking NoSQL and Node.js: Server-Side JavaScript Injection (SSJS)</a>, and this type of injection is also mentioned in <a href="http://bishankochher.blogspot.com/2011/12/nodejs-security-good-bad-and-ugly.html">Node.JS Security &#8211; the good, bad and ugly</a>.
</p>
<p>Consider a node.js application where the developer makes insecure use of eval to parse incoming JSON:</p>
<pre>var http = require('http');
http.createServer(function (request, response) {
    if (request.method === 'POST') {
	var data = '';
	request.addListener('data', function(chunk) { data += chunk; });
	request.addListener('end', function() {
	  var stockQuery = <span class="error">eval("(" + data + ")")</span>;
	  var price = getStockPrice(stockQuery.symbol);
	  ...
});
</pre>
<p>This leads to full remote code execution on the server. It&#8217;s actually worse than SQL-injection. The attacker could send in code to read out local files:</p>
<pre>var fs = require('fs');
return fs.readFileSync('/etc/passwd');</pre>
</p>
<p>If the attacker is not able to directly read the response, we can also imagine types of <b>blind eval injection</b>. The attacker can send in <code>while(1);</code> and easily overload the server&#8217;s CPU. Alternatively the at could upload files and run them using <code>child_process.spawn</code>, or send code that reads out the entire file system or the database (hello SQL-injection),  and uploads it to a remote location.
</p>
<p>To avoid this problem we should really just avoid sticking user data inside eval statements. At least void using string concatenation. For JSON parsing we sould really stick to <code>JSON.parse()</code>. If we really have to use eval for anything, we could use a syntax like:</p>
<pre>with({username: user.username, email: user.email}) {
   result = eval("doSomething(username, email)");
}
</pre>
<p>Of course in the above example there is no reason to use eval, but you get the point. Access variables instead of using string concatenation.</p>
<p>Typical use of <code>eval</code> involves trying to set dynamic properties or invoke dynamic methods on objects. A typical eval statement thus looks something like:</p>
<pre>eval("user." + propertyName + " = '" + propertyValue +"'"); //Set property with dynamic name
eval("user." + methodName + "()"); // Invoke method dynamically
</pre>
<p>It is really easy to avoid using <code>eval</code> in this example. We can just use array lookups instead.</p>
<pre>
user[propertyName] = propertyValue; //Set property with dynamic name
user[methodName](); // Invoke method dynamically
</pre>
<h2>Client side vulnerabilities</h2>
<p>On the client side, unsafe use of use input can also result in injection issues. We&#8217;ll leave out HTML injection and XSS for now, and cover that in the next post.</p>
<p>JSON injection can happen if JSON is built by string concatenation before being sent to the server:<br />
<code>'{value1:"' + value + '"}'</code><br />
In this case <code>value</code> could escape the quotes and inject new key value pairs:<br />
<code>'{value1:"<span class="error">hello",value2:"world</span>"}'</code>
</p>
<p>Similarly this can happen when building URLs in an unsafe manner:<br />
<code>url: "http://example.com/search/" + searchTerm</code><br />
This could lead to URLs like:<br />
<code>url: "http://example.com/search/<span class="error">../something/evil</span>"</code><br />
Similarily we can have the same problem for URL parameters:<br />
<code>url: "http://example.com/search?q=" + searchTerm</code><br />
which could lead to:<br />
<code>url: "http://example.com/search?q=<span class="error">notmuch&amp;someother=parameter</span>"</code><br />
An example of a bug like this on AOL can be seen in the end of the <a href="http://www.youtube.com/watch?v=f_It469LUFM">DOMinator tutorial video</a> from <a href="http://blog.mindedsecurity.com/2011/05/dominator-project.html">Minded Security</a>.
</p>
<h2>Missing anything?</h2>
<p>Contact me on <a href="http://twitter.com/webtonull">twitter</a> and I&#8217;ll be happy to add (with attribution).</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/g12XkcikxWo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/owasp-top-10-for-javascript-a1-injection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/owasp-top-10-for-javascript-a1-injection/</feedburner:origLink></item>
		<item>
		<title>UX Lx 2012 Conference – Highlights</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/jlSKLrQuiFE/</link>
		<comments>http://open.bekk.no/ux-lx-2012-conference-highlights/#comments</comments>
		<pubDate>Thu, 24 May 2012 11:16:22 +0000</pubDate>
		<dc:creator>Mattias Olovsson</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[Brukertesting]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[konferanse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8805</guid>
		<description><![CDATA[Some lucky interaction designers from BEKK had the chance to visit the UX Lx conference in sunny Lisbon, between May the 16th and the 19th, where UX-people from all over the world met to discuss user experience, participate in workshops and listen to a lot of inspiring talks. There is so much to tell you [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left">Some lucky interaction designers from BEKK had the chance to visit the <a href="http://www.ux-lx.com/" target="_blank">UX Lx conference</a> in sunny Lisbon, between May the 16<sup>th</sup> and the 19<sup>th</sup>, where UX-people from all over the world met to discuss user experience, participate in workshops and listen to a lot of inspiring talks. There is so much to tell you about, but we´ll try to give you a short summary of highlights.</p>
<p style="text-align: center"><a href="http://open.bekk.no/wp-content/uploads/2012/05/people1.jpg"><img class="aligncenter  wp-image-8907" src="http://open.bekk.no/wp-content/uploads/2012/05/people1.jpg" alt="people visiting the conference" width="720" height="316" /></a></p>
<h5 style="text-align: left"><strong>1. Gerry McGovern &#8211; Top Task Management</strong></h5>
<p><em>@gerrymcgovern</em></p>
<p>Irish Gerry McGovern is absolutely clear about one thing: ”Cut content or you´ll kill the user experience”. His speech is convincing and spiced up with British Monty Python-like humour. He describes the web as an organism, which is just eating and eating, meaning adding more and more content, without pooing. Some of the things pushing this behaviour is the counting of content produced, of hits, time spent on a page and so on. This counting sometimes gives a false and damaging impression of a website&#8217;s performance. ”Traffic is how idiots track success”, he says.</p>
<p>His solution is Top Task Management.  All websites are made up of a series of customer tasks and many organizations spend too much time focusing on the tiny tasks, instead of the important ones; the top tasks. In his workshop we learn why the tiny tasks in the &#8220;Long Tail&#8221; get in the way of the top tasks of the &#8220;Long Neck&#8221;—and what to do about it. <a href="http://www.customercarewords.com/webinars/Long-Neck.pptx" target="_blank">Download his presentation</a>.</p>
<p>&nbsp;</p>
<h5><strong>2. Joshua Porter &#8211; Microcopy</strong></h5>
<p><em>@ bokardo</em></p>
<p>In this speech Joshua Porter describes how to use microcopy to reduce interface friction, prevent cognitive blocks and to bring personality to the interface. Using these small, helpful and sometimes encouraging words is a quick way of improving the user experience. If we understand the users mental models, predict what they will ask for and add microcopy, we`ll manage to clear the path for the users.</p>
<p>Joshua gives a number of nice examples and I´ll give you some of them. Add the text ”No credit card needed” to the ”Free Trial”-button, just to make that absolutely clear. Add some humour to an email sign up with this line: ”We hate spam just as much as you” or tell people you`re serious about a survey by saying: ”We promise to read every word”. Adding microcopy is both simple and useful, so why not use it? Have a look at his <a href="http://www.slideshare.net/500startups/joshua-porter-10426310" target="_blank">presentation!</a></p>
<p>&nbsp;</p>
<h5>3. Nate Bolt  &#8211; Remote Research</h5>
<p><em>@boltpeters</em></p>
<p>The history of user testing shows an academic focused and lab-based testing, which sometimes lead to wrong conclusions. Nowadays we have an array of methods and tools for remote research to choose from. We can observe users, through Skype, GotoMeeting or other screen sharing tools with so called <strong>moderated </strong>tests or we could easily automate and scale the test by sending out a survey to a large number of users, using <strong>automated</strong> tools like Usabilla or similar.</p>
<p>The big advantage with remote user testing is that we survey or observe the users in their actual enviroment, which is both timesaving and cost effective too. In this workshop we learn how to choose the appropriate tool, how to recruit participants and how to facilitate the test . But make sure you´re prepared when doing remote research, cause everything could go very wrong!</p>
<p>Check out <a href="http://www.remoteresear.ch/samples" target="_blank">Bolt´s webpage</a> if you want to learn more about remote research.</p>
<div id="attachment_8884" class="wp-caption aligncenter" style="width: 502px"><a href="http://open.bekk.no/wp-content/uploads/2012/05/remote-research-workshop.jpg"><img class=" wp-image-8884    " src="http://open.bekk.no/wp-content/uploads/2012/05/remote-research-workshop.jpg" alt="remote research workshop" width="492" height="252" /></a><p class="wp-caption-text">The Remote Research Workshop</p></div>
<h5>4. Debra Gelman &#8211; Designing for Children</h5>
<p><em>@dgelman</em></p>
<p><a href="https://speakerdeck.com/u/dgelman/p/designing-for-children" target="_blank">Debra Gelman´s workshop</a> includes concrete tips, her experiences, as well as the surrounding theory of designing for children. She also talks about how to employ the acquired knowledge, to be used in the development of concepts, with children as the target user group.</p>
<p>Based on psychological and sociological differences, she divides children in several age groups: 2-5, 6-9 and 10-12 years old. Each age group requires special consideration as they significantly differ from each other. In addition, Debra touches on the differences and similarities between designing for children and designing for adults. For example, she has found that while adults can categorize information based on several variables (like color, shape, size, etc.), children are only capable of identifying one variable. More so, that variable tends to be color, a phenomenon she referred to as &#8220;color serve&#8221;. Finally, she briefly describes how to perform research with kids, a problematic topic due to both legal and psychological aspects.</p>
<p>For more, view <a href="https://docs.google.com/document/d/1UMEhxqFV8zu4o49CV4YRSDF5E_kOipSbm3gdOvVm7a4/edit" target="_blank">Mutte´s notes</a>.</p>
<h5></h5>
<h5>5. Jesse James Garrett &#8211; Design for Engagement</h5>
<p><em>@the_uMe</em></p>
<p>Garrett´s talk is less practical and more philosophical. It´s inspiring and make us think about our practice, what we’re actually doing and who is really a designer. Beethoven was an experience designer through his music, he claimes.</p>
<p style="text-align: left">He talks about the user experience of tomorrow. The history of user experience, which started years ago with products, then expanded to involve services, then environments and now it is all about creating <strong>cross-channel-experiences</strong>. The ultimate goal is to create human <strong>engagement</strong>, which can occur in the four areas of PACE (Perception, Action, Cognition and Emotion), he says. Design is not anymore about “mediumism”, but rather a cross-channel experience.</p>
<p><img class="wp-image-8903 alignleft" src="http://open.bekk.no/wp-content/uploads/2012/05/jesse3.jpg" alt="Garrett on the stage" width="518" height="360" /></p>
<h5 style="text-align: left">6. Peter Morville – The Architecture of understanding</h5>
<p style="text-align: left"><em>@morville</em></p>
<p style="text-align: left">The wellknown author of the book “Information Architecture for the www” talks about the importance of a cross-channel strategy too. He means that IX-people (more precise IA`s) are bridge builders and must be good at both understanding what people are asking for and at encouraging and helping the customers to understand the importance of a cross-channelstrategy.</p>
<p style="text-align: left">Have a look at his inspiring <a href="http://www.slideshare.net/morville/the-architecture-of-understanding" target="_blank">talk</a>.</p>
<h5 style="text-align: left">7. Indi Young- Mental Models</h5>
<p style="text-align: left"><em>@indiyoung</em></p>
<p style="text-align: left">A mental model is &#8220;a mental representation&#8221; of how people think, feel, react, and interact with their environment. These models are useful in the development of services and products as they can remind your team of the users&#8217; mentality.</p>
<p>In this workshop Indi Young reminds us of the importance of attempting to deduce the mental model of a user, as she rightly says &#8220;we are not the target audience&#8221;. For example, she recommends researchers to consider user interviews more as conversations. We should strive to encourage the interviewee to share stories, as &#8220;stories are just data with a soul&#8221;, and stories are easier for an interviewee to recall and retell, she says. The workshop gradually transforms from theory to practice. She performs a live demonstration on stage, interviewing a volunteer and tells us a lot of useful tips. For example, never ask an interviewee to imagine a future/potential mental state. This is because we do not want speculation and guesswork, but rather reasons for why they actually do what they do. This is a very educational workshop about an interesting topic, excellently presented by an expert.</p>
<p>For more, view <a href="https://docs.google.com/document/d/1xeC49-Nrne5lK_DP-RlK9xqDyr7fpl7xuiH7UI31838/edit" target="_blank">Mutte´s notes</a>.</p>
<p>&nbsp;</p>
<p><strong>Want some more?</strong> Check out the currently <a href="http://www.lanyrd.com/2012/uxlx/coverage/" target="_blank">available speaker presentations</a> from UXLx 2012.</p>
<p>&nbsp;</p>
<div class="mceTemp">
<dl>
<dt><a href="http://open.bekk.no/wp-content/uploads/2012/05/the-participants-outside-the-conference-center.jpg"><img class=" wp-image-8877   " src="http://open.bekk.no/wp-content/uploads/2012/05/the-participants-outside-the-conference-center-1024x573.jpg" alt="the participants outside the conference center" width="631" height="353" /></a></dt>
<dd></dd>
</dl>
</div>
<p>Participants from BEKK: Lena Hjalmarsson, Kristin Edvardsen (student and winner of <a href="http://open.bekk.no/ffc/vinnerne-av-ffc-2012-er-karet/" target="_blank">FFC</a>), Oskar Lindh (student and winner of <a href="http://open.bekk.no/ffc/vinnerne-av-ffc-2012-er-karet/" target="_blank">FFC</a>), Mattias Olovsson, Moquan Chen and Samuel Ericson (photographer).</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/jlSKLrQuiFE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/ux-lx-2012-conference-highlights/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/ux-lx-2012-conference-highlights/</feedburner:origLink></item>
		<item>
		<title>Caching Spring &gt; v 3.1.1</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/QrcNv3ycXLs/</link>
		<comments>http://open.bekk.no/caching-spring-v-3-1-1/#comments</comments>
		<pubDate>Wed, 23 May 2012 21:10:32 +0000</pubDate>
		<dc:creator>Eivind Bergstøl</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[ehcache]]></category>
		<category><![CDATA[google guava]]></category>
		<category><![CDATA[guava]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8769</guid>
		<description><![CDATA[When working with legacy systems, we often Service Oriented Architecture on top of a mainframe of some sort. Basically all our new web applications therefore communicates with web services and generate some type of response based on that data. The web services are not very fast; typically they have a response time between 100ms and 1500ms. When creating [...]]]></description>
			<content:encoded><![CDATA[<p>When working with legacy systems, we often Service Oriented Architecture on top of a mainframe of some sort. Basically all our new web applications therefore communicates with web services and generate some type of response based on that data. The web services are not very fast; typically they have a response time between 100ms and 1500ms. When creating web applications based on data from these web services, we want to cache data in our webapp to speed things up. Normally, the data is quite static and eventual consistency between web and mainframe data is sufficient.</p>
<h2>Google guava cache</h2>
<p>Not long ago, we started using the <a title="Google Guava project" href="http://code.google.com/p/guava-libraries/" target="_blank">Google Guava project</a> for our caching needs. This is a very nice cache system that can be plugged in to any class structure to cache method responses. From the outside, you call, for instance, an interface function. And in the implementation class you use a builder to create a static cache for the class method. You delegate your actual call to Guava, and the cache will look up a key and return a value if it exists in the cache, otherwise it will execute the actual method.</p>
<p>A typical, simple implementation of a Guava cache:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Component</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DataService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Cache cache<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> CACHE_SIZE <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> CACHE_EXPIRATION_IN_HOURS <span style="color: #339933;">=</span> <span style="color: #cc66cc;">24</span><span style="color: #339933;">;</span>
&nbsp;
	@Autowire
	<span style="color: #000000; font-weight: bold;">private</span> MyWebServiceBean myConnectorBean<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Document</span> getDataFromService<span style="color: #009900;">&#40;</span><span style="color: #003399;">Document</span> request<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cache <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> initializeCache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003399;">Document</span> response <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			CacheKey key <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CacheKey<span style="color: #009900;">&#40;</span>request.<span style="color: #006633;">hashCode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			response <span style="color: #339933;">=</span> cache.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>ExecutionException e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">RuntimeException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Error fetching from cache&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">return</span> response<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> initializeCache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		cache <span style="color: #339933;">=</span> CacheBuilder.<span style="color: #006633;">newBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">maximumSize</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">expireAfterWrite</span><span style="color: #009900;">&#40;</span>CACHE_EXPIRATION_IN_HOURS, TimeUnit.<span style="color: #006633;">HOURS</span><span style="color: #009900;">&#41;</span>
			.<span style="color: #006633;">build</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> CacheLoader<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				@Override
				<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Document</span> load<span style="color: #009900;">&#40;</span>CacheKey cacheKey<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #000000; font-weight: bold;">return</span> myConnectorBean.<span style="color: #006633;">getDataFromService</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Guava has all the functions you want in a cache: Time to live, max elements, eviction, invalidation, statistics, eviction events and much much more. However, implementations tend to be quite complex and new developers struggle to get the grasp of what is going on when they see the code. It can also be difficult to write code that is non-intrusive in the classes that need caching. The example above could probably be written much smarter that this, but the complexity of the code is quite obvious.</p>
<h2>Spring Cache Abstraction</h2>
<p>Spring Cache Abstraction is new in <a title="Spring 3.1" href="http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html" target="_blank">Spring 3.1</a>. It seems to be built on previous work done with <a title="spring ehcache annotations" href="http://code.google.com/p/ehcache-spring-annotations/" target="_blank">spring ehcache annotations</a>.</p>
<p>Spring cache abstraction is just that, an abstraction. It is based on some very powerful annotations like @Cacheable, @CachePut, @CacheEvict and more. I will not show examples for all annotations in this blog, just the few that helped me replace Guava.</p>
<p>Basically what you do is annotate a method, or a class, with <strong>@Cacheable(&#8220;name-of-cache&#8221;)</strong>. Spring will then proxy the class and any calls done to the methods will be cached in the named cache. The default cache key will be based on the input parameters to the method. Next time you call the method with the same parameters, the cached data will be returned. This is all you need to do with the class to enable caching for this method, or class. <em>(This means of course that the method should be deterministic. Costly numerical calculations could be an example.)</em></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Component</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DataService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
	@Autowire
	<span style="color: #000000; font-weight: bold;">private</span> MyWebServiceBean myConnectorBean<span style="color: #339933;">;</span>
&nbsp;
	@Cacheable<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name-of-cache&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Document</span> getDataFromService<span style="color: #009900;">&#40;</span><span style="color: #003399;">Document</span> request<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> myConnectorBean.<span style="color: #006633;">getDataFromService</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>But to cache something, you need a cache engine!</h3>
<p>We use annotated Spring beans to wire up the application. <em>(NO XML FTW) </em>In our @Configuration class we added the <strong>@EnableCaching</strong> annotation. <strong>This is new in Spring 3.1.1! </strong>We then create a @Bean for CacheManager. This class is used by Spring Cache Abstraction to control the caching. We can choose to use a simple ConcurrentMapCache, with a name equal to the one we use in @Cacheable, for very simple caching:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Configuration
@EnableCaching
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ServiceContext<span style="color: #009900;">&#123;</span>
&nbsp;
	@Bean
	<span style="color: #000000; font-weight: bold;">public</span> CacheManager cacheManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		CacheManager cacheManager <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleCacheManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		cacheManager.<span style="color: #006633;">addCaches</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Arrays</span>.<span style="color: #006633;">asList</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ConcurrentMapCache<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name-of-cache&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">return</span> cacheManager<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And that is it! Your applications should now be able to cache the class methods you annotate.</p>
<h3>What if I don&#8217;t want the cache to live for ever?</h3>
<p>An easy way could be to annotate a method with <strong>@CacheEvict(&#8220;name-of-cache&#8221;, allEntries=true) </strong>When this method is called, the cache will be emptied.</p>
<p>However, in our web application, we typically want to cache the xml response from a slow web service. This data is quite static, but it <em>can</em> change. The question is: When does it change? When should we evict data from the cache? And what do we do when the concurrent map becomes large? We need functionality that Guava gives us. At this point, there exists no ready made implementations of Guava with Spring Cache Abstraction. (&#8230;let&#8217;s start implementing!) Spring provides an implementation of <a title="Ehcache" href="http://ehcache.org/" target="_blank">Ehcache</a>, a well proven cache system.</p>
<p>What we need to do to unilize Ehcache is to replace our concurrentMapCache with an Ehcache manager. Notice that we have added an interface to the @Configuration class. This is to help Spring understand that the @Bean keyGenerator is the implementation that we want to use to generate default keys.</p>
<p>The KeyGenerator is an interface that takes the actual object that is doing caching, the actual method that is being called and all parameters to that method as input. Based on that input, it generates a key for the cache and returns it. The DefaultKeyGenerator that is used above creates a hashcode as key. This should work very well for methods that are deterministic.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Configuration
@EnableCaching
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CoreServiceConfig <span style="color: #000000; font-weight: bold;">implements</span> CachingConfigurer <span style="color: #009900;">&#123;</span>
&nbsp;
	@Bean
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> CacheManager cacheManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
		EhCacheManagerFactoryBean factory <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EhCacheManagerFactoryBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		factory.<span style="color: #006633;">setCacheManagerName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;My cache manager&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		factory.<span style="color: #006633;">setConfigLocation</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ClassPathResource<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ehcache.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		factory.<span style="color: #006633;">setShared</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			factory.<span style="color: #006633;">afterPropertiesSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">RuntimeException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Init cache crashed&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		EhCacheCacheManager managerEH <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EhCacheCacheManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		managerEH.<span style="color: #006633;">setCacheManager</span><span style="color: #009900;">&#40;</span>factory.<span style="color: #006633;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> managerEH<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Bean
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> KeyGenerator keyGenerator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> DefaultKeyGenerator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>To configure Ehcache we use ehcache.xml on the classpath:<br />
<div id="gist-2780709" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nt">&lt;ehcache&gt;</span></div><div class='line' id='LC2'>	<span class="nt">&lt;diskStore</span> <span class="na">path=</span><span class="s">&quot;java.io.tmpdir&quot;</span><span class="nt">/&gt;</span></div><div class='line' id='LC3'>	<span class="nt">&lt;defaultCache</span></div><div class='line' id='LC4'>		<span class="na">name=</span><span class="s">&quot;name_of_cache&quot;</span></div><div class='line' id='LC5'>		<span class="na">maxEntriesLocalHeap=</span><span class="s">&quot;1000&quot;</span></div><div class='line' id='LC6'>		<span class="na">eternal=</span><span class="s">&quot;false&quot;</span></div><div class='line' id='LC7'>		<span class="na">timeToIdleSeconds=</span><span class="s">&quot;120&quot;</span></div><div class='line' id='LC8'>		<span class="na">timeToLiveSeconds=</span><span class="s">&quot;120&quot;</span></div><div class='line' id='LC9'>		<span class="na">overflowToDisk=</span><span class="s">&quot;true&quot;</span></div><div class='line' id='LC10'>		<span class="na">maxEntriesLocalDisk=</span><span class="s">&quot;10000000&quot;</span></div><div class='line' id='LC11'>		<span class="na">diskPersistent=</span><span class="s">&quot;false&quot;</span></div><div class='line' id='LC12'>		<span class="na">diskExpiryThreadIntervalSeconds=</span><span class="s">&quot;120&quot;</span></div><div class='line' id='LC13'>		<span class="na">memoryStoreEvictionPolicy=</span><span class="s">&quot;LRU&quot;</span></div><div class='line' id='LC14'>		<span class="nt">/&gt;</span></div><div class='line' id='LC15'><span class="nt">&lt;/ehcache&gt;</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2780709/fdefa3b06d018dce86138c19b881309bd81f1afe/ehcahce.xml" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2780709#file_ehcahce.xml" style="float:right;margin-right:10px;color:#666">ehcahce.xml</a>
            <a href="https://gist.github.com/2780709">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</p>
<p>There are of course classes that makes it possible to do this in Java code instead, but some xml could be nice just to be able to easily configure our caches. <em>Remember to add Ehcache jar on you classpath..</em></p>
<h3>Security</h3>
<p>If we cache web service responses per user, an different user could in theory fiddle with some parameters and access data he or she should not. <strong>This is a serious security issue!</strong> We need to make the cache smarter. What if we could chacnge the cache keys by adding data that the user can not control? Our web application is actually a rest api using Jersey resources, and on top of that, we have a single sign-on solution to control user access.</p>
<p>We implement a custom key generator:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SecureKeyGenerator <span style="color: #000000; font-weight: bold;">implements</span> KeyGenerator <span style="color: #009900;">&#123;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> generate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> target, <span style="color: #003399;">Method</span> method, <span style="color: #003399;">Object</span>... <span style="color: #006633;">params</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">Object</span> keyPostFix <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DefaultKeyGenerator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">generate</span><span style="color: #009900;">&#40;</span>target, method, params<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>target <span style="color: #000000; font-weight: bold;">instanceof</span> SecureKeyAware <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>SecureAware<span style="color: #009900;">&#41;</span> target<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSecureKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>SecureKeyAware<span style="color: #009900;">&#41;</span> target<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSecureKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> keyPostFix<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> RuntimeExeption<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Target for key generation is not secure key aware.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The single signon solutions helps us here, because the backend has a unique identifier for each user. We just add this identifier to the key and then we have a secure cache since method parameters no longer are the only providers for key generation. Since the key is any subclass of Object, we could create the key using a MyKeyImplementation if we needed to do something smart with the keys in the cache in stead of leaving it as a string.</p>
<hr />
<p>In this blog, we have shown how to add caching to a class or method in a non-intrusive way with Spring. The example is quite simple, and for this application it works very well. Spring cache abstraction can be used in much more complicated ways &#8211; Check out the <a title="Spring documentation" href="http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html" target="_blank">Spring documentation</a>! Remember that Spring is only an abstraction layer. Spring does not handle the actual caching but leaves that to the underlying implementation library.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/QrcNv3ycXLs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/caching-spring-v-3-1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/caching-spring-v-3-1-1/</feedburner:origLink></item>
		<item>
		<title>3 steg på veien mot å bli kundesentrisk</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/3AZh0X2KE5E/</link>
		<comments>http://open.bekk.no/veien-mot-a-bli-kundesentrisk/#comments</comments>
		<pubDate>Mon, 21 May 2012 05:10:32 +0000</pubDate>
		<dc:creator>Elisabeth Rønneberg</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Kundebehov]]></category>
		<category><![CDATA[Kundefokus]]></category>
		<category><![CDATA[kundeorientering]]></category>
		<category><![CDATA[kunder]]></category>
		<category><![CDATA[Kundesentrisk]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8755</guid>
		<description><![CDATA[Mange selskaper baserer virksomheten sin på en produktsentrisk strategi. Jeg mener ikke at dette er feil, men at det for mange vil være mer hensiktsmessig å organisere seg etter ulike kunder framfor produkter, da kundene forventer tilpassede produkter og løsninger. I mitt forrige blogginnlegg - Å være kundesentrisk er mer enn å tilby god kundeservice [...]]]></description>
			<content:encoded><![CDATA[<p><em>Mange selskaper baserer virksomheten sin på en produktsentrisk strategi. Jeg mener ikke at dette er feil, men at det for mange vil være mer hensiktsmessig å organisere seg etter ulike kunder framfor produkter, da kundene forventer tilpassede produkter og løsninger.</em></p>
<p>I mitt forrige blogginnlegg <em>- </em><em>Å være kundesentrisk er mer enn å tilby god kundeservice</em><em> -</em> tok jeg for meg begrepet og betydningen av det å være kundesentrisk. Det er spesielt tre aspekter som understøtter behovet for å orientere seg mer kundesentrisk, og jeg vil trekke frem tre steg på veien for hvordan man kan imøtekomme disse:</p>
<h5><strong><em>1.</em> <em>Ny generasjon forandrer spillereglene – Vær løsningstilbyder</em></strong></h5>
<p>Vi ser stadig en sterkere endret kundeadferd i form av at:</p>
<ul>
<li>yngre kunder er mindre lojale</li>
<li>en ny generasjon kunder har et annet forhold til IKT – de har mer informasjon tilgjengelig og ønsker å gjøre jobben selv</li>
<li>de ønsker nye kommunikasjonskanaler</li>
</ul>
<p>Dette har implikasjon for bedrifter! Tidligere kunne bedrifter lansere et produkt, og la det være opp til kunden hvordan dette skulle integreres med andre produkter. Det er ikke lenger tilfelle; bedriftene må hjelpe kundene med å forstå hvordan produktene passer inn i deres situasjon. Bedriften må med andre ord være løsningstilbydere. Det betyr at bedriftene må ha kapabiliteten; både operasjonelt og organisatorisk, til å kunne tilby ulike produkter og tjenester til ulike type kunder.</p>
<h5><strong><em>2. </em><em>Kundene er heterogene og har ulike behov – Gjenkjenn kunden og dens behov </em></strong></h5>
<p>Jeg mener at den “gjennomsnittlige kunde” ikke eksisterer, da bedrifter i dag opererer med en heterogen kundeportefølje i henhold til hva kunden er verdt, hvordan kunden vil respondere til produktet eller tilbudet, samt deres villighet til å handle og snakke med hverandre. For å klare å tilby riktig produkt til riktig kunde er man avhengig av å gjenkjenne kunden eller segmentet den tilhører, og klare og skille de kundene som er verdifulle fra de som ikke er det.</p>
<p>Min erfaring er at mange bedrifter i dag har segmenteringsmodeller basert på tenkning fra tradisjonell produktmarkedsføring. Inndelingen av kundeporteføljen er da ofte basert på observerende ting og karakteristikker som for eksempel demografi, kjønn og geografi.  Disse karakteristikkene mener jeg i dag blir for enkle og lite effektive i forhold til heterogeniteten og dynamikken som er i selskapenes kundeportefølje. Med dagens kunder og deres behov, anser jeg det som sentralt å segmentere kundene på deres verdier. Jeg snakker ikke om historisk lønnsomhet, men om fremtidsrettet kundeverdi &#8211; hva kunden kan være verdt for selskapet i fremtiden. I dette arbeidet bør selskapene fokusere på økt levetid, økt salg («share-of-wallet», kryssalg, økt volum osv), og/eller reduserte kostnader (salg, service, distribusjon osv).</p>
<h5><strong><em>3.</em><em> Ikke alle kunder er verdifulle for deg &#8211; Ha riktig kundeportefølje</em></strong></h5>
<p>Det er en gammel sannhet at det er lønnsomt å ta vare på gode kunder; men hvordan klare å finne de riktige kundene å fokusere på? En forutsetning for lønnsomme kunderelasjoner er at bedriften må skaffe seg kundeinnsikt og innovere seg i den enkelte kundens behov. Gjennom å gjøre dette kan bedriften tilegne seg kundenes tillit og lojalitet, og kan skape synergier ved å balansere innsatsen av ressurser mot ulike typer av kunder i porteføljen. På denne måten vil bedriftene kunne klare å fokusere på de riktige kundene, og dermed øke lønnsomheten.</p>
<p>&nbsp;</p>
<p>Med andre ord bør selskaper på veien mot å bli kundesentrisk starte med å jobbe mer effektivt med sine kundeporteføljer. Selskaper bør i økende grad orientere seg og agere mer differensiert mot ulike kunder. Gjennom å ha god innsikt i den enkelte kundes behov og adferd, vet man hvilke kunder man bør investere i og hvilke som bør pleies med mindre ressurser.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/3AZh0X2KE5E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/veien-mot-a-bli-kundesentrisk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/veien-mot-a-bli-kundesentrisk/</feedburner:origLink></item>
		<item>
		<title>Fem fellestrekk for høy kundetilfredshet</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/hGusVK8fS_g/</link>
		<comments>http://open.bekk.no/kundetilfredshet/#comments</comments>
		<pubDate>Wed, 09 May 2012 20:58:41 +0000</pubDate>
		<dc:creator>Trygve Wiese-Haugland</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Ledelse]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Kundestrategi]]></category>
		<category><![CDATA[Kundetilfredshet]]></category>
		<category><![CDATA[Management Consulting]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8732</guid>
		<description><![CDATA[I dag ble resultatene fra Norsk Kundebarometer 2012 offentliggjort, og for tredje gang kan Flytoget skryte av å ha Norges mest fornøyde kunder. Selskapet oppnår 85,8 av 100 mulige poeng, mens gjennomsnittet for de 190 undersøkte virksomhetene er 71,3. I tillegg til Flytoget, ser vi at FINN, Toyota og One Call nok en gang er [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">I dag ble resultatene fra Norsk Kundebarometer 2012 offentliggjort, og for tredje gang kan Flytoget skryte av å ha Norges mest fornøyde kunder. Selskapet oppnår 85,8 av 100 mulige poeng, mens gjennomsnittet for de 190 undersøkte virksomhetene er 71,3. I tillegg til Flytoget, ser vi at FINN, Toyota og One Call nok en gang er blant virksomhetene med mest fornøyde kunder. I den forbindelse er det på sin plass å spørre seg: <em>Finnes det fellestrekk blant disse som andre kan lære av?</em> Ja, mener vi, og presenterer her fem fellestrekk for virksomheter med høy kundetilfredshet.</p>
<h5 style="text-align: justify;"><strong>1. Enkle verdiforslag til kundene</strong></h5>
<p style="text-align: justify;">De nevnte virksomhetene har enkle verdiforslag og et klart svar på hva de løser for kundene. Dette gjør at markedet aldri er i tvil om hva de leverer: Flytoget tilbyr passasjerene den korteste reisetiden til og fra Gardermoen. FINN representerer mulighetenes marked og gir kundene full oversikt over jobb og eiendom, mens annonsørene tilbys en godt besøkt markedsplass. Ved å fokusere på kvalitet gjennom hele verdikjeden leverer Toyota markedets mest driftsikre biler. Verdiforslaget til One Call er heller ikke til å ta feil av: De gir deg landets laveste telefonregning uten skjulte kostnader, og hjelper deg med å finne det billigste abonnementet basert på eget bruksmønster.</p>
<h5 style="text-align: justify;"><strong>2. God kundeinnsikt</strong></h5>
<p style="text-align: justify;">Evnen til å tilegne seg og dra nytte av kundeinnsikt er viktig for å fremstå som relevante, innovative og interessante for kundene. Her kan det være verdt å trekke frem hvordan Flytoget har begynt å bruke infoskjermene ombord til å vise ventetid i sikkerhetskontrollen på Gardermoen. Dette viser at de forstår hvilke behov de reisende har og at mange er bekymret for om de rekker sine respektive fly. FINN gir på sin side kundene mulighet til å lagre søk og personalisere sin egen side gjennom konseptet Min FINN. Basert på dette, samt tidligere trafikkmønster, kan de da foreslå relevante annonser tilpasset kunders ulike individuelle behov.</p>
<h5 style="text-align: justify;"><strong>3. Åpenhet om egen kundestrategi</strong></h5>
<p style="text-align: justify;">Et annet fellestrekk er at virksomhetene er åpne om egen kundestrategi og verdien av tilfredse kunder, noe som bidrar til at kundene føler seg verdsatt. Under dagens overrekkelse av Kundetilfredshetsprisen uttalte Flytogets representant følgende: ”Kundene er våre eneste sjefer og de påvirker alt vi gjør.” Et annet eksempel er hvordan One Call fremhever god kundeservice som ett av tre viktige argumenter for at kunder skal velge dem. Bevisstheten og topplederforankringen rundt dette understrekes blant annet gjennom TV-reklamer der administrerende direktør Øistein Eriksen selv forteller hvor viktig god kundeservice og fornøyde kunder er for dem.</p>
<h5 style="text-align: justify;"><strong>4. Personlig service og enkel selvbetjening</strong></h5>
<p style="text-align: justify;">Videre tilbyr virksomhetene personlig service og enkle selvbetjeningsløsninger som kundene verdsetter. Flytoget har for eksempel automatisert kjøp og kontroll av billetter, noe som gir kundene effektivitet i billettkjøp og ro ombord i toget. Toyota tilbyr blant annet enkle ”gjør-det-selv”-veiledninger på nettsidene sine, slik at kunder som ønsker å foreta mindre reparasjoner selv får hjelp til dette. Den enkle prosessen for å bli kunde i One Call er et annet eksempel: Alt du trenger å gjøre er å fylle ut et kort webskjema med nåværende telefonnummer og ønsket abonnement &#8211; resten blir håndtert av One Call.</p>
<h5 style="text-align: justify;"><strong>5. Kompetente og fornøyde medarbeidere</strong></h5>
<p style="text-align: justify;">Sist, men ikke minst, legger virksomhetene stor vekt på opplæring og oppfølging for å sikre kvalifiserte og motiverte medarbeidere. Dette bidrar til at medarbeiderne blir gode ambassadører, yter bedre service og fungerer som virksomhetens beste ansikt utad. Både Flytoget og FINN har i flere år ligget i toppen av kåringen Great Place to Work og hatt de mest tilfredse medarbeiderne. Virksomhetene som har de mest tilfredse medarbeiderne jobber bevisst med dette og med å synliggjøre medarbeidernes bidrag. Sett i lys av dette er det kanskje ikke tilfeldig at Flytogets ledelse ble igjen på kontoret, mens de lot en alminnelig flytogvert få æren av å motta dagens pris…<strong> </strong></p>
<p style="text-align: justify;">Dette er noen av fellestrekkene blant virksomhetene med høyest kundetilfredshet. Kanskje er du enig, eller kanskje ser du andre fellestrekk som er verdt å nevne?</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/hGusVK8fS_g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/kundetilfredshet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/kundetilfredshet/</feedburner:origLink></item>
		<item>
		<title>Writing reusable Backbone.js components</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/veKcq1C4CGQ/</link>
		<comments>http://open.bekk.no/mixins-in-backbone/#comments</comments>
		<pubDate>Tue, 08 May 2012 11:24:01 +0000</pubDate>
		<dc:creator>Kim Joar Bekkelund</dc:creator>
				<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Grensesnittutvikling]]></category>
		<category><![CDATA[Webarkitektur]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8722</guid>
		<description><![CDATA[In this blog post I show how functionality can easily be reused across Backbone.js models, collections and views in a very powerful way. This technique helps decouple code and make each component more focused on its primary task.]]></description>
			<content:encoded><![CDATA[<p>In our Backbone.js code we have a few times seen the need to reuse similar methods in several models, collections and views. I&#039;ve seen many create a component which they extend from, e.g. a <code>PaginationCollection</code>, but we didn&#039;t like this solution as we only wanted to share some code between objects, not add another layer to our architecture (and, even worse, potentially even more layers if we wanted to include several shared components). Basically we wanted a more decoupled solution, and we solved it by using mixins.</p>
<h2>So — what&#039;s a mixin?</h2>
<p>Basically, a mixin allows you to extend your Backbone components with utility functions. Let&#039;s, for example, say that we have pagination which is similar in many views, but not in all. How should we include this functionality?</p>
<p>We have the following API for adding extra functionality:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">UsersView.<span style="color: #660066;">mixin</span><span style="color: #009900;">&#40;</span>Pagination<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
AppView.<span style="color: #660066;">mixin</span><span style="color: #009900;">&#40;</span>Transitions<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We have, however, taken the concept of mixins one step further than what I&#039;ve seen before. In addition to including all the properties which are present in the mixin, our implementation enable mixins to include their own <code>initialize</code> which will extend the existing <code>initialize</code>. When mixing into views a mixin can also include its own <code>render</code> and <code>events</code>. Let&#039;s take a look at what this means in practice:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> UserView <span style="color: #339933;">=</span> BaseView.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    events<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;click h1&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;user&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    initialize<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;user init&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    user<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This is our mixin:</span>
<span style="color: #003366; font-weight: bold;">var</span> Pagination <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// expects the view it's mixed into to have a link with class `next`</span>
    <span style="color: #006600; font-style: italic;">// present in the DOM</span>
    events<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;click a.next&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;next&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    initialize<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;pagination init&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    next<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;next for: &quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #006600; font-style: italic;">// yeah, you would absolutely use a collection as it's named</span>
        <span style="color: #006600; font-style: italic;">// pagination, this was just to keep the example short ;)</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
UserView.<span style="color: #660066;">mixin</span><span style="color: #009900;">&#40;</span>Pagination<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> model <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
model.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;Kim&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> UserView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> model<span style="color: #339933;">:</span> model <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// this initialization console logs (in order):</span>
<span style="color: #006600; font-style: italic;">// &quot;user init&quot;</span>
<span style="color: #006600; font-style: italic;">// &quot;pagination init&quot;</span>
&nbsp;
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>view.<span style="color: #660066;">user</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;Kim&quot;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>view.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;next for: Kim&quot;</span>
console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>view.<span style="color: #660066;">events</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// {</span>
                          <span style="color: #006600; font-style: italic;">//   &quot;click a.next&quot;: &quot;next&quot;,</span>
                          <span style="color: #006600; font-style: italic;">//   &quot;click h1&quot;: &quot;user&quot;</span>
                          <span style="color: #006600; font-style: italic;">// }</span></pre></div></div>

<p>As we can see from the code, a mixin has access to <code>this</code> in the same way as the model, collection or view itself. Additionally, mixins can potentially be self-contained, i.e. because <code>initialize</code>, <code>render</code> and <code>events</code> can be extended the component we mix into does not need to know anything about the the mixin. This makes it especially easy to include a new mixin or remove one that is in use.</p>
<h2>Implementation</h2>
<p>Let&#039;s have a look at an example of how these mixins can be implemented. Specifically we will take a look at an implementation of mixins for views:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Utils <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Utils.<span style="color: #660066;">viewMixin</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>from<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> to <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prototype</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we add those methods which exists on `from` but not on `to` to the latter</span>
  _.<span style="color: #660066;">defaults</span><span style="color: #009900;">&#40;</span>to<span style="color: #339933;">,</span> from<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// … and we do the same for events</span>
  _.<span style="color: #660066;">defaults</span><span style="color: #009900;">&#40;</span>to.<span style="color: #660066;">events</span><span style="color: #339933;">,</span> from.<span style="color: #660066;">events</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we then extend `to`'s `initialize`</span>
  Utils.<span style="color: #660066;">extendMethod</span><span style="color: #009900;">&#40;</span>to<span style="color: #339933;">,</span> from<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;initialize&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// … and its `render`</span>
  Utils.<span style="color: #660066;">extendMethod</span><span style="color: #009900;">&#40;</span>to<span style="color: #339933;">,</span> from<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;render&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Helper method to extend an already existing method</span>
Utils.<span style="color: #660066;">extendMethod</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>to<span style="color: #339933;">,</span> from<span style="color: #339933;">,</span> methodName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// if the method is defined on from ...</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>_.<span style="color: #660066;">isUndefined</span><span style="color: #009900;">&#40;</span>from<span style="color: #009900;">&#91;</span>methodName<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> old <span style="color: #339933;">=</span> to<span style="color: #009900;">&#91;</span>methodName<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// ... we create a new function on to</span>
    to<span style="color: #009900;">&#91;</span>methodName<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// wherein we first call the method which exists on `to`</span>
      <span style="color: #003366; font-weight: bold;">var</span> oldReturn <span style="color: #339933;">=</span> old.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// and then call the method on `from`</span>
      from<span style="color: #009900;">&#91;</span>methodName<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// and then return the expected result,</span>
      <span style="color: #006600; font-style: italic;">// i.e. what the method on `to` returns</span>
      <span style="color: #000066; font-weight: bold;">return</span> oldReturn<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now we need to include this mixin in such a way that <code>this</code> means the correct thing and we can use it like we saw in the example above. This can be done in two ways, both of which utilize the <code>viewMixin</code> method we created above:</p>
<ol>
<li>
<p>As <a href="http://documentcloud.github.com/backbone/#FAQ-extending">mentioned</a> in the Backbone docs it&#039;s okey to add methods directly to a Backbone component. We can use this idea and add <code>mixin</code> like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">mixin</span> <span style="color: #339933;">=</span> Utils.<span style="color: #660066;">viewMixin</span><span style="color: #339933;">;</span></pre></div></div>

</li>
<li>
<p>If you create a layered architecture you can include <code>viewMixin</code> in one of your layers. In our project we had a <code>BaseView</code> which we created all our views from. Remember, this is how Backbone views are defined:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span>properties<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>classProperties<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>So, in order to create our desired API we can add <code>mixin</code> as a class property on our <code>BaseView</code>, for example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> BaseView <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// lots of methods</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
  mixin<span style="color: #339933;">:</span> Utils.<span style="color: #660066;">viewMixin</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></div></div>

</li>
</ol>
<p>In my project we chose to go for the latter solution as we already had a <code>BaseView</code>.</p>
<h2>Testing</h2>
<p>Mixins can be tested both by themselves and when mixed into a component. We&#039;ll take a look at how the latter can be done.</p>
<p>Jasmine has a great way to include similar tests several places. Davis W. Frank of Pivotal Labs <a href="http://pivotallabs.com/users/dwfrank/blog/articles/1720-drying-up-jasmine-specs-with-shared-behavior">wrote a great blog post</a> about this a year ago. Basically, the point is to write a function that contains regular Jasmine specs. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> sharedBehaviorForPagination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  describe<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;pagination&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should be able to paginate to the next page&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should not be able to paginate to the next page when on the last page&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In the specs for the component we mix into we can then call this function:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">describe<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;users&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// ... lots of users specific specs</span>
&nbsp;
  sharedBehaviorForPagination<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We have now included the shared set of specs into our regular tests for &quot;users&quot;. If some shared state is needed, we can change <code>sharedBehaviorForPagination</code> to receive arguments in order to share state. We found this to be a great technique for ensuring that our mixins works as expected in all the components which include them.</p>
<h2>When?</h2>
<p>Mixins are a simple but potentially very powerful abstraction. We used them for mainly for three things: pagination, local error handling and handling transitions between pages. Basically, we used mixins when we found them to help decouple our code and make each component more focused. The right time to use them appears to be when a component does more than one thing and when we can better separate concerns when splitting to the code.</p>
<hr />
<p>In this blog post I&#039;ve only looked at using them for views, but they are also great for breaking up models and collections.</p>
<p>To give credit were credit is due, this blog post, and our solution to the mixin problem, was heavily influenced by Dmitry Polushkin&#039;s <a href="https://gist.github.com/1256695">gist on mixins</a>.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/veKcq1C4CGQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/mixins-in-backbone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://open.bekk.no/mixins-in-backbone/</feedburner:origLink></item>
		<item>
		<title>Fire myter om Social CRM</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/PUq930uOUnQ/</link>
		<comments>http://open.bekk.no/socialcrm/#comments</comments>
		<pubDate>Mon, 07 May 2012 12:53:20 +0000</pubDate>
		<dc:creator>Trygve Wiese-Haugland</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Ledelse]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[CRM]]></category>
		<category><![CDATA[Kundestrategi]]></category>
		<category><![CDATA[Management Consulting]]></category>
		<category><![CDATA[Social CRM]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8669</guid>
		<description><![CDATA[Når jeg snakker med kunder om Social CRM eller leser om temaet på nett, registrerer jeg at mange misforstår både hva det innebærer og hva man kan få ut av det. Dette kan bidra til at virksomheter avstår fra Social CRM eller feilaktig tror de allerede jobber i henhold til denne filosofien. Formålet med dette [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Når jeg snakker med kunder om Social CRM eller leser om temaet på nett, registrerer jeg at mange misforstår både hva det innebærer og hva man kan få ut av det. Dette kan bidra til at virksomheter avstår fra Social CRM eller feilaktig tror de allerede jobber i henhold til denne filosofien. Formålet med dette innlegget er derfor å etablere en felles forståelse for fagområdet og rydde opp i noen av de vanligste misforståelsene.</p>
<h5><strong>Hva er Social CRM?</strong></h5>
<p style="text-align: justify;">Det finnes en rekke upresise definisjoner av Social CRM som samlet sett bidrar til mytene jeg her skal diskutere. La meg derfor starte med å definere Social CRM som <em>en prosess for å overvåke, engasjere og administrere nåværende og potensielle kunder på tvers av sosiale medier for å kunne forbedre egen virksomhet og dens relasjon med kundene.</em></p>
<h5 style="text-align: justify;"><strong>Myte 1: Social CRM kan erstatte tradisjonell CRM</strong></h5>
<p style="text-align: justify;">Den tradisjonelle tilnærmingen til innsamling av kundedata baserer seg på virksomhetens kontakt med kundene, for eksempel gjennom kjøpsprosesser, kundeservice og kundeundersøkelser. Dette gir nyttig, men likevel begrenset informasjon. Mens tradisjonell CRM først og fremst handler om å samle kundedata i skjæringspunktet mellom kunde og virksomhet, muliggjør Social CRM innsikt i hva kundene sier til hverandre. Både eksterne sosiale nettverk, samt virksomhetens egne diskusjonsforum og idéportaler er aktuelle informasjonskilder. Slike informasjonskilder gir bedre grunnlag for å forstå hva kundene faktisk er opptatt av, hva de søker etter, hva de deltar på, hva de liker og hva de misliker. Men til tross for at sosiale medier muliggjør ny kundeinnsikt, må dette fortsatt kombineres med kjøpshistorikk, reklamasjoner og annet som samles gjennom tradisjonell CRM. <em>Social CRM endrer derfor ikke definisjonen eller viktigheten av tradisjonell CRM – Social CRM er et supplement til dette.</em></p>
<h5 style="text-align: justify;"><strong>Myte 2: Social CRM gir virksomheten bedre kontroll over kundene</strong></h5>
<p style="text-align: justify;">Det er ikke overraskende at det oppstår misforståelser rundt Social CRM fordi navnet i seg selv er relativt misvisende. Bakgrunnen for en slik påstand er at CRM, eller Customer Relationship Management, indikerer noe virksomheten har kontroll over og kan lede. Dette strider mot den grunnleggende filosofien bak Social CRM. Social CRM handler ikke om ledelse og kontroll av kunden, men om engasjement med kunden. Man kan derfor diskutere om et bedre navn ville vært Social CRE – Social Customer Relationship Engagement. Jeg skal ikke gå nærmere inn på en navnediskusjon her, fordi et navn i seg selv gir lite verdi. Det som imidlertid er viktig er forståelsen av at maktforholdet mellom virksomhet og kunde nå er snudd på hodet: <em>Skal man lykkes med Social CRM må man først og fremst innse at det ikke lenger er virksomheten, men kundene som har kontroll.</em></p>
<h5 style="text-align: justify;"><strong>Myte 3: Social CRM handler bare om tilstedeværelse i sosiale medier</strong></h5>
<p style="text-align: justify;">En tredje vanlig misforståelse er at Social CRM sidestilles med tilstedeværelse i sosiale medier. Mange virksomheter ser sosiale medier primært som nye kanaler for markedsføring og kundeservice, noe som riktignok kan gi verdi og tjene sine respektive formål isolert sett. Antall følgere på Facebook og Twitter er imidlertid ikke noe mål på om man lykkes med Social CRM eller ikke. Hvorvidt du har opprettet egne stillinger for kundeservice i sosiale medier, eller hvorvidt du har gått til anskaffelse av sosiale lytteverktøy er heller ikke noe mål på om man har forstått og innført filosofien bak Social CRM. <em>Social CRM handler om evnen til å analysere og utnytte kundeinnsikten man får gjennom sosiale medier til å forbedre egen virksomhet og dens relasjon med kundene.</em></p>
<h5 style="text-align: justify;"><strong>Myte 4: Social CRM gir ingen verdi</strong></h5>
<p style="text-align: justify;">Som tidligere nevnt gir Social CRM bedre innsikt i kundens reelle behov. Dersom man evner å utnytte denne kundeinnsikten til faktiske forbedringer, vil man lettere kunne innfri og overgå kundens forventninger til produkter og tjenester. I tillegg til bedre produkt- og tjenesteutvikling, signaliserer dette at man tar kundene på alvor. Når kundene føler seg inkludert og viktige, vil de lettere etablere eierskap og forpliktelse til virksomheten, dens produkter og tjenester. Social CRM bidrar i tillegg til at virksomheter fanger opp problemer og misnøye tidligere, noe som gjør at kundeservice lettere kan kommunisere proaktivt. Færre kundehenvendelser og kortere ventetid, bidrar både til lavere kostnader og mer fornøyde kunder. <em>Social CRM bidrar derfor til økt verdiskaping både gjennom produkt- og tjenesteutvikling, salg- og markedsføring og kundeservice.</em></p>
<p style="text-align: justify;">Dette er noen av de vanligste mytene rundt Social CRM. Kanskje kjenner du deg igjen i disse, eller kanskje har du andre myter som kan diskuteres?</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/PUq930uOUnQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/socialcrm/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://open.bekk.no/socialcrm/</feedburner:origLink></item>
		<item>
		<title>A view’s responsibility — a lesson on JavaScript and the DOM</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/AZ50T6SCdZ8/</link>
		<comments>http://open.bekk.no/a-views-responsibility/#comments</comments>
		<pubDate>Wed, 02 May 2012 13:10:57 +0000</pubDate>
		<dc:creator>Kim Joar Bekkelund</dc:creator>
				<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Webarkitektur]]></category>
		<category><![CDATA[abstractions]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8647</guid>
		<description><![CDATA[Creating abstractions are at the core of writing great JavaScript. In this blog post I propose a way of creating view abstractions by giving a view ownership of an HTML element and everything inside it.]]></description>
			<content:encoded><![CDATA[<p>Throughout most JavaScript code I&#039;ve seen, <code>$</code> is littered all over the place. You need all list items from the members list? Just do <code>$(&#039;.members li&#039;)</code>. And then you need to add something to the sidebar, just <code>$(&#039;.sidebar&#039;).append(&quot;this is so easy&quot;)</code>. So — what&#039;s the problem?</p>
<p>First of all, how do you test these views? Or, this is JavaScript, so you probably <a href="https://twitter.com/#!/jasminebdd/status/182322290464276480">don&#039;t</a>. Cheekiness aside, the basic problem is that you need the DOM present to enable searching for selectors, and to have the DOM present you (often) need to set up the entire application — which, obviously, slows down tests considerably.</p>
<p>Secondly, who is allowed to change what? Can all functions change whatever part of the DOM they want? This wreaks havoc for your tests and creates uncertainty as to where something occurs. And once again, you most likely need to set up the entire application to test the view.</p>
<p>My solution: <strong>A view is responsible for one HTML element and everything inside it.</strong></p>
<p>And, of course, a view may contain several sub-views which again are responsible for themselves.</p>
<h2>What&#039;s a view?</h2>
<p>Basically, a view is a component which handles some part of a user interface. My views have five primary responsibilities (Those familiar with MVC and MVP will probably call these views <em>Controllers</em> or <em>Presenters</em>, but the nomenclature is not important — splitting responsibilities between different components is):</p>
<ul>
<li>Rendering the view, i.e. making changes to the DOM.</li>
<li>Listening for DOM events, such as <code>click</code> and <code>submit</code>.</li>
<li>Listening for events from the rest of my application, plus triggering events when the view is in certain states.</li>
<li>Creating sub-views if they are needed.</li>
<li>Updating models based on changes in the view (Don&#039;t you dare make <code>$.ajax</code> calls directly in views!)</li>
</ul>
<p>A view is, however, never ever allowed to access something which is outside its subset of the DOM.</p>
<p>Let&#039;s look at an example of a view:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// a view constructor which accepts:</span>
<span style="color: #006600; font-style: italic;">// - el, which is a jQuery object of the HTML element the view owns</span>
<span style="color: #006600; font-style: italic;">// - user, which is a user model with key-value pairs</span>
<span style="color: #003366; font-weight: bold;">var</span> UserView <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #339933;">,</span> user<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span> <span style="color: #339933;">=</span> el<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">user</span> <span style="color: #339933;">=</span> user<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
UserView.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">showImage</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;img src='</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">user</span>.<span style="color: #660066;">image</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// let's just create a super simple user object</span>
<span style="color: #003366; font-weight: bold;">var</span> user <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  image<span style="color: #339933;">:</span> <span style="color: #3366CC;">'http://example.com/image.png'</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// initialize the view with the jQuery object the view owns and a user</span>
<span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> UserView<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> user<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// ... and now we can do stuff which changes the DOM</span>
view.<span style="color: #660066;">showImage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This <code>view</code> is never ever to go outside of <code>.user</code>. Ever.</p>
<p>No frameworks or libraries are needed, just being strict with how you write your code. With these small changes we have contained a subset of the user interface to a specific view, and this <code>UserView</code> is easily testable and can easily be moved around on the page. It can even be removed without being afraid of how it impacts the rest of the application.</p>
<h2>Easily testable</h2>
<p>Just as an example, to test this bit of code we can initialize it with <code>$(&#039;&lt;div&gt;&lt;/div&gt;&#039;)</code> instead of <code>$(&#039;.user&#039;)</code>. This just means that we let an empty <code>div</code> live in the jQuery object instead of the <code>.user</code> subset of the DOM.</p>
<p>Using this trick, we can test the user view by calling <code>showImage</code> and then check that the image is present. As everything lives in the jQuery object we don&#039;t need to set up the DOM. Let&#039;s look at a code example using Jasmine:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">describe<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'user view'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'should be able to show image'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> user <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
      image<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;user.png&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> UserView<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;div&gt;&lt;/div&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> user<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    view.<span style="color: #660066;">showImage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// remember that `view.el` is a jQuery object. So now we can call</span>
    <span style="color: #006600; font-style: italic;">// `find` on it directly instead of looking for `img` in the entire</span>
    <span style="color: #006600; font-style: italic;">// DOM.</span>
    <span style="color: #003366; font-weight: bold;">var</span> image <span style="color: #339933;">=</span> view.<span style="color: #660066;">el</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'img'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span>image.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;src&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;user.png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>With a small helper function the code becomes even easier to work with:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">UserView.<span style="color: #660066;">prototype</span>.$ <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now you can write <code>view.$(&#039;img&#039;)</code> instead of <code>view.el.find(&#039;img&#039;)</code>.</p>
<h2>But I need to change something &#039;over there&#039;</h2>
<p>So let&#039;s say you have created several of these views, but now one view needs to change something in another view — but how? Remember, a view is not allowed do anything outside its HTML element. </p>
<p>The solution is events.</p>
<p>Events are basically just a way to say: &quot;Hi, I want to know when some action occurs&quot; and &quot;Hi, you know what? The action you&#039;re waiting for just occurred!&quot; We are used to this idea from jQuery DOM events such as <code>click</code> and <code>submit</code>. Now we are just moving it into the rest of our code.</p>
<p>Let&#039;s look at some examples using <a href="https://github.com/Wolfy87/EventEmitter">EventEmitter</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> events <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> EventEmitter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> UserView <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #339933;">,</span> user<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span> <span style="color: #339933;">=</span> el<span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">user</span> <span style="color: #339933;">=</span> user<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Let's listen for someone emitting the event 'user:showImage', which</span>
  <span style="color: #006600; font-style: italic;">// we listen for and then show the user's image.</span>
  <span style="color: #006600; font-style: italic;">// The first parameter is the event name, the second is the function</span>
  <span style="color: #006600; font-style: italic;">// to call when the event is triggered, and the third is the context</span>
  <span style="color: #006600; font-style: italic;">// the function is called with.</span>
  events.<span style="color: #660066;">addListener</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'user:showImage'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">showImage</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// We can also emit events. Let's tell listeners that we have created</span>
  <span style="color: #006600; font-style: italic;">// a user view.</span>
  events.<span style="color: #660066;">emit</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'user:created'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now, whenever you are interested in something outside a view, you can listen for events, and you can also let other views know when something has occurred. This creates a highly decoupled application which is easy to test and easy to extend.</p>
<h2>But, why?</h2>
<p>To sum up, there are three primary benefits of writing your JavaScript views like this:</p>
<ul>
<li>You always know who is responsible for some subset of the DOM, and changing a view will <em>never</em> impact the DOM outside of its &quot;walls&quot;.</li>
<li>You can have localized DOM lookup. Instead of looking for <code>.user img</code> you can look for <code>img</code> on the user view. Based on the above example we can find the image by writing <code>userView.DOM(&#039;img&#039;)</code>.</li>
<li>It&#039;s very simple to test. And your tests will be blazingly fast as they do not depend on the DOM or on the entire app being set up.</li>
</ul>
<hr />
<p>Many of the ideas I discuss in this blog post is both inspired by and beautifully handled by <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> and <a href="http://spinejs.com/">Spine.js</a>. I truly recommend checking out those libraries if you&#039;re working on a large JavaScript application.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/AZ50T6SCdZ8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/a-views-responsibility/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://open.bekk.no/a-views-responsibility/</feedburner:origLink></item>
		<item>
		<title>Integration testing Backbone.js</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/AWqS0K-ORfY/</link>
		<comments>http://open.bekk.no/integration-testing-backbone-js/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 09:06:14 +0000</pubDate>
		<dc:creator>Kim Joar Bekkelund</dc:creator>
				<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Webarkitektur]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[integration tests]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8626</guid>
		<description><![CDATA[Throughout my last project we have had an interesting approach to testing our Backbone.js code. Instead of unit testing each and every bit of the application, we mock out Ajax requests and test that the application works end-to-end.]]></description>
			<content:encoded><![CDATA[<p>Throughout my last project we have had an interesting approach to testing our Backbone.js code. Instead of unit testing each and every bit of the application, we mock out Ajax requests and test that the application works end-to-end. Of course, for complex methods we also write unit tests. Our main goal, however, is not to write a lot of tests, but to be more confident that the application work as expected from a user&#039;s point of view.</p>
<p>We experience three primary benefits from these tests:</p>
<ul>
<li>Rather than being implementation-oriented, they focus on the end result. This means that restructuring and changing code rarely breaks tests, as long as we don&#039;t break the application&#039;s end-to-end behaviour.</li>
<li>They are very easy to write using Backbone&#039;s abstractions. They are also more natural to write as they focus on the end result.</li>
<li>They are very fast, so we could run them all the freakin&#039; time.</li>
</ul>
<p>Let&#039;s look at an example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should list all persons in response&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// fetch an Ajax response</span>
  <span style="color: #003366; font-weight: bold;">var</span> response <span style="color: #339933;">=</span> readFixtures<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;responses/persons.json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> options <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// no additional options for the Ajax request</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// create our view, sending in an empty collection</span>
  <span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> PersonsView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> collection<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Persons<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
  view.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// show header and other static stuff</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// mock out all requests (this is our core test abstraction),</span>
  <span style="color: #006600; font-style: italic;">// i.e. what this function does is responding to all Ajax requests in</span>
  <span style="color: #006600; font-style: italic;">// the callback with the same response and with the same options.</span>
  <span style="color: #006600; font-style: italic;">// Thus, when `fakeResponse` is finished, all Ajax requests will have</span>
  <span style="color: #006600; font-style: italic;">// responded, and as we listen for finished Ajax requests in our view,</span>
  <span style="color: #006600; font-style: italic;">// we will then have properly set up our PersonsView.</span>
  fakeResponse<span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    view.<span style="color: #660066;">collection</span>.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// trigger Ajax request</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
&nbsp;
  <span style="color: #006600; font-style: italic;">// ensure that all persons are present</span>
  expect<span style="color: #009900;">&#40;</span>view.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.persons li'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>So, basically, we test the end result given a specific response.</p>
<p>We use the following libraries for writing tests:</p>
<ul>
<li><a href="http://pivotal.github.com/jasmine/">Jasmine</a> as our test framework.</li>
<li><a href="https://github.com/velesin/jasmine-jquery">Jasmine-jQuery</a> for fixtures.</li>
<li><a href="http://sinonjs.org/">Sinon.js</a> for test spies, stubs and mocks.</li>
</ul>
<p>The core test abstraction in the example is <code>fakeResponse</code>. This method creates mock responses for Ajax requests using Sinon.js. This is a simplified implementation of the function:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> fakeResponse<span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> statusCode<span style="color: #339933;">,</span> headers<span style="color: #339933;">,</span> server<span style="color: #339933;">,</span> resp<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// some default values, so we don't have to set status code and</span>
  <span style="color: #006600; font-style: italic;">// content type all the time.</span>
  statusCode <span style="color: #339933;">=</span> options.<span style="color: #660066;">statusCode</span> <span style="color: #339933;">||</span> <span style="color: #CC0000;">200</span><span style="color: #339933;">;</span>
  headers <span style="color: #339933;">=</span> options.<span style="color: #660066;">headers</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">&quot;Content-Type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/json&quot;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we create what Sinon.js calls a fake server. This is basically just</span>
  <span style="color: #006600; font-style: italic;">// a name for mocking out all XMLHttpRequests. (There are no actual</span>
  <span style="color: #006600; font-style: italic;">// servers involved.)</span>
  server <span style="color: #339933;">=</span> sinon.<span style="color: #660066;">fakeServer</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we tell Sinon.js what we want to respond with</span>
  server.<span style="color: #660066;">respondWith</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>statusCode<span style="color: #339933;">,</span> headers<span style="color: #339933;">,</span> response<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  callback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// this actually makes Sinon.js respond to the Ajax request. As we can</span>
  <span style="color: #006600; font-style: italic;">// choose when to respond to a request, it is for example possible to</span>
  <span style="color: #006600; font-style: italic;">// test that spinners start and stop, that we handle timeouts</span>
  <span style="color: #006600; font-style: italic;">// properly, and so on.</span>
  server.<span style="color: #660066;">respond</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  server.<span style="color: #660066;">restore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>With this relatively simple abstraction we can do a lot of powerful stuff in our tests. Let&#039;s look at a new example where we interact with the view and perform several Ajax requests:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should show error message when pagination fails&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// ajax responses</span>
  <span style="color: #003366; font-weight: bold;">var</span> response <span style="color: #339933;">=</span> readFixtures<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;responses/persons.json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> errorResponse <span style="color: #339933;">=</span> readFixtures<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;responses/errors.json&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// create our initial view</span>
  <span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> PersonsView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> collection<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Persons<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  view.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// show header and other static stuff</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// mock out all requests</span>
  fakeResponse<span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> headers<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    view.<span style="color: #660066;">collection</span>.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// trigger Ajax request</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// now we have set up our initial state, and can go on to doing things</span>
  <span style="color: #006600; font-style: italic;">// in the view.</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we ensure that errors are not present</span>
  expect<span style="color: #009900;">&#40;</span>view.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.errors'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">not</span>.<span style="color: #660066;">toExist</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// we set up an error response ...</span>
  fakeResponse<span style="color: #009900;">&#40;</span>errorResponse<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> statusCode<span style="color: #339933;">:</span> <span style="color: #CC0000;">503</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// ... and we trigger the error by clicking the next button</span>
    <span style="color: #006600; font-style: italic;">// (in our view we listen for the click event and start the</span>
    <span style="color: #006600; font-style: italic;">// pagination process)</span>
    view.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'a.more'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// ensure that errors are present</span>
  expect<span style="color: #009900;">&#40;</span>view.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.errors'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toExist</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We often initialize views the same way for several tests, as with <code>PersonsView</code> in the examples above. It is usually a good idea to create abstractions for these at some point. For example we can create a <code>getPersonsViewFromResponse</code> as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> getPersonsViewFromResponse<span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> view <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> PersonsView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> collection<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">new</span> Persons<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  view.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  fakeResponse<span style="color: #009900;">&#40;</span>response<span style="color: #339933;">,</span> options<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    view.<span style="color: #660066;">collection</span>.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> view<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Thus, we can call <code>getPersonsViewFromResponse</code> to initialize our view, which makes our tests even easier to write.</p>
<hr />
<p>We have written more than 200 of these tests, and, as they don&#039;t change the DOM, they are blazingly fast. Ours run in about 1.3 seconds. Additionally, they work wonders for our confidence and our code.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/AWqS0K-ORfY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/integration-testing-backbone-js/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/integration-testing-backbone-js/</feedburner:origLink></item>
		<item>
		<title>Jenkins Git Plugin does not garbage collect</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/4AXTf3pE8lU/</link>
		<comments>http://open.bekk.no/jenkins-gitplugin-does-not-garbage-collect/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 13:34:34 +0000</pubDate>
		<dc:creator>Stein Inge Morisbak</dc:creator>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git plugin]]></category>
		<category><![CDATA[gitplugin]]></category>
		<category><![CDATA[jenkins]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8606</guid>
		<description><![CDATA[The Jenkins Git Plugin does not garbage collect automatically. I have requested this feature, but in the meantime I have worked around this by scheduling a bash script to run nightly for all the Jenkins workspaces: #!/bin/bash repo_dirs=$&#40; ls -d1 $@ &#41; for repo_dir in ${repo_dirs[@]} do cd $repo_dir echo &#34;checking if $repo_dir is a [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin" title="Jenkins Git Plugin" target="_blank">Jenkins Git Plugin</a> does not garbage collect automatically. I have <a href="https://issues.jenkins-ci.org/browse/JENKINS-13493" title="JENKINS-13493" target="_blank">requested this feature</a>, but in the meantime I have worked around this by scheduling a bash script to run nightly for all the Jenkins workspaces:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">repo_dirs</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-d1</span> $<span style="color: #000000; font-weight: bold;">@</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">for</span> repo_dir <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${repo_dirs[@]}</span>
<span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$repo_dir</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;checking if <span style="color: #007800;">$repo_dir</span> is a git repo&quot;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> .git <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>
  <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Garbage collecting <span style="color: #007800;">$repo_dir</span>&quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">git</span> <span style="color: #c20cb9; font-weight: bold;">gc</span>
  <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>The script is scheduled to run every night in Jenkins. Create a new Job and select &#8220;Build a free-style software project&#8221;. Fill in Build as follows:</p>
<p><img src="https://github.com/steinim/Images/raw/master/git_gc_build.png" alt="git-gc Build" /></p>
<p>The script can also be used manually from the command line or as a cron job with path(s) to your repos as an argument. Without an argument it will process current directory.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/4AXTf3pE8lU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/jenkins-gitplugin-does-not-garbage-collect/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/jenkins-gitplugin-does-not-garbage-collect/</feedburner:origLink></item>
		<item>
		<title>Efficient Java serialization</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/7I9g90kDPLo/</link>
		<comments>http://open.bekk.no/efficient-java-serialization/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 19:08:43 +0000</pubDate>
		<dc:creator>Eivind Waaler</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hazelcast]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[kryo]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8567</guid>
		<description><![CDATA[This post shows an example of making Java serialization more efficient using Kryo. The context is serialization on the Hazelcast grid product, but the approach can be used in any situation where you need to improve the speed and memory consumption of standard Java serialization.]]></description>
			<content:encoded><![CDATA[<p><em>This post shows an example of making Java serialization more efficient using Kryo. The context is serialization on the Hazelcast grid product, but the approach can be used in any situation where you need to improve the speed and memory consumption of standard Java serialization.</em></p>
<h3>The external serializer problem</h3>
<p>Lately we&#8217;ve been working with <a href="http://www.hazelcast.com/" title="Hazelcast">Hazelcast</a>, an open source Java In-Memory Data Grid. In its simplest form Hazelcast is extremely easy to work with. Just use the static <code>getMap</code> method and starting putting objects into the grid:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Map<span style="color: #339933;">&lt;</span>Integer, String<span style="color: #339933;">&gt;</span> testMap <span style="color: #339933;">=</span> Hazelcast.<span style="color: #006633;">getMap</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
testMap.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #0000ff;">&quot;entry 1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
testMap.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #0000ff;">&quot;entry 2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>If you are running several grid nodes, the data is serialized across the cluster automatically. So after running the code above on one node you can extract the data on a different, or the same, node:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Map<span style="color: #339933;">&lt;</span>Integer, String<span style="color: #339933;">&gt;</span> testMap <span style="color: #339933;">=</span> Hazelcast.<span style="color: #006633;">getMap</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003399;">String</span> entry <span style="color: #339933;">=</span> testMap.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// &quot;entry 1&quot;</span></pre></div></div>

<p>The only requirement on the objects going into the grid is that they are serializable, either by implementing <code>java.io.Serializable/Externalizable</code> or <code>com.hazelcast.nio.DataSerializable</code>. Our problem is that we need to be able to work with an existing domain model. We can add <code>implements Serializable</code>, but standard Java serialization is inefficient both in terms of speed and size. We would rather not implement <code>Externalizable</code> or <code>DataSerializable</code> as the domain model is used in other places, and we don&#8217;t want to clutter it with serialization code.</p>
<p>We took a quick look at different serialization frameworks and decided to try out <a href="http://code.google.com/p/kryo/" title="Kryo">Kryo</a>, an easy to use framework scoring pretty good in <a href="https://github.com/eishay/jvm-serializers/wiki" title="JVM Serializer benchmark">benchmarks</a>. Hazelcast however does not support plugging in a custom serializer at the moment (version 2.0.2). So this is our problem:</p>
<p><strong>How to utilize an efficient serialization framework like Kryo with a product that does not support plugable serializers?</strong></p>
<h3>Proposed solution: serializable wrapper</h3>
<p>What we&#8217;ve come up with so far is the following. First we put all Kryo specifics into a utility class <code>KryoSerializer</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">eivindw.io</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.esotericsoftware.kryo.Kryo</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.esotericsoftware.kryo.ObjectBuffer</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> KryoSerializer <span style="color: #009900;">&#123;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> Kryo kryo <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Kryo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
      kryo.<span style="color: #006633;">setRegistrationOptional</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> register<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span>... <span style="color: #006633;">classes</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span> clazz <span style="color: #339933;">:</span> classes<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         kryo.<span style="color: #006633;">register</span><span style="color: #009900;">&#40;</span>clazz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> write<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      ObjectBuffer objectBuffer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ObjectBuffer<span style="color: #009900;">&#40;</span>kryo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000000; font-weight: bold;">return</span> objectBuffer.<span style="color: #006633;">writeClassAndObject</span><span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">Object</span> read<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      ObjectBuffer objectBuffer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ObjectBuffer<span style="color: #009900;">&#40;</span>kryo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000000; font-weight: bold;">return</span> objectBuffer.<span style="color: #006633;">readClassAndObject</span><span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>What this does is provide an easy way to turn objects into byte arrays and vice versa, the <code>Person</code> class in this example doesn&#8217;t even have to implement <code>Serializable</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Eivind&quot;</span>, <span style="color: #cc66cc;">35</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes <span style="color: #339933;">=</span> KryoSerializer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// serialize to byte array</span>
&nbsp;
Person samePerson <span style="color: #339933;">=</span> KryoSerializer.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// deserialize back to object</span></pre></div></div>

<p>To make use of this on the Hazelcast grid we created a serializable &#8220;wrapper&#8221; class:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">eivindw.io</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.ObjectStreamException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.Serializable</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> KryoWrapper <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> s<span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> KryoWrapper<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      s <span style="color: #339933;">=</span> KryoSerializer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Object</span> readResolve<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ObjectStreamException</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> KryoSerializer.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The wrapper will use the <code>KryoSerializer</code> to store a given object as a byte array, which the JVM of course knows how to serialize efficiently. Then the <code>readResolve</code> method will use the <code>KryoSerializer</code> to recreate and return the original object from the byte array. The JVM allows this as a sort of automatic replacement of the deserialized object &#8211; for reference see <a href="http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html" title="java.io.Serializable JavaDoc">java.io.Serializable JavaDoc</a>. This allows us to use the wrapper directly on the Hazelcast maps:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Map<span style="color: #339933;">&lt;</span>Integer, Object<span style="color: #339933;">&gt;</span> testMap <span style="color: #339933;">=</span> Hazelcast.<span style="color: #006633;">getMap</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;persons&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Eivind&quot;</span>, <span style="color: #cc66cc;">35</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
testMap.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #000000; font-weight: bold;">new</span> KryoWrapper<span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Putting a wrapper - serializes fast and small</span>
&nbsp;
Person samePerson <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Person<span style="color: #009900;">&#41;</span> testMap.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Getting a Person - &quot;automatic&quot; deserialized</span></pre></div></div>

<p>The wrapper will work with standard Java serialization as well:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">ByteArrayOutputStream</span> baos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">ObjectOutputStream</span> oos <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectOutputStream</span><span style="color: #009900;">&#40;</span>baos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
oos.<span style="color: #006633;">writeObject</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> KryoWrapper<span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Using wrapper when writing</span>
&nbsp;
<span style="color: #003399;">ByteArrayInputStream</span> bais <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayInputStream</span><span style="color: #009900;">&#40;</span>baos.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">ObjectInputStream</span> ois <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectInputStream</span><span style="color: #009900;">&#40;</span>bais<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Person person <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Person<span style="color: #009900;">&#41;</span> ois.<span style="color: #006633;">readObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Casting result directly to Person</span></pre></div></div>

<p>Why use the readResolve method with a cast instead of an explicit wrap method? Hazelcast provides a series of ways to access the serialized objects in the grid, for example <a href="http://hazelcast.com/docs/2.0/manual/multi_html/ch02s03.html#MapQuery" title="Hazelcast Map Queries">queries</a>. Having the wrapper automatically deserialize to the object allows us to use all these features directly, as if the object was serialized directly on the grid.</p>
<h3>Feedback?</h3>
<p>I feel we&#8217;ve come up with a pretty good way to make use of an external serializer in a framework requiring class-internal serialization. Our first tests indicate that we are saving both time and space using this approach. What do you think? Is this use of the readResolve method a viable way to solve this problem? Please leave a comment if you have any suggestions for improvement/alternatives or questions <img src='http://open.bekk.no/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The code shown in this post is available as a <a href="https://github.com/eivindw/hazelcast-kryo-example" title="Github - Hazelcast Kryo Example">github project</a>.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/7I9g90kDPLo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/efficient-java-serialization/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://open.bekk.no/efficient-java-serialization/</feedburner:origLink></item>
		<item>
		<title>Utvikle smidige ledere – lede smidige utviklere</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/1qViQgP5vr0/</link>
		<comments>http://open.bekk.no/utvikle-smidig-ledere-lede-smidige-utviklere/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 17:08:57 +0000</pubDate>
		<dc:creator>Christer Løvaas</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[IT-rådgivning]]></category>
		<category><![CDATA[Ledelse]]></category>
		<category><![CDATA[Prosjektledelse]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[kanban]]></category>
		<category><![CDATA[ledelse]]></category>
		<category><![CDATA[Metodikk]]></category>
		<category><![CDATA[Samarbeid]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[smidig]]></category>
		<category><![CDATA[Teamwork]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8543</guid>
		<description><![CDATA[Finnes det et tankesett som går utenpå kjente smidige metoder. I boken Management 3.0 beskriver Jurgen Appelo hvorfor smidig virker, og hvordan vi kan få det til å virke enda bedre. Smidig ledelse Forfatteren tar på seg ambisjonen det er å beskrive de mer grunnleggende egenskapene i de smidige metodene vi kjenner. Han beskriver hvordan [...]]]></description>
			<content:encoded><![CDATA[<p>Finnes det et tankesett som går utenpå kjente smidige metoder. I boken Management 3.0 beskriver Jurgen Appelo hvorfor smidig virker, og hvordan vi kan få det til å virke enda bedre.</p>
<h3>Smidig ledelse</h3>
<p>Forfatteren tar på seg ambisjonen det er å beskrive de mer grunnleggende egenskapene i de smidige metodene vi kjenner. Han beskriver hvordan vi både kan lede prosjekter og team bedre. Appelo tar utgangspunkt i forskningsbaserte metoder og funn, og setter den smidige tenkningen i perspektiv. Han peker på en retning for å utvikle en mer helhetlig modell for ledelse basert på suksessen smidige metoder har hatt både innenfor systemutvikling, produksjonsprosesser og tjenesteyting.</p>
<h3>Helhetlig tilnærming</h3>
<p>Gjennom å delta i og lede smidige systemutviklingsprosjekter har jeg vært borti flere ulike modeller for smidig utvikling. Det være seg timeboksbaserte metoder som <a href="http://www.scrum.org/what-is-scrum">Scrum</a> og <a href="http://www.extremeprogramming.org/">XP</a>, eller flytbaserte som <a href="http://www.lean.org/whatslean/">Lean</a> og <a href="http://en.wikipedia.org/wiki/Kanban_(development)">Kanban</a>. Alle modellene har elementer som er gode og dårlige, og det har etterhvert utviklet seg en praksis hvor utviklerteam og prosjekter tar elementer fra ulike smidige teknikker og setter sammen etter teamets og leverandørenes smak. Av og til oppstår energitappende &#8220;religionsdebatter&#8221; om metoder og teknikker. Apellos bok beskriver et tankesett som frigjør oss fra spesifikke metoder. Med en helheltlig tilnærming beskriver han hvorfor smidig virker, og hvordan vi kan få det til å virke enda bedre.</p>
<p>Appelos utgangspunkt er at alle tradisjonelle ledelsesmodeller er fokusert rundt optimalisering (1.0) og suboptimalisering (2.0) av <a href="http://no.wikipedia.org/wiki/Determinisme">deterministisk</a> tenkning og <a href="http://no.wikipedia.org/wiki/Hierarki">hierarkiske </a>strukturer. Han mener, og eksemplifiserer at, de tradisjonelle ledelsesmodellene har bevist sin utilstrekkelighet og beskriver svært overbevisende en ny modell han kaller Ledelse 3.0. Nøkkelbegrepet er <a href="http://no.wikipedia.org/wiki/Kompleksitet">kompleksitet</a>.</p>
<h3>Seks hovedegrener</h3>
<p>Modellen Appelo har laget for Ledelse 3.0 har han kalt &#8220;Martie&#8221;. I boken ser han mer detaljert på hver av disse grenene:</p>
<div id="attachment_8548" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-8548 " src="http://open.bekk.no/wp-content/uploads/2012/03/Martie_Mgmt30_Appelo-300x271.png" alt="Martie, Management 3.0, Appelo, Complexity" width="300" height="271" /><p class="wp-caption-text">Management 3.0</p></div>
<ul>
<li>Energizing people<br />
Hva er det som får mennesker til å &#8220;tikke og gå&#8221;?</li>
<li>Empower teams<br />
Hvordan kan en gruppe gjøres selvstendig og å ta sine egne beslutninger?</li>
<li>Allign constraints<br />
Hvordan beskrive rammebetingelser slik at de kan sees på som hensiktsmessige og ikke som hindringer?</li>
<li>Develop competance<br />
Hvorfor er kompetanse så viktig?</li>
<li>Grow structure<br />
Hvordan styrer man komplekse strukturer når de blir store?</li>
<li>Improve everything<br />
Hvordan jobbe med læring i komplekse organisasjoner?</li>
</ul>
<p>Forfatteren diskuterer en forståelse av menneskelig samspill og kommunikasjon basert på psykologiske og biologiske fakta. <a href="http://no.wikipedia.org/wiki/Determinisme">Determinisme</a>, <a href="http://no.wikipedia.org/wiki/Kompleksitet">kompleksitetsteori</a>, <a href="http://no.wikipedia.org/wiki/Reduksjonisme">reduksjonisme og holisme</a> er alle begreper som omtales. Som eksempel bruker forfatteren bl.a vannets egenskaper. Man kan ikke ved å beskrive vann etter formelen H2O forklare (på en enkel måte) vannets oppførsel og egenskaper. Summen av argumentene er at det gir mening å legge en kompleks modell til grunn for en smidig planlegging og styring av menneskelig aktivitet og interaksjon. For å forutse adferden til slike strukturer , og lede dem, bør man forstå hvilke egenskaper som kjennetegner dem. Mange av de teoriene vi kjenner fra smidige metoder kan gjenkjennes fra denne grunntenkningen.</p>
<h3>Heller tankegang enn metode</h3>
<p>Jeg har jobbet med smidige systemutviklingsprosesser siden 2006. Det begynner å bli lenge siden <a href="http://agilemanifesto.org/">Agile Manifesto</a> ble skrevet (2001). For meg var det veldig stimulerende å lese en bok hvor jeg drar kjensel på utfordringene i prosjekthverdagen, og forstå hvorfor disse utfordringen oppstår. For meg bidro boken til å bygge bro over de smidige metodesiloene.</p>
<p>Anbefalt lesning for alle som jobber med smidig ledelse: <a href="http://amzn.to/FQjtWE">Management 3.0; Leading agile deveolopers &#8211; Developing agile leaders av Jurgen Appelo</a></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/1qViQgP5vr0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/utvikle-smidig-ledere-lede-smidige-utviklere/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/utvikle-smidig-ledere-lede-smidige-utviklere/</feedburner:origLink></item>
		<item>
		<title>Å være kundesentrisk er mer enn å tilby god kundeservice</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/jmhuUVmbuxQ/</link>
		<comments>http://open.bekk.no/kundesentrisk/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 14:42:11 +0000</pubDate>
		<dc:creator>Elisabeth Rønneberg</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Kundefokus]]></category>
		<category><![CDATA[kundeorientering]]></category>
		<category><![CDATA[kunder]]></category>
		<category><![CDATA[Kundesentrisk]]></category>
		<category><![CDATA[Kundeservice]]></category>
		<category><![CDATA[Kundestrategi]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8523</guid>
		<description><![CDATA[Et stadig økende antall bedrifter proklamerer at de er kundesentriske eller kundeorienterte. Jeg våger allikevel å påstå at det fortsatt knyttes stor usikkerhet til hva som ligger i begrepet kundesentrisk, hvilket forretningsmessig potensial som ligger der og hva som skiller en kundesentrisk strategi fra en mer tradisjonell produktsentrisk strategi. Stadig flere spør kunden jevnlig om [...]]]></description>
			<content:encoded><![CDATA[<p><em>Et stadig økende antall bedrifter proklamerer at de er kundesentriske eller kundeorienterte. Jeg våger allikevel å påstå at det fortsatt knyttes stor usikkerhet til hva som ligger i begrepet kundesentrisk, hvilket forretningsmessig potensial som ligger der og hva som skiller en kundesentrisk strategi fra en mer tradisjonell produktsentrisk strategi.</em></p>
<p>Stadig flere spør kunden jevnlig om hun liker produktet som tilbys, hva hun liker og ikke liker ved produktet og hvordan produktet kan tilpasses kunden bedre. Dette innebærer “å se på kunden gjennom objektivet av produktet” og er etter min mening ikke tilstrekkelig til å kunne si at man har en kundesentrisk tilnærming. Hva skiller da kundesentriske organisasjoner fra andre bedrifter som proklamerer sitt kundefokus?</p>
<p>Kort fortalt vil jeg si at kundesentriske organisasjoner har flyttet seg forbi tradisjonell kundeservice til å re-orientere hele forretningsmodellen rundt kunden, og gjennom dette øke kundetilfredsheten og sin egen lønnsomhet. Kundesentriske bedrifter forstår ikke bare hva kundene verdsetter, men også hvilken verdi den enkelte kunde utgjør av bunnlinjen. Kundesentriske selskaper orienterer forretningsmodellen etter en kundestrategi som gir svar på hvilke kunder bedriften skal prioritere. I tillegg skreddersyr de forretningsprosesser, eksempelvis produktutvikling og kundepleie, for å levere størst mulig verdi til de mest verdifulle kundene for minst mulig kostnad. Sentrale elementer av det å være kundesentrisk er:</p>
<h6><strong>God kundeservice</strong></h6>
<p>God kundeservice alene gjør ikke en bedrift kundesentrisk, men den sikreste måten å miste en kunde på er å få ham til å føle at du ikke bryr deg om ham. Å tilby god service og spørre etter tilbakemeldinger fra kunder er derfor en av flere viktige elementer av det å være kundesentrisk.</p>
<h6><strong>Differensiert tilbud til kundene</strong></h6>
<p>En kundesentrisk organisasjon bør være imøtekommende, og utvikle nye varer og tjenester for de mest lønnsomme kundene og ikke nødvendigvis for de andre kundene. Det vil ikke si at man skal ignorere kunder, si opp kunder eller håndtere dem dårlig. Det handler om å differensiere innsatsen mot ulike kundesegmenter. Denne differensieringen av tilbudet til kundene medfører knallhard prioritering og fokus på verdiskapning.</p>
<h6><strong>Kundeorientert organisering</strong></h6>
<p>Skal man differensiere tilbudet til kundene innebærer dette også i mange tilfeller at bedriften må organiseres med hensyn på kundene &#8211; ikke med hensyn på produktene.</p>
<h6><strong>Kundeorienterte produkter </strong></h6>
<p>En kundesentrisk tilnærming innebærer at man tenker på hvem kundene er, og hvordan man kan være tjenestetilbyder innenfor de problemområdene som kundene står ovenfor. En kundesentrisk bedrift ønsker å løse disse problemene for kundene, og finne frem til en best mulig måte å gjøre det på, fremfor å fokusere på å selge enkeltprodukter til kundene. I et kundesentrisk bank/finans-konsern vil man, eksempelvis, fokusere på hvordan man kombinerer produkter fra forsikring, bank og fond for samlet å skape en god løsning for kunden. Kundene forventer at produktene tilpasses deres individuelle behov, og de forskjellige produktmiljøene vil da samarbeide om løsningen.</p>
<p>Jeg mener med andre ord at kundesentrisk er mer enn bare det å gi god kundeservice. Hva legger du i begrepet kundesentrisk?</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/jmhuUVmbuxQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/kundesentrisk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/kundesentrisk/</feedburner:origLink></item>
		<item>
		<title>Do you use an IoC container?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/D-BfRPwpxfU/</link>
		<comments>http://open.bekk.no/do-you-use-an-ioc-container/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 11:05:12 +0000</pubDate>
		<dc:creator>Mats Mortensen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Systemarkitektur]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[IoC]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8287</guid>
		<description><![CDATA[If your answer to this question is “no”, then why not? An IoC container will make your life easier and help you develop more SOLID decoupled software. We have been using an IoC container on our project for a while now and it has been a very positive experience. I might even argue that it has changed my perception on how to develop software [...]]]></description>
			<content:encoded><![CDATA[<p><strong>If your answer to this question is “no”, then why not? An IoC container will make your life easier and help you develop more <a href="http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29">SOLID</a>, decoupled software. We have been using an IoC container on our project for a while now and it has been a very positive experience. I might even argue that it has changed my perception on how to develop software!</strong></p>
<h4>Introduction</h4>
<p>I wanted to share some of what I have learned about IoC containers, not only because I believe they help you create better software, but also because I struggled for a while to really understand the concept and what I was gaining by using one. An IoC container is closely related to <a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency injection (DI)</a> where you inject objects into a class instead of creating the objects inside the class. You can basically think of an IoC container as a tool that helps you do this in a more flexible and customizable way.</p>
<p>So what exactly is Inversion of Control (IoC)? <a href="http://en.wikipedia.org/wiki/Inversion_of_control">Inversion of Control</a> is a principle that states that the flow of control is somehow inverted from regular procedural programming. It is a general concept that applies to systems where some framework takes control of the code execution and calls back into your code. IoC containers make use of this principle, but in my opinion they might as well have been called dependency injection (DI) containers because this is the pattern they help you implement.</p>
<h4>Don’t repeat yourself!</h4>
<p>Before I get more into IoC containers, let’s start with a simple dependency injection example. I will assume that you are familiar with DI and are aware of the advantages of constructor injection If not, I recommend reading <a href="https://github.com/ninject/ninject/wiki/Dependency-Injection-By-Hand">this short intro to DI</a> and then <a href="http://misko.hevery.com/code-reviewers-guide/">this guide about writing testable code</a>.</p>
<p>Lets say we are creating a pirate game and want to create Jack Sparrow’s pirate ship, the Black Pearl. Jack Sparrow is injected into the ship’s constructor along with a crew to help him sail the ship. As any decent pirate captain, Sparrow needs a sword and a treasure map, both of which are injected into his constructor. Without using an IoC container the code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">IShip ship <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> BlackPearl<span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> JackSparrow<span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> Sword<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> TreasureMap<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> Crew<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span></pre></div></div>

<p>In this simple example the BlackPearl depend on two interfaces; the ICaptain and ICrew which Sparrow and Crew implement. Looks fairly reasonable right? But what do you do if you want to use the BlackPearl in many different places in your code? The worst approach would be to violate the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> principle and just copy the code to wherever you need it. Don’t worry, I won’t waste time explaining why that is a bad idea! A much better approach would be to create a BlackPearl factory that creates BlackPearl objects for you. Using this approach, if the BlackPearl changes and needs another class to be injected, you only need to update the code found in the factory.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> BlackPearlFactory<span style="color: #008000;">&#123;</span>
   IShip Create<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
       <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">new</span> BlackPearl<span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> JackSparrow<span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> Sword<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> TreasureMap<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">new</span> Crew<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
   <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The factory pattern is nice, but what if you need Sparrow and the crew in other classes than the BlackPearl? You might create a few more factories that look similar to this one, but they would create other types of objects that also depend on Sparrow and maybe the Crew. This probably seems reasonable, but there is a problem. You are still repeating yourself. Every time you write new JackSparrow() more than once you are repeating yourself. If Sparrow suddenly wants a bottle of grog to be injected you have to update all the places where you have new’ed him up. When the number of classes increase and the dependency tree grows, this quickly becomes a maintenance nightmare. It will also become an incentive to keep adding code to existing classes (violating the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">SRP</a>) when you should be creating new, small classes with specific responsibilities!</p>
<h4>A way out of this mess</h4>
<p>This is where IoC containers come to the rescue and give you a solution to this problem. You basically outsource the responsibility for creating objects to an IoC container which can, with a bit of configuration, give you any object with all necessary dependencies injected for you. If we return to the last example and leave out some configuration details you would be able to create the BlackPearl like this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">IShip ship <span style="color: #008000;">=</span> container<span style="color: #008000;">.</span><span style="color: #0000FF;">Resolve</span><span style="color: #008000;">&lt;</span>IShip<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>The IoC container would be smart enough to first create the Sword and TreasureMap, and inject them into a new instance of JackSparrow. Then it would create the Crew and inject both JackSparrow and the Crew into a new instance of the BlackPearl which would finally be returned back to you from the Resolve method call. The container takes care of creating all the dependencies for the BlackPearl that you normally would have to create yourself. This saves you a lot of work, especially later when you want to make changes to your code. For instance, if you want to remove an injected dependency from the constructor of a class that is managed by the IoC container you can just remove it and update the code in that class accordingly. The IoC container will simply skip injecting that dependency when it creates an instance of the class and since the container is the only one (except for maybe unit tests) that knows about the constructor, the rest of the code won’t even know that this change happened!</p>
<h4>How does it work?</h4>
<p>If you are new to IoC containers you might be wondering how the container creates instances of other classes, especially when the types that are injected into the constructor are interfaces. All IoC containers must be configured so that they can identify all injected types and be able to map interfaces to specific class implementations. The configuration is usually written in code or in some kind of XML based configuration file. If it is done in code you typically use a “fluent” API which makes the configuration code very easy to read. There are pros and cons to either approach, but I cannot possibly understand why people still use XML for this unless it is for legacy reasons.</p>
<p>Here is how you would register a single dependency in Castle Windsor, currently my IoC container of choice, using its fluent registration API:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">container<span style="color: #008000;">.</span><span style="color: #0000FF;">Register</span><span style="color: #008000;">&#40;</span>Component<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&lt;</span>IShip<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ImplementedBy</span><span style="color: #008000;">&lt;</span>BlackPearl<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Castle Windsor now knows that when an instance of the interface IShip is needed it can provide it by creating an instance of the BlackPearl class using reflection. In order for interfaces to be resolved and dependencies to be injected automatically they must all be registered in the container. For example, in order to resolve the BlackPearl in the previous example you would have to add the following registrations:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">container<span style="color: #008000;">.</span><span style="color: #0000FF;">Register</span><span style="color: #008000;">&#40;</span>Component<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&lt;</span>ICaptain<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ImplementedBy</span><span style="color: #008000;">&lt;</span>JackSparrow<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
container<span style="color: #008000;">.</span><span style="color: #0000FF;">Register</span><span style="color: #008000;">&#40;</span>Component<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&lt;</span>ISword<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ImplementedBy</span><span style="color: #008000;">&lt;</span>Sword<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
container<span style="color: #008000;">.</span><span style="color: #0000FF;">Register</span><span style="color: #008000;">&#40;</span>Component<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&lt;</span>ICrew<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ImplementedBy</span><span style="color: #008000;">&lt;</span>Crew<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
container<span style="color: #008000;">.</span><span style="color: #0000FF;">Register</span><span style="color: #008000;">&#40;</span>Component<span style="color: #008000;">.</span><span style="color: #0600FF; font-weight: bold;">For</span><span style="color: #008000;">&lt;</span>ITreasureMap<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ImplementedBy</span><span style="color: #008000;">&lt;</span>TreasureMap<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>If you have been paying attention you might be thinking that this example is flawed because if we do it this way we can only have one type of ship, one type of sword, etc. And you would be right! If you wanted to create different implementations of IShip you would still have to create a factory even when using an IoC container. However, in order to keep things simple, this example assumes there is only one implementation for each interface. </p>
<h4>“Don’t call us, we’ll call you!”</h4>
<p>By now you probably think this is so awesome that you want to just run off and start using an IoC container in your project, but wait one second! A classic mistake is to use an IoC container directly to resolve whatever you need anywhere and everywhere! It is NOT how it is intended to be used. Use the container according to the Hollywood principle; Don’t call the container, it’ll call you!</p>
<p>What does that even mean? It means that you should resolve classes directly from the container in as few places as possible, preferably only one place and let the container automatically create instances of all other classes. Typically you should only need to use the container when you initialize your application and maybe to respond to events that you are not in control of. For instance, if you use it in a web application you should keep the container available as a singleton and use it directly to service a http request, but only once for each request. The reason it is called the Hollywood principle is the same reason it is called inversion of control; when you resolve a class or interface from the IoC container it takes control of the code execution and calls back into your constructor code for every class instance it creates.</p>
<h4>Final thoughts</h4>
<p>I have barely scratched the surface of what is possible with IoC containers and I have deliberately left out many details concerning their use and how they work, but hopefully this is enough to inspire some of you to find out more. If you are a .net developer I recommend you to check out <a href="http://docs.castleproject.org/Windsor.MainPage.ashx">Castle Windsor</a>, <a href="http://structuremap.net/structuremap/">StructureMap</a>, <a href="http://www.ninject.org/">Ninject</a> or <a href="http://code.google.com/p/autofac/">Autofac</a>. They are all excellent IoC containers. If you for some reason don’t want to use an existing IoC container why not <a href="http://ayende.com/Blog/archive/2007/10/20/Building-an-IoC-container-in-15-lines-of-code.aspx">create one yourself in 15 lines of code?</a></p>
<p>In case you are still confused about what IoC is and how it relates to IoC containers, I think <a href="http://stackoverflow.com/questions/1362962/when-not-to-use-ioc-and-di">Bernard over at Stackoverflow sums it up nicely</a>:</p>
<blockquote><p>Inversion of Control = Marriage<br />
IoC Container = Wife</p>
<p>Marriage is the definition of a known pattern &#8211; Wife is the implementation of that pattern <img src='http://open.bekk.no/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p></blockquote>
<p>Enjoy!</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/D-BfRPwpxfU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/do-you-use-an-ioc-container/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/do-you-use-an-ioc-container/</feedburner:origLink></item>
		<item>
		<title>Slik lykkes du med modernisering av virksomheten</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/Im_-IzH7AlQ/</link>
		<comments>http://open.bekk.no/slik-lykkes-du-med-modernisering-av-virksomheten/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 22:10:24 +0000</pubDate>
		<dc:creator>Eric Mortensen</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[IT-rådgivning]]></category>
		<category><![CDATA[modernisering]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8337</guid>
		<description><![CDATA[Modernisering står høyt på agendaen hos mange ledere. Det blir stadig viktigere for bedrifter å utvikle evnen til å videreutvikle sine produkter og tjenester for å møte skiftende kundebehov, samtidig som en skal møte krav og forventninger om en stadig mer effektiv drift. Dette krever kontinuerlig videreutvikling av effektive kunde- og internprosesser, og ikke minst [...]]]></description>
			<content:encoded><![CDATA[<p>Modernisering står høyt på agendaen hos mange ledere. Det blir stadig viktigere for bedrifter å utvikle evnen til å videreutvikle sine produkter og tjenester for å møte skiftende kundebehov, samtidig som en skal møte krav og forventninger om en stadig mer effektiv drift. Dette krever kontinuerlig videreutvikling av effektive kunde- og internprosesser, og ikke minst fleksible og dynamiske IT-systemer.</p>
<p>En vanlig felle å gå i er å fokusere for mye på IT-systemer, og for lite på prosesser og kunder. Mange tenker at hvis vi bare erstatter systemene våre så kommer resten av seg selv. Det hadde vært veldig behagelig om det var så vel, men dette er en farlig vei å gå. IT-systemer i seg selv løser ingenting. Systemene må passe inn i de riktige prosessene, og prosessene er riktig når de løser kundenes behov mest mulig effektivt. Formålet med modernisering er derfor å re-etablere hvordan vi jobber, for å kunne skape mer verdi for kundene. Dette krever et godt samspill mellom kunder, prosesser og systemer.</p>
<p><strong>Kunder</strong>: Bedrifter er til for kunder og ikke omvendt. Hva er de vesentligste driverne for kundene deres i dag og i fremtiden? Ønsker de gode kjøps- og bruksopplevelser? Gode produkter? Råd og veiledning? Lave priser? Ja faktisk &#8211; hvem er kundene? Er de alle like? Er det forskjeller i hvordan de ønsker å betjenes? Og gitt bedriftens egne strategiske mål – hva er det viktig for dere at dere lykkes med? Bundling av flere produkter og tjenester for å øke kundelønnsomheten? Effektivisere kundebetjeningen? Uansett om du velger å tenke overflatisk eller tenke grundig gjennom dette vil det være en viktig øvelse å gjøre.</p>
<div id="attachment_8340" class="wp-caption alignright" style="width: 310px"><a href="http://open.bekk.no/wp-content/uploads/2012/03/modernisering.png"><img class="size-medium wp-image-8340" src="http://open.bekk.no/wp-content/uploads/2012/03/modernisering-300x233.png" alt="" width="300" height="233" /></a><p class="wp-caption-text">Vellykket modernisering krever et samspill mellom kunder, prosesser og systemer</p></div>
<p><strong>Prosesser</strong>: Kjernen i all kommersiell virksomhet er å dekke kundenes behov mest mulig ressurseffektivt. Et viktig spørsmål å avklare er om dette først og fremst handler om å redusere ressursbruken og øke lønnsomheten gitt dagens kundeomsetning, eller om det også handler om å skalere opp dagens operasjoner og sikre at dagens prosesser kan ta unna for en forventet kundevekst? Et annet viktig spørsmål er hvilke muligheter vi har for å forbedre prosessene – gjennom å utnytte teknologi til for eksempel digitalisering, automatisering, samhandling eller informasjons- og kunnskapsdeling. Og hvilke muligheter har vi rett og slett for å gjøre ting enklere – med eller uten teknologi?</p>
<p><strong>Systemer</strong>: En modernisering krever til syvende og sist en utskiftning eller større videreutvikling av IT-systemer. En vellykket modernisering krever at fremtidens IT-systemer samspiller godt med hverandre og med hvordan bedriften ønsker å jobbe. Moderne IT-systemer må ikke bare understøtte effektive prosesser og møte bedriftens strategiske behov. De må også være kostnadseffektive i drift. Og enda viktigere er det at de understøtter en fleksibilitet og en smidighet som sikrer at dere har muligheten til å snu dere rundt når markedet og kundene sine behov atter igjen skifter retning. Systemene må være tilpasset prosessene, men prosessene må ofte også tilpasses systemene. Dette gjelder særlig ferdigutviklet programvare som kjøpes inn for å tilpasses bedriftens ønskede arbeidsform.</p>
<p>Mange starter moderniseringsarbeidet med det konkrete systemet de opplever som flaskehalsen. En slik systemorientert innfallsvinkel kan gi mer effektive systemer, men det gir også lite rom for å tenke nytt rundt hvilke behov kundene våre har som vi må løse, eller hvordan vi skal utforme arbeidshverdagen til våre medarbeidere slik at de enklest mulig kan møte kundenes behov. En modernisering som kun fokuserer på systemet reproduserer bare gamle prosesser i nye farger. En vellykket modernisering av prosesser og systemer avhenger derfor av et helhetlig samspill mellom kundebehov, prosesser og IT-systemer.</p>
<p>Lykkes man med dette samspillet gir det desto større muligheter for store gevinster.<br />
• <strong>Økt inntjening og verdiskapning</strong> gjennom prosesser, systemer og kundeløsninger som skaper betydelig merverdi for virksomheten og kundene og som reduserer graden av manuelt arbeid<br />
•<strong> Redusert time-to-market</strong> og reduserte kostnader gjennom prosesser, systemer og kundeløsninger som gir økt fleksibilitet, økt smidighet og økt endringsevne<br />
• <strong>Mer kostnadseffektiv systemforvaltning</strong> gjennom systemer og løsninger som er moderne, tjenesteorienterte og helhetlige</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/Im_-IzH7AlQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/slik-lykkes-du-med-modernisering-av-virksomheten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/slik-lykkes-du-med-modernisering-av-virksomheten/</feedburner:origLink></item>
		<item>
		<title>NTNU vant Oppdraget 2012 – gratulerer!</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/LnvqO7RIw_k/</link>
		<comments>http://open.bekk.no/ntnu-vant-oppdraget-2012-gratulerer/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 09:31:34 +0000</pubDate>
		<dc:creator>Eldri Coll Mossige</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8253</guid>
		<description><![CDATA[Etter 24 timers intensiv jobbing presenterte lagene fra BI, NHH og NTNU sine løsninger for juryen fredag formiddag. Med 20 minutter til rådighet skulle hvert lag overbevise juryen om at deres fremtidsrettede og bærekraftige tiltak vil gjøre NSB til kundens favoritt innen 2015. - Vi er imponerte over hva alle lagene har klart å komme [...]]]></description>
			<content:encoded><![CDATA[<p>Etter 24 timers intensiv jobbing presenterte lagene fra BI, NHH og NTNU sine løsninger for juryen fredag formiddag. Med 20 minutter til rådighet skulle hvert lag overbevise juryen om at deres fremtidsrettede og bærekraftige tiltak vil gjøre NSB til kundens favoritt innen 2015. </p>
<p><em>- Vi er imponerte over hva alle lagene har klart å komme fram til i løpet av den korte tiden dere har hatt til rådighet</em>, sa juryleder Harald Krogh, avdelingsleder i Bekk Management Consulting, da han foran spente studenter skulle utrope vinnerlaget. I juryen hadde han med seg konsernsjef i NSB, Geir Isaksen, konserndirektør for strategi og forretningsutvikling Arne Fosen og administrerende direktør i Bekk Consulting, Olav Folkestad. </p>
<p>NTNU ble utropt som vinnerlag til applaus fra juryen og de andre deltakerne. Dette er tredje gang NTNU har gått av med seieren gjennom Oppdragets femårige historie. Juryen forklarte at det som skilte NTNU fra de andre lagene var lagets evne til å tenke helhetlig løsning gjennom gode og gjennomarbeidede tiltak. For seieren mottar NTNU-laget 25 000 kroner, samt 25 000 kroner fra NSB som laget har valgt å donere til Norges Røde Kors sitt prosjekt ”Vann for livet”.  </p>
<p>NTNU-laget forklarte konsernsjef Geir Isaksen i NSB at Røde Kors sitt prosjekt ble valgt fordi organisasjonen har vist en evne til å få mest mulig ut av hver bidragskrone.   </p>
<p>Vinnerlaget består av Einar Bjering, Maren Omli Flasnes, Erling Laugsand og Maria Tandberg Nygård, alle fjerdeårsstudenter ved Industriell økonomi og teknologiledelse på NTNU.  </p>
<p>BEKK ønsker å takke alle studentene for strålende innsats under Oppdraget og NSB for spennende problemstilling og stort engasjement. </p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/LnvqO7RIw_k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/ntnu-vant-oppdraget-2012-gratulerer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/ntnu-vant-oppdraget-2012-gratulerer/</feedburner:origLink></item>
		<item>
		<title>Slik får du Axure-prototypene dine til å fungere på mobil og nettbrett</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/rItougKUZY0/</link>
		<comments>http://open.bekk.no/prototyping-for-mobil-og-nettbrett/#comments</comments>
		<pubDate>Sat, 18 Feb 2012 22:12:49 +0000</pubDate>
		<dc:creator>Kjell Lybeck</dc:creator>
				<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[Axure]]></category>
		<category><![CDATA[Brukertesting]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobil]]></category>
		<category><![CDATA[Nettbrett]]></category>
		<category><![CDATA[Prototyping]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8199</guid>
		<description><![CDATA[Kjære kunde, “mobile first”… I dag er det mer og mer vanlig å etablere seg i flere kanaler, men ikke alle er helt der enda. Morgan Stanley presenterte for en stund tilbake trender som sier at 91% av mobilbrukerne har mobilen innen 1 meters rekkevidde. Det nye “buzz wordet” er “mobile first”. The Economist presenterer [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center"><a href="http://open.bekk.no/wp-content/uploads/2012/02/IphoneIpad.jpg"><img class="size-full wp-image-8248 aligncenter" src="http://open.bekk.no/wp-content/uploads/2012/02/IphoneIpad.jpg" alt="" width="500" height="400" /></a></p>
<h2><strong>Kjære kunde, “mobile first”…</strong></h2>
<p>I dag er det mer og mer vanlig å etablere seg i flere kanaler, men ikke alle er helt der enda. Morgan Stanley presenterte for en stund tilbake trender som sier at 91% av mobilbrukerne har mobilen innen 1 meters rekkevidde. Det nye “buzz wordet” er “mobile first”. The Economist presenterer frisk statistikk som “Every 4 seconds a child is born… and 15 mobile phones are sold”. Det er på tide å gjøre noe, ta noen valg.</p>
<p>Men mange forbinder “flerkanaleri” med økt kostnad, og man kvier seg litt. Hva om man prototyper en mobil løsning først, dette er jo raskt og enkelt å få til. I samme slengen kan man brukerteste det man lager for å få svar på om det man tenker fungerer på ordentlig.</p>
<p>Dette er vel dyrt? Egentlig ikke. Det blir en “Lakmustest” før man lager en ekte løsning, noe som er langt billigere enn å prøve å feile med ekte løsning.</p>
<p>Her er en oppskrift for hvordan man skaper en øyenåpner for kunden.</p>
<p>&nbsp;</p>
<h2><strong>“Weapon of choice”</strong></h2>
<p><strong></strong><a title="Axure" href="http://www.axure.com/" target="_blank">Axure RP Pro</a> er et kraftig verktøy for prototyping av interaktive webløsninger. Når man skal lage prototyper tilpasset mobile enheter som iPhone og iPad er det noen hensyn du må ta for at prototypen skal fremstå korrekt i nettleseren på mobilen eller nettbrettet ditt.</p>
<p>Axure kan benyttes til å lage alt fra enkle skisser og wireframes til mer avanserte klikkbare og dynamiske prototyper. Verktøyet har et drag-and-drop widgets bibliotek hvor man enten kan benytte standardbibliotekene som følger med fra leverandøren, eller man kan tilpasse og lage egne bibliotek. Bibliotekene gjør at verktøyet er enkelt å bruke og man kan lage omtrent hva som helst, raskt, uten å skrive en eneste linje kode.</p>
<p>&nbsp;</p>
<h2><strong>Prototypen</strong></h2>
<p>Vi valgte å prototype løsningen med en “standard mobil skjermbredde” på 320 pixler.</p>
<p>I prosjektet hvor vi første gang prototypet en mobil løsning, oppdaget vi at prototypen ble svært liten på mobilen når vi la den ut på webserveren. Mobilen vi testet på var en iPhone 4. Alt innhold ble svært lite og det ble presset opp i venstre hjørne som et frimerke slik skjermbildet under lengst til venstre viser.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPhoneNoHTML1.jpg"><img class="size-full wp-image-8207 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPhoneNoHTML1.jpg" alt="" width="757" height="470" /></a></p>
<p>&nbsp;</p>
<p>Dette var verken realistisk eller optimalt i forhold til brukertesten vi hadde planlagt å gjennomføre. Vi prøvde derfor å løse problemet ved å øke størrelse på tekst og på skjermbredden i Axure til 480 pixler. Det ble litt bedre, men fremdeles ikke helt optimalt. Skjermbildet i midten over viser denne justeringen.</p>
<p>Vi fortsatte å eksperimentere til vi fant en mer optimal skjermstørrelse og landet på skjermstørrelsen 768 pixler. Skjermbildet over lengst til høyre illustrerer dette.</p>
<p>Lærdom: Vi hadde brukt lang tid med mye prøving og feiling for å komme fram til et resultat som vi ikke var fornøyde med. Vi hadde nå en prototyp som så grei ut på mobil, men som var håpløs å jobbe med i Axure. Den var håpløs fordi alt var gigantisk stort, man mistet oversikten og den var tung å vedlikeholde.</p>
<p>&nbsp;</p>
<h2><strong>“Workaround”?</strong></h2>
<p>Det måtte da finnes en mer effektiv måte å jobbe på. Selvfølgelig gjorde det det. Et søk på Google viste at vi ikke var de eneste som hadde møtt på disse utfordringene. Litt magisk HTML-kode var alt som skulle til. Når man genererer en prototyp i Axure genereres et stort antall HTML-sider. Ved å inkludere en liten kodesnutt på hver av disse sidene i &lt;head&gt;-taggen ble ting løst av seg selv, helt automagisk. I hovedsak var det tre varianter som dekker det meste.</p>
<p>&nbsp;</p>
<h3><strong>1: Automatisk skalering</strong></h3>
<p>Dersom man ikke vet skjermstørrelsen man utvikler for, eller skal vise prototype på forskjellige enheter, er det hensiktsmessig og benytte en kodesnutt hvor skalering skjer automatisk. Den kan se slik ut:</p>
<p>&nbsp;</p>
<p><strong> &lt;meta name = “viewport” content = ” width=device-width “&gt;</strong></p>
<p>&nbsp;</p>
<p>Skjermbildene under viser forskjellen på en prototyp med 320 pixler bredde med og uten kodesnutten i &lt;head&gt;-taggen.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_320px.jpg"><img class="size-full wp-image-8206 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_320px.jpg" alt="" width="511" height="484" /></a></p>
<p>&nbsp;</p>
<p>Skjermbildene under viser forskjellen på en prototyp med 480 pixler bredde med og uten kodesnutten i &lt;head&gt;-taggen</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_480px.jpg"><img class="size-full wp-image-8208 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_480px.jpg" alt="" width="508" height="476" /></a></p>
<p>&nbsp;</p>
<p>Skjermbildene under viser forskjellen på en prototyp med 768 pixler bredde med og uten kodesnutten i &lt;head&gt;-taggen.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_768px.jpg"><img class="size-full wp-image-8209 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPhone_768px.jpg" alt="" width="506" height="480" /></a></p>
<p>&nbsp;</p>
<h3><strong>2: Overstyring</strong></h3>
<p>Ønsker man å overstyre hvordan den mobile enheten skalerer bredden på siden, kan man eksplisitt sette bredden inn i kodesnutten slik:</p>
<p>&nbsp;</p>
<p><strong>&lt;meta name = “viewport” content = “width=356″&gt;</strong></p>
<p><strong> </strong></p>
<h3><strong>3: Begrensninger</strong></h3>
<p>Det er også mulig å sette begrensninger med kode slik at brukeren ikke har mulighet til å øke eller minske skjermstørrelsen. Dette kan gjøres på denne måten:</p>
<p>&nbsp;</p>
<p><strong>&lt;meta name = “viewport” content = “user-scalable=no, width=device-width”&gt;.</strong></p>
<p><strong> </strong></p>
<h2><strong>Eksperiment med iPad</strong></h2>
<p><strong></strong>Vi valgte samtidig å teste hvordan prototypen oppførte seg på en iPad. Vi testet med skjermbreddene 320, 480 og 768 pixler. Breddene 320 og 480 pixler utnyttet ikke iPad’ens skjermstørrelse særlig godt.  Den beste skjermbredden var på 768 pixler.</p>
<p>Under følger skjermbilder av hva vi så når vi testet med de forskjellige skjermbreddene. Vi testet også her med og uten kode for automatisk skalering i &lt;head&gt;-taggen:</p>
<p>&nbsp;</p>
<p><strong>&lt;meta name = “viewport” content = ” width=device-width “&gt;</strong></p>
<p>&nbsp;</p>
<p>Med 320 pixler bredde ble det seende slik ut:</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPad_320px.jpg"><img class="size-full wp-image-8210 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPad_320px.jpg" alt="" width="765" height="512" /></a></p>
<p>&nbsp;</p>
<p>Med 480 pixler bredde ble det seende slik ut:</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPad_480px.jpg"><img class="size-full wp-image-8211 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPad_480px.jpg" alt="" width="768" height="507" /></a></p>
<p>&nbsp;</p>
<p>Med 768 pixler bredde ble det seende slik ut:</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/iPad_768px.jpg"><img class="size-full wp-image-8212 alignnone" src="http://open.bekk.no/wp-content/uploads/2012/02/iPad_768px.jpg" alt="" width="776" height="512" /></a></p>
<p>&nbsp;</p>
<h2><strong>Oppsummering</strong></h2>
<p>Så, var dette nybrottsarbeid? Sikkert ikke, men det gav oss svært nyttige erfaringer. Dette er ikke spesielt komplisert å få til når man har gjort det et par ganger, også var litt gøy også!</p>
<p>Hva har vi lært? Vi vet nå hvordan vi går fram og hvilke verktøy som kan benyttes til å prototype og til å testet mobile webløsninger. Slik vi ser det, men vi kan jo ta feil, så er dette en av de beste måtene å få testet nettopp dette på. Fremtidige prosjekter vil kunne gjennomføres raskt, effektivt og svært realistisk.</p>
<p>Videre vet vi ut i fra eksperimentering med skjermbredder, fontstørrelser og kodesnutter at dersom man skal lage en prototyp som både skal testes på iPhone og iPad bør den lages med en skjermbredde på 768 pixler med kodesnutten for automatisk skalering i &lt;head&gt;-taggen. Skal man kun teste på iPhone fungerer alle skjermbredder så lenge kodesnutten er inkludert.</p>
<p><strong> </strong></p>
<h2><strong>Oppskriften</strong></h2>
<p>1. Lag prototypen i Axure – jobb innenfor “standard mobil skjermbredde” på 320, 480 eller 768 pixler</p>
<p>2. Legg til en av følgende kodesnutter i HTML-filene for prototypen i &lt;head&gt;-tag</p>
<p>&nbsp;</p>
<p><strong>Automatisk skalering: </strong></p>
<p><strong></strong>Dersom man ikke vet skjermstørrelsen man utvikler for, eller skal vise prototype på forskjellige enheter, er det hensiktsmessig og benytte en kodesnutt hvor skalering skjer automatisk. Den vil se slik ut:</p>
<p><strong>&lt;meta name = “viewport” content = ” width=device-width “&gt;</strong></p>
<p>&nbsp;</p>
<p><strong>Overstyring: </strong></p>
<p><strong></strong>Ønsker man å overstyre hvordan den mobile enheten skalerer bredden på siden, kan man eksplisitt sette bredden inn i kodesnutten slik:</p>
<p><strong>&lt;meta name = “viewport” content = “width=356″&gt;</strong></p>
<p>&nbsp;</p>
<p><strong>Begrensninger: </strong></p>
<p><strong></strong>Det er også mulig å sette begrensninger med kode slik at bruker ikke har mulighet til å øke eller minske skjermstørrelsen. Dette kan gjøres på denne måten:</p>
<p><strong>&lt;meta name = “viewport” content = “user-scalable=no, width=device-width”&gt;</strong></p>
<p>&nbsp;</p>
<p>3. Legg prototypen ut på en webserver og åpne den på en iPhone eller iPad</p>
<p>&nbsp;</p>
<p>Lykke til!</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/rItougKUZY0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/prototyping-for-mobil-og-nettbrett/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://open.bekk.no/prototyping-for-mobil-og-nettbrett/</feedburner:origLink></item>
		<item>
		<title>Oppdraget 2012 – hvem klarer å imponere NSB?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/Wy1FFkJxhHY/</link>
		<comments>http://open.bekk.no/oppdraget-2012/#comments</comments>
		<pubDate>Thu, 16 Feb 2012 13:35:21 +0000</pubDate>
		<dc:creator>Eldri Coll Mossige</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Bekk Management Consulting]]></category>
		<category><![CDATA[Case-konkurranse]]></category>
		<category><![CDATA[NSB]]></category>
		<category><![CDATA[Oppdraget]]></category>
		<category><![CDATA[Studentkonkurranse]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8185</guid>
		<description><![CDATA[Oppdraget 2012 er i gang! Tre studentlag fra landets tre største byer står klare til å konkurrere om å gi de beste strategiske rådene til årets oppdragsgiver NSB. Kvalifisering til konkurransen ble  i høst gjennomført ved NHH, BI og NTNU og i dag sparkes finalen i casekonkurransen ”Oppdraget 2012” i gang. Et reelt oppdrag fra [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Oppdraget 2012 er i gang! Tre studentlag fra landets tre største byer står klare til å konkurrere om å gi de beste strategiske rådene til årets oppdragsgiver NSB. Kvalifisering til konkurransen ble  i høst gjennomført ved NHH, BI og NTNU og i dag sparkes finalen i casekonkurransen ”Oppdraget 2012” i gang.</strong></p>
<h4>Et reelt oppdrag fra en reell oppdragsgiver</h4>
<p>Casekonkurransen ”Oppdraget” arrangeres av Bekk Management Consulting for femte gang i år. Studenter fra de tre mest anerkjente merkantile studiene i Norge  konkurrerer om å gi de beste strategiske rådene til store næringslivsaktører.  Årets oppdragsgiver er NSB.</p>
<h4>Gjennomføring og premie</h4>
<p>Konkurransen går over to dager og finner sted i Oslo. I dag er første konkurransedag, og studentene har blitt presentert for problemstillingen og caset. De har også fått tilgang til underlagsmateriell og anledning til å intervjue nøkkelpersoner i NSB-konsernet. Noen av Bekk Management Consultings mest erfarne konsulenter er også tilgjengelige for å veilede dem.<br />
&nbsp;<br />
I morgen skal studentene presentere sine råd og anbefalinger til en jury bestående av NSBs konsernsjef, NSBs konserndirektør for strategi og forretningsutviklingledelse, administrerende direktør i Bekk Consulting og avdelingsleder for Bekk Management Consulting. Laget som imponerer juryen mest får en pengepremie på 25.000 kroner, samt muligheten til å donere tilsvarende beløp til en valgfri veldedig organisasjon.</p>
<h4>Trangt nåløye</h4>
<p>Prosessen for å bli de heldige som får representere sitt studiested under Oppdraget er ikke rett frem. Lagene har sendt inn søknader med motivasjonsbrev og CV’er. Tre lag ved hver studieinstitusjon ble plukket ut til å være med i en kvalifiseringsrunde. Laget fra hver skole med de beste ideene og den mest overbevisende presentasjonen ble deretter invitert videre til finalen.</p>
<h4>Hvem går av med seieren?</h4>
<p>Det ligger prestisje i å vinne Oppdraget, og knivingen mellom skolene er stor. I fjorårsutgaven av Oppdraget var Sparebank 1 oppdragsgiver. Da var det NHH som presenterte de beste strategiske rådene, og donerte kr 25.000 til NHH Aid.  Vil NHH klare å holde på seieren? Vil NTNU ta tilbake gullpallen? Eller vil BI utmerke seg som best? Følg med!</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/Wy1FFkJxhHY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/oppdraget-2012/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/oppdraget-2012/</feedburner:origLink></item>
		<item>
		<title>Hva vil det egentlig si å være kundeorientert?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/2io9TEBNkB4/</link>
		<comments>http://open.bekk.no/hva-er-kundeorientering/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:56:30 +0000</pubDate>
		<dc:creator>Tore Stautland Bjøndal</dc:creator>
				<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[innovasjon]]></category>
		<category><![CDATA[kundeopplevelse]]></category>
		<category><![CDATA[kundeorientering]]></category>
		<category><![CDATA[kundeverdi]]></category>
		<category><![CDATA[strategi]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8137</guid>
		<description><![CDATA[“We’ve entered the age of the customer — an era where a focus on customers matters more than any other strategic imperative” (Forrester Research, 2011)
- men hva er kundeorientering egentlig? For å besvare dette spørsmålet mener jeg at vi må se kundeorientering i lys av en større kontekst. Det er dette temaet som belyses i denne bloggposten.]]></description>
			<content:encoded><![CDATA[<p>Kundeorientering er et uttrykk som er i vinden om dagen, og i oktober 2011 lanserte Forrester Research følgende påstand:</p>
<p><strong>“We’ve entered the age of the customer — an era where a focus on customers matters more than any other strategic imperative”</strong></p>
<p>- men hva er kundeorientering egentlig? For å besvare dette spørsmålet mener jeg at vi må se kundeorientering i lys av en større kontekst. Det er dette temaet som belyses i denne bloggposten.</p>
<h4>Kundeorientering, kundeverdi og kundeopplevelse er <span style="text-decoration: underline">ikke</span> synonymer</h4>
<p>Før vi går videre ønsker jeg å forsøke å rydde opp i noen begreper som ofte brukes om hverandre, nemlig: kundeopplevelse, kundeorientering og kundeverdi. Ved å knytte begrepene til virksomheten, kunden og helheten blir det lettere å skille dem (Se Figur 1).</p>
<p><strong>Kundeverdi</strong> – realiseres først når en kunde benytter seg av det aktuelle produktet eller tjenesten for å få løst den oppgaven han eller hun prøver å løse (”job to be done”). Det er viktig å skille på en virksomhets verdiforslag og reell kundeverdi. Om en virksomhet klarer å levere reell kundeverdi avgjøres av kundens grad av tilfredshet ved utnyttelse av produktet eller tjenesten for å utføre den ønskede oppgaven.</p>
<p><strong>Kundeorientering</strong> – er å innrette organisasjonen, inklusive ledelse, prosesser og kultur, for å effektivt kunne imøtekomme kundenes skiftende behov og preferanser. Kundeorientering er knyttet til de aktivitetene en virksomhet utfører internt, helt fra produksjon og utvikling av varer og tjenester til kundestøtte.</p>
<p><strong>Kundeopplevelse</strong> – kan oppsummeres som helheten av kundeorientering og kundeverdi. Det vil si summen av de inntrykk og erfaringer en kunde får i relasjon med en virksomhet i forhold til sine forventninger. Grunnlaget for kundeopplevelse legges ved alle kontakt- og interaksjonspunkter en kunde har med virksomheten (kundereisen), helt fra et behov for å løse en oppgave oppstår og til denne oppgaven er løst. Og inkluderer også opplevd verdi av de produktene og tjenestene som leveres.</p>
<p>&nbsp;</p>
<div id="attachment_8136" class="wp-caption aligncenter" style="width: 702px"><a href="http://open.bekk.no/wp-content/uploads/2012/02/kundeopplevelse.png"><img class="size-full wp-image-8136 " src="http://open.bekk.no/wp-content/uploads/2012/02/kundeopplevelse.png" alt="" width="692" height="328" /></a><p class="wp-caption-text">Figur 1: Kundeorientering, kundeverdi og kundeopplevelse</p></div>
<h4>Hvorfor har så mange virksomheter nå fokus på å være kundeorientert?</h4>
<p>Den primære driveren for utviklingen i retning kundeorientering er akkurat som uttrykket tilsier: <strong>kunden. </strong>I BEKK har vi identifisert følgende forbrukertrender som påvirker virksomheters behov for å adoptere en kundesentrisk tilnærming til videreutviklingen av deres forretningsmodeller:</p>
<p style="padding-left: 30px"><strong>Den selvbetjente kunden</strong> – dagens kunder rapporterer at tidspresset i hverdagen bare øker og at de trenger nye løsninger for å selv utføre de nødvendige oppgaver ved ledig tid.</p>
<p style="padding-left: 30px"><strong>Den sosiale kunden</strong> – kunden er ikke lenger en selvstendig entitet. Kunder snakker i mye større grad sammen i åpne fora, som ikke kan kontrolleres og sensureres av virksomheter, om sine erfaringer med produkter / tjenester og leverandørene av disse.</p>
<p style="padding-left: 30px"><strong>Den teknologiske kunden</strong> – stadig utvikling og adopsjon av ny teknologi har senket inngangsbarrieren for nye aktører i mange markeder. Dette har medført større utvalg og lavere byttekostnader for kundene, noe som igjen har ført til lavere lojalitet.</p>
<p style="padding-left: 30px"><strong>Den forlangende kunden</strong> – kunden opplever i større grad at de nye aktørene i flere markeder lytter til dem og tilpasser seg deres behov. Dette medfører at den samme forventningen blir gjeldende for etablerte og modne virksomheter.</p>
<p>Kombinasjonen av disse endringene i forbrukeratferd medfører at kundene i større grad tar aktiv stilling til valg av leverandører for de produkter og tjenester som de anskaffer. Dermed blir reell kundeorientering et konkurransefortrinn for å kunne levere på kunders forventning.</p>
<h4>Så hva innebærer det å være kundeorientert?</h4>
<p>I all hovedsak mener jeg at kundeorientering handler om å invitere kunden til dialog rundt alle aspekter av kundeopplevelsen og ta avgjørelser basert på den innsikten som genereres gjennom dialogen. Dialogen bør dekke både:</p>
<ul>
<li>Utvalget og sammensetningen av produkter og tjenester en bedrift tilbyr selv, og i kombinasjon med andre aktører.</li>
<li>Kundeopplevelsen underveis i anskaffelsen og bruken av produktet eller tjenesten.</li>
</ul>
<p>Innsikten bør spesielt rettes inn mot å etablere:</p>
<ul>
<li>Enkle og brukervennlige fysiske og digitale kontaktpunkter</li>
<li>En generell serviceinnstilling i alle kontaktpunkter ut mot kunde</li>
<li>Evne til å omstille seg i henhold til endringer i kundebehov (fremfor en ’push’-mentalitet)</li>
<li>En organisasjonsstruktur som i større grad er basert på kundesegmenter enn siloorienterte produkt/tjeneste-grupperinger</li>
</ul>
<p>Min påstand er at kundeorientering er et virkemiddel for oppnå økt kundeverdi og en bedre kundeopplevelse underveis, og dermed må sees i tett sammenheng med dette. Dersom en virksomhet mangler en tydelig målsetning for hva kundeorientering skal bidra til, vil de sjelden lykkes i arbeidet.</p>
<p>Har du et annet syn på kundeorientering? Kommenter gjerne under eller send meg en epost!</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/2io9TEBNkB4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/hva-er-kundeorientering/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/hva-er-kundeorientering/</feedburner:origLink></item>
		<item>
		<title>Enterprise 2.0 Summit i Paris</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/bvvo8NSFz1g/</link>
		<comments>http://open.bekk.no/enterprise-2-0-summit-i-paris/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:26:28 +0000</pubDate>
		<dc:creator>Line Ånderbakk Olsen</dc:creator>
				<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[Enterprise 2.0]]></category>
		<category><![CDATA[konferanse]]></category>
		<category><![CDATA[sosial programvare]]></category>
		<category><![CDATA[sosiale nettverk]]></category>
		<category><![CDATA[Virksomhet 2.0]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8108</guid>
		<description><![CDATA[Dette var fjerde gang den europeiske Enterprise 2.0 konferansen ble arrangert. Rundt 150 deltakere deltok på denne to-dagers konferansen i Paris i februar. I denne oppsummeringen har jeg delt noe av det jeg satt igjen med fra konferansen. Tilbakemeldingen på Twitter har vært overveldende positiv. Selv sitter jeg inne med et litt annet inntrykk av [...]]]></description>
			<content:encoded><![CDATA[<p>Dette var fjerde gang <a href="http://www.e20summit.com/">den europeiske Enterprise 2.0 konferansen</a> ble arrangert. Rundt 150 deltakere deltok på denne to-dagers konferansen i Paris i februar. I denne oppsummeringen har jeg delt noe av det jeg satt igjen med fra konferansen.</p>
<p>Tilbakemeldingen på Twitter har vært overveldende positiv. Selv sitter jeg inne med et litt annet inntrykk av konferansen, men mer om dette til slutt i oppsummeringen.</p>
<p><a href="http://www.flickr.com/photos/kongressmedia/6852759405/in/pool-1247663@N24/"><img class="alignnone size-full wp-image-8115" src="http://open.bekk.no/wp-content/uploads/2012/02/6852759405_cd4a5f929e_z.jpg" alt="En av de mange paneldebattene under konferansen. Kilde: KongressMedia" width="640" height="325" /></a></p>
<p><strong>Må vi ha et mål med samhandlingen?</strong></p>
<p>Enkelte av foredragsholderne var tydelige på at man må ha et mål med samhandlingen. Veldig forenklet innebærer dette å gå strukturert til verks med behovsanalyser som kartlegger målgrupper, bruksscenarioer eller use cases, identifisere KPI&#8217;er og ta i bruk analytics for å følge med på om løsningen blir brukt slik vi håper på. Sjekk ut <a href="http://www.slideshare.net/rawnshah/understanding-social-business-excellence-enterprise20summit-2012-paris">presentasjonen til Rawn Shah</a> for mer informasjon om dette. Andre foredragsholdere, eller &#8220;praktikere&#8221; som de ble kalt under konferansen, hevdet at dette ikke var like nødvendig. Vi trenger ikke lengre snakke om hvorfor vi gjør dette, men hopp i det og lær underveis.</p>
<p>Hvilken av disse to fremgangsmåtene virksomhetene heller mot, kan ha noe å gjøre med hvor mye erfaring og modenhet de har med sosial programvare og Enterprise 2.0 fra før av. Dersom en er ny innenfor dette, er det kanskje greit å bare hoppe i det for å få i gang samtalene og la ansatte bli vant til å dele og kommunisere med hverandre via et slikt verktøy, mens bedrifter som allerede behersker dette godt ønsker å ta samhandlingen et skritt videre.</p>
<p><strong>Hvor mye governance trenger vi egentlig?</strong></p>
<p>Det ble hevdet at <em>If you don&#8217;t have governance &#8211; it&#8217;s a toy</em> blant en av deltakerne. Hvor mye styring trenger vi egentlig? Svaret er som i mange andre sammenhenger; det kommer ann på.</p>
<p>Ta for eksempel det å opprette et nytt community eller arbeidsområde. Skal ansatte få opprette dette på egen hånd eller er det en moderator som skal ha dette ansvaret? Praksisen blant foredragsholderne var begge deler.</p>
<p>En foredragsholder kunne fortelle at de krevde at ansatte søkte om lov for å få opprettet et nytt community. I søknaden måtte de oppgi hvorfor de trengte dette (mål og KPI), og hvor lenge de hadde behov for det. Foredragsholderen argumenterte med at det var mer frustrerende for brukerne å:</p>
<ul>
<li>ikke finne svar på spørsmål</li>
<li>finne ufullstendige eller utdaterte svar</li>
<li>finne døde commnunities</li>
</ul>
<p>I tillegg til å få oversikt og kontroll over det som er av communities, skapte det også en større forpliktelse blant de ansatte til å holde informasjonen oppdatert og riktig.</p>
<p>Folk har vanskeligheter med å endre vanene sine. En god del av gruppene og arbeidsområdene som opprettes på sosiale plattformer er en gjenspeiling av organisasjonsstrukturen eller andre fysiske grupper som ansatte er medlem i. Dette kan være avdelinger, prosjektgrupper, faggrupper og sosiale grupper som de ansatte er med i. Noen av gruppene er åpne for alle, mens andre grupper er skjulte for dem som ikke er medlem. Vær obs på at &#8220;sosiale siloer&#8221; også kan dannes innad i samme verktøy, og ikke bare mellom ulike sosiale plattformer som ikke snakker sammen.</p>
<p><strong>Ulik grad av modenhet blant organisasjoner</strong></p>
<p>Både deltakere og foredragsholdere som deltok under årets konferanse, hadde ulik grad av erfaring. Enkelte virket ganske fersk på dette området og hadde mange spørsmål som de mer erfarne syns ble for banale og enkle. Fremfor å snakke om &#8220;<em>bør vi tillate kommentering på artikler</em>&#8221; og &#8220;<em>sjefen min blogger</em>&#8220;, viste denne gruppen større interesse for:</p>
<ul>
<li>Integrere sosiale features inn i eksisterende forretningsprosesser og tradisjonelle intranett</li>
<li>Governance</li>
<li>Mobil</li>
<li>Måling og forbedring</li>
</ul>
<p>I de aller fleste bedrifter lever sosiale systemer og forretningskritiske prosesser i to vidt forskjellige verdener. Sosiale løsninger er sjeldent integrert med resten av intranettet, og sosiale siloer oppstår rundt omkring i organisasjoner av forskjellige årsaker. Jane McConnell, forfatter av en årlig intranettundersøkelsen &#8220;<a href="http://www.digital-workplace-trends.com/">Digital workplace trends 2012</a>&#8221; håper vi vil se en bedring på dette området i årene som kommer. Sjekk ut presentasjonen hennes for å se hvilke <a href="http://www.slideshare.net/NetStrategyJMC/digital-workplace-trends-2012">trender en kan forvente å se på arbeidsplassen</a> i året som kommer.</p>
<p><strong>Finnes det en beste praksis?</strong></p>
<p>Et av trackene under konferansen het &#8220;Best-Practices&#8221;.  Lyis Suarez som var en av foredragsholderne kom med denne tweeten &#8220;<em>#e20s Seriously, best practices need to disappear from E2.0; there aren&#8217;t best practices! What works for some won&#8217;t work for others</em>&#8220;. Denne tweeten spredte seg som ild i tørt gress og ble mye nevnt under de resterende foredragene. Poenget hans var at det finnes gode praksiser, men ingen beste praksis. Hver enkelt organisasjon er forskjellig, har ulik kultur, utfordringer og mål som må adresseres for å få til Enterprise 2.0.</p>
<p><strong>Enterprise 2.0 Summit konferansen har også noe å lære..</strong></p>
<p>For å være helt ærlig, så var det flere av deltakerne som var skuffet over måten konferansen var organisert på, deriblant meg selv. De fleste sesjonene var organisert som paneldebatter hvor to eller flere personer fortalte kort hvem de var og hvordan de har tatt i bruk sosial programvare. Resten av tiden ble brukt på spørsmål fra salen eller moderatoren. Tanken var helt sikkert veldig god, og arrangørene tenkte nok at dette skulle bli en interaktiv opplevelse og skape god dialog mellom publikum og foredragsholdere.</p>
<p>Flere av oss deltakere satt igjen med et annet syn på konferansen og følte at det ikke kom noe &#8220;nytt&#8221; ut av paneldebattene. Med såpass kort tid til hver enkelt, opplevdes mange av presentasjonene som svært like. Dette var veldig synd for foredragsholderne som kun fikk skrapet litt i overflaten, fremfor å virkelig dele sin erfaring med publikum. Jeg tror derfor konferansen hadde vært bedre tjent med å gi hver foredragsholder lengre tid slik at de hadde fått mulighet til å gå i dybden på det de snakket om.</p>
<p>Dersom du er interessert i presentasjoner fra konferansen, videooppsummeringer, bilder, twitter-feeds og bloggposter finner du det meste på <a href="http://jimworth.pbworks.com/w/page/50669937/Enterprise%2020%20Summit%20Paris%20Feb%202012">denne siden</a>.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/bvvo8NSFz1g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/enterprise-2-0-summit-i-paris/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/enterprise-2-0-summit-i-paris/</feedburner:origLink></item>
		<item>
		<title>Erfaringer fra testdrevet JavaScript</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/4h5aOxoMB8w/</link>
		<comments>http://open.bekk.no/erfaringer-fra-testdrevet-javascript/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 00:10:40 +0000</pubDate>
		<dc:creator>Snorre Brandstadmoen</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Grensesnittutvikling]]></category>
		<category><![CDATA[Kvalitet og testing]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Webarkitektur]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web sockets]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8033</guid>
		<description><![CDATA[Magnar Sveen gir en glimrende introduksjon til testdrevet JavaScript-utvikling i screencast-serien &#8220;Zombier, mafia og testdrevet utvikling&#8221;, zombietdd.com. Etter å ha fulgt med på denne i høst, ble jeg inspirert til å gjøre noe tilsvarende selv og bestemte meg for å utvikle en enkel applikasjon, der jeg benytter TDD-metodikk og tilhørende verktøy. iTouch App&#8217;en som skal [...]]]></description>
			<content:encoded><![CDATA[<p>Magnar Sveen gir en glimrende introduksjon til testdrevet JavaScript-utvikling i screencast-serien &#8220;Zombier, mafia og testdrevet utvikling&#8221;, <a href="http://zombietdd.com" target="_blank">zombietdd.com</a>. Etter å ha fulgt med på denne i høst, ble jeg inspirert til å gjøre noe tilsvarende selv og bestemte meg for å utvikle en enkel applikasjon, der jeg benytter TDD-metodikk og tilhørende verktøy.</p>
<p><span id="more-8033"></span></p>
<h2>iTouch</h2>
<p>App&#8217;en som skal lages er et spill, hvor poenget er å taste en gitt tekst feilfritt, raskest mulig. Spillet skal støtte flere samtidige spillere, og alle spillere skal fortløpende se hvordan konkurrenter ligger an underveis, samt status på egen tasting i form av fargekoding av tastet tekst.</p>
<p>Jeg ser for meg en arkitektur der vi kjører JavaScript på server, JavaScript+HTML på klienter, og sanntidsoppdatering av konkurrentstatus over Web Sockets.</p>
<p style="text-align: center"> <a href="http://open.bekk.no/wp-content/uploads/2012/02/overordnet_arkitektur.png"><img class="size-full wp-image-8041 aligncenter" src="http://open.bekk.no/wp-content/uploads/2012/02/overordnet_arkitektur.png" alt="Overordnet arkitektur" width="722" height="494" /></a></p>
<p>Tanken er at på hvert tastetrykk, sender klienten inntastet tekst til serveren for validering. Serveren sender så tilbake et statusobjekt som sier noe om hvorvidt tastet tekst er feil, hvor mye av tekst som gjenstår osv. Det blir så opp til klienten presentere denne statusen til brukeren.</p>
<h2>Litt om teknologi</h2>
<p>Til Web Sockets-kommunikasjonen skal jeg bruke rammeverket <a href="http://nowjs.com" target="_blank">NowJS</a>, som er ganske fascinerende. Det lar deg synkronisere JavaScript-variabler og -funksjoner mellom klient og server, slik at man kan kalle funksjoner på server direkte fra klient, og faktisk også funksjoner definert på klient(er) direkte fra server. NowJS baserer seg på veletablerte SocketIO.</p>
<p>Serverkoden kjører på <a href="http://nodejs.org" target="_blank">Node.js</a>, som er blitt en defacto plattform for serverside JavaScript.</p>
<h2>Testdrevet utvikling</h2>
<p>I JavaScript er det p.t. en rekke testrammeverk tilgjengelig. Jeg har valgt å bruke <a href="http://pivotal.github.com/jasmine" target="_blank">Jasmine</a>, mest fordi jeg liker BDD-syntaksen, og at man kan benytte rammeverket til å teste både klient- og serverkode. I dag ville jeg nok gått for <a href="http://busterjs.org" target="_blank">Buster.JS</a>, men mer om Buster senere.</p>
<p>Man kan fint kjøre Jasmine-tester <a href="https://github.com/pivotal/jasmine/blob/master/lib/jasmine-core/example/SpecRunner.html" target="_blank">standalone i en nettleser</a>, men det er fornuftig å benytte seg av en test runner, eksempelvis <a href="http://code.google.com/p/js-test-driver" target="_blank">JS Test Driver</a>. Bloggpost’en til kollegaer Torstein og Børge: <a title="Getting started with JS and TDD" href="http://open.bekk.no/getting-started-with-js-and-tdd/" target="_blank">”Getting started with JS and TDD”</a>,  gir en grundig innføring i hvordan Jasmine er i bruk, samt hvordan man integrerer med JS Test Driver.</p>
<p>Det avgjørende her er å få lastet ned riktige biblioteker, lagt disse inn i en fornuftig <a href="https://gist.github.com/1747920" target="_blank">mappestruktur</a>, og fått satt opp en <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/jsTestDriver.conf" target="_blank">jsTestDriver.conf</a>-fil til å reflektere denne.  I tillegg kan det være fornuftig å installere &#8220;jstdutil&#8221;. Dette verktøyet lar deg kjøre kommandoene &#8220;jstestdriver&#8221; og &#8220;jsautotest&#8221; fra kommandolinja. Sjekk siden til Christian Johansen for <a href="http://cjohansen.no/en/javascript/jstdutil_a_ruby_wrapper_over_jstestdriver" target="_blank">installasjonsbeskrivelse</a>.</p>
<p>Prosjektet mitt benytter altså Jasmine som testrammeverk, og JS Test Driver for å kjøre testene. Når disse tingene er på plass, er man klar til å skrive første test!</p>
<h2>Første test</h2>
<p>Dette blir litt som å skrive første setningen i en bok, eller i denne bloggposten for den saks skyld. Jeg tenker det enkleste å teste i min kode måtte være mekanismen som validerer inntastet tekst. Jeg ser for meg at vi oppretter en scoringobjekt som tar inn en tekst, og returnerer et statusobjekt som sier noe om hvilke bokstaver i teksten som evt. er feil.</p>
<p>Vi spesifiserer forventet oppførsel i filen spec/scoring.spec.js:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should validate text with 2 errors&quot;</span><span style="color: #339933;">,</span>
<span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> typedText <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;DeTte Er en test&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span>scoring.<span style="color: #660066;">validate</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toBeDefined</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> results <span style="color: #339933;">=</span> scoring.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span>originalText<span style="color: #339933;">,</span> typedText<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span>results.<span style="color: #660066;">errors</span>.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span>results.<span style="color: #660066;">errors</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">6</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>og kjører kommandoen ”jstestdriver –tests all –reset”, eller enda bedre ”jsautotest”. Vi får beskjed om å opprette scoring-modulen i namespacet TDD, med funksjonen &#8220;validate&#8221;. Og etter litt TDD’ing ender vi opp med en mer eller mindre komplett <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/spec/server/scoring.spec.js" target="_blank">scoring.spec.js</a>  med tilhørende implementasjon <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/src/server/scoring.js" target="_blank">scoring.js</a>.</p>
<h2>Arkitektur</h2>
<p>Før vi går videre med tester, kan vi titte litt på kodearkitektur. I tillegg til scoring-modulen, trenger vi funksjonalitet for å administrere selve spillets gang. La oss gi denne modulen navnet &#8220;game&#8221;. På klientsiden trenger vi en modul som styrer kommunikasjonen med server og oppdatering av skjermbilder; game_controller.js</p>
<p>Hvis vi skisserer opp systemet, så har vi et avhengighetsbilde som ligner dette:</p>
<p>&nbsp;</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/02/javascriptarkitektur.png"><img class="aligncenter size-full wp-image-8059" src="http://open.bekk.no/wp-content/uploads/2012/02/javascriptarkitektur.png" alt="" width="360" height="427" /></a></p>
<p>Vi vet at game benytter NowJS-rammeverket for å formidle sanntidsinformasjon, i tillegg til scoringmodulen for å kalkulere status. Samtidig skal game_controller.js kommunisere med game.js vha. NowJS.</p>
<p>Når man nå skal sette sammen disse bitene, er det viktig å tenke at de skal være <strong>løst koblet</strong>. Dette kan man få til ved å spesifisere eksterne avhengigheter ved opprettelse av modulene. F.eks., får game.js <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/src/server/game.js#LC17" target="_blank">sprøytet inn en referanse til scoring</a> og <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/src/server/game.js#LC20" target="_blank">NowJS</a> når den blir opprettet, og kode for å opprette et game-objekt blir:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> game <span style="color: #339933;">=</span> TDD.<span style="color: #660066;">game</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    originalText<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;En tekst&quot;</span><span style="color: #339933;">,</span>
    scoring<span style="color: #339933;">:</span> TDD.<span style="color: #660066;">scoring</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    everyone<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">everyone</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dette gjør det lett å enhetsteste game.js, da man enkelt kan stubbe/mocke disse avhengighetene.</p>
<h2>Mer testing</h2>
<p>Nå har det liten hensikt å gå i gjennom all kildekode og tester i teksten her, men vi skal se litt mer på hvordan utvalgt funksjonalitet er implementert og testet.</p>
<p>Når det gjelder game-modulen, skal denne bla. ha funksjonalitet for å</p>
<ul>
<li>registrere deltakere</li>
<li>sette i gang en ny omgang</li>
<li>distribuere forløpende status til alle deltakere</li>
</ul>
<p>Hvis vi ser nærmere på det siste punktet, så skal status sendes fortløpende til alle deltakerne i sanntid over Web Sockets vha. NowJS. Web Sockets-kommunikasjonen er fullstendig abstrahert bort av rammeverket, og alt man trenger å gjøre er å legge til funksjoner i det spesielle ”<a href="http://nowjs.com/doc/nowjs" target="_blank">now</a>”-objektet som blir synkronisert mellom server og klient. Rammeverket fungerer slik at man kan adressere server via now-objektet på klienten, samt adressere alle klienter via everyone.now-objektet fra serveren.</p>
<p>Når man vet hvordan dette rammeverket fungerer, er man i stand til å spesifisere testen:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should validate text and distribute scores upon validation request&quot;</span><span style="color: #339933;">,</span>
<span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> typedText <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Dette er en&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066;">status</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;errors&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;percentage&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">98</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    spyOn<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">game</span>.<span style="color: #660066;">scoring</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;validate&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">andReturn</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    spyOn<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">everyone</span>.<span style="color: #660066;">now</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'receiveScores'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">game</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">everyone</span>.<span style="color: #660066;">now</span><span style="color: #339933;">,</span> typedText<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">everyone</span>.<span style="color: #660066;">now</span>.<span style="color: #660066;">receiveScores</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toHaveBeenCalledWith</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
        clientId<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;123&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #000066;">name</span><span style="color: #339933;">:</span> undefined
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #000066;">status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Her bruker vi <a href="https://github.com/pivotal/jasmine/wiki/Spies" target="_blank">spy-egenskapene</a> til Jasmine, til å legge til en forventning om at når man kaller ”validate”-funksjonen på serveren, så skal ”receiveScores”-funksjonen kalles på alle klienter.</p>
<p>Selve this.everyone.now er en stub vi selv spesifiserer:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">everyone</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    now<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        validate<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        receiveScores<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>clientId<span style="color: #339933;">,</span> score<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        startGame<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        displayTextToBeTyped<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        hideStartButton<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        showStartButton<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        clearText<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        gameOver<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        user<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
            clientId<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;123&quot;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Igjen, er det bare å <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/src/server/game.js#LC85" target="_blank">implementere spesifikasjonen</a> og kjøre testene:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Game.should massage original text
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Game.should validate text and distribute scores upon validation request
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Game.should NOT end game when text is errornous
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Game.should end game when text is <span style="color: #7a0874; font-weight: bold;">complete</span> with no errors
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Game.should start game on request
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Validation of text and scoring.should validate typed text
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Validation of text and scoring.should validate text with <span style="color: #000000;">2</span> errors
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Validation of text and scoring.should calculate score when typed text is <span style="color: #000000;">100</span><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">complete</span>
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Validation of text and scoring.should calculate score when typed text is <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">complete</span>
Firefox <span style="color: #000000;">10.0</span> Mac OS <span style="color: #7a0874; font-weight: bold;">&#91;</span>PASSED<span style="color: #7a0874; font-weight: bold;">&#93;</span> Validation of text and scoring.should calculate score when typed text is incomplete
Total <span style="color: #000000;">10</span> tests <span style="color: #7a0874; font-weight: bold;">&#40;</span>Passed: <span style="color: #000000;">10</span>; Fails: <span style="color: #000000;">0</span>; Errors: <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">8.00</span> ms<span style="color: #7a0874; font-weight: bold;">&#41;</span>
  Firefox <span style="color: #000000;">10.0</span> Mac OS: Run <span style="color: #000000;">10</span> tests <span style="color: #7a0874; font-weight: bold;">&#40;</span>Passed: <span style="color: #000000;">10</span>; Fails: <span style="color: #000000;">0</span>; Errors <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">8.00</span> ms<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<h2>Hva med klienten?</h2>
<p>Det er like enkelt å teste klientkode som serverkode, selv om man må hanskes med en DOM. Det avgjørende her er å gjøre klientkoden ”unobtrusive” og ikke mikse JavaScript og HTML-markup mer enn nødvendig.</p>
<p>Vi kan begynne med å tenke litt på hvordan markup’en på klienten skal se ut. Da spillet går ut på taste en gitt tekst, trenger vi i hvert fall et editerbart felt, og et element til å presentere tekst som skal tastes. I tillegg kan vi legge til en knapp for å starte en omgang, samt et element for å vise progress bars. Grensesnittet kan f.eks. se slik ut:</p>
<p style="text-align: left"><a href="http://open.bekk.no/wp-content/uploads/2012/02/gui.png"><img class="aligncenter size-full wp-image-8064" src="http://open.bekk.no/wp-content/uploads/2012/02/gui.png" alt="" width="618" height="539" /></a><br />
med tilhørende HTML:</p>
<pre>&lt;!DOCTYPE&gt;
&lt;html&gt;
  &lt;body&gt;
    &lt;div id="wrapper"&gt;
      &lt;h1&gt;iTouch&lt;/h1&gt;
      &lt;input id="name" type="text" placeholder="Skriv inn navnet ditt her og trykk ENTER"/&gt;
      &lt;button id="startButton"&gt;Start ny omgang (vent til alle er klare da)&lt;/button&gt;
      &lt;div id="text-to-be-typed"&gt;&lt;/div&gt;
      &lt;div id="typed-text" contenteditable="true"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Med disse antakelsene, kan vi utvikle klientlogikken – <strong>test først</strong>.</p>
<p>Eksempelvis kan vi spesifisere at spillet skal startes når noen klikker på ”Start ny omgang”-knappen på følgende vis:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should do start game when start button is clicked&quot;</span><span style="color: #339933;">,</span>
<span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    spyOn<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">game</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;startGame&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">startButton</span>.<span style="color: #660066;">trigger</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;click&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">game</span>.<span style="color: #660066;">startGame</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toHaveBeenCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">startButton</span><span style="color: #009900;">&#41;</span>.<span style="color: #000066; font-weight: bold;">is</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">':hidden'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toBeTruthy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Denne testen spesifiserer at startGame-funksjonen skal kalles, og at knappen skal skjules.<br />
$(this.startButton) er et jQuery-wrappet element som er definert slik:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">startButton</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&lt;button&gt;&lt;/button&gt;&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    id<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;startButton&quot;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">appendTo</span><span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>og <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/spec/client/game_controller.spec.js#LC45" target="_blank">sprøytet inn i game_controller-modulens create-funksjon</a>.</p>
<p>Slik kan vi fortsette; ta f.eks. koden som tester at tekst fargelegges korrekt. Ganske avansert GUI-messig, og ganske enkelt å teste da man kan simulere nettleser-eventer, kjøre css-spørringer osv.:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;should color text upon text validation and update progress bar&quot;</span><span style="color: #339933;">,</span>
<span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> originalText <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Dette er en test&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> typedText <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;Dette er En&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> errorIndex <span style="color: #339933;">=</span> <span style="color: #CC0000;">9</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> clientId <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;123&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    spyOn<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">now</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;validate&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">andCallFake</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        self.<span style="color: #660066;">now</span>.<span style="color: #660066;">receiveScores</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
            clientId<span style="color: #339933;">:</span> clientId<span style="color: #339933;">,</span>
            <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Snorre&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;errors&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>errorIndex<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;percentage&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">95</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">game</span>.<span style="color: #660066;">now</span>.<span style="color: #660066;">displayTextToBeTyped</span><span style="color: #009900;">&#40;</span>originalText<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">typedTextElement</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span>typedText<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">typedTextElement</span>.<span style="color: #660066;">trigger</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;keyup&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">now</span>.<span style="color: #660066;">validate</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toHaveBeenCalled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textToBeTypedElement</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;:nth-child(1)&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;color&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;rgb(0, 128, 0)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textToBeTypedElement</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;:nth-child(&quot;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>errorIndex <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;color&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;rgb(255, 0, 0)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    expect<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">textToBeTypedElement</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;:nth-child(&quot;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>typedText.<span style="color: #660066;">length</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">css</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;color&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;rgb(0, 0, 0)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    expect<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">wrapperElement</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#&quot;</span> <span style="color: #339933;">+</span> clientId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">attr</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;value&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toEqual</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">95</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Når man lager JavaScript-koden &#8220;unobtrusive&#8221; (i mangel av et bedre norsk ord), blir man kvitt all spagettikode man ofte ser i $(document).ready(), og sitter igjen med en <strong>ryddig</strong> <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/public/index.html" target="_blank">index.html</a>.</p>
<h2>Hmmm, hvorfor kjører vi alle testene i Firefox?</h2>
<p>Inntil nå, har vi kjørt klientestene og servertesten i kontekst av en nettleser via JS Test Driver. Da vi at vet at serverkoden skal kjøre på Node, gir det ikke mening å la ymse <a href="http://en.wikipedia.org/wiki/JavaScript_engine#JavaScript_engines" target="_blank">nettleser-JavaScript-motorer</a> - og ikke Nodes Google V8-baserte kjøretidsmiljø, tolke koden vår. Vi kan bote på dette ved å kjøre server testene med <a href="https://github.com/mhevery/jasmine-node" target="_blank">jasmine-node</a>. Dette er en Node.js-modul, som installeres med <a href="http://npmjs.org/" target="_blank">npm</a> (som nå bundles med Node-installasjonen). Da kan vi kjøre servertestene våre med:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>faggruppe<span style="color: #000000; font-weight: bold;">/</span>iTouch<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">git</span>::master<span style="color: #7a0874; font-weight: bold;">&#41;</span>:➔ jasmine-node spec<span style="color: #000000; font-weight: bold;">/</span>server <span style="color: #660033;">--verbose</span>
Started
..........
Spec Game
  it should massage original text
  it should validate text and distribute scores upon validation request
  it should NOT end game when text is errornous
  it should end game when text is <span style="color: #7a0874; font-weight: bold;">complete</span> with no errors
  it should start game on request
Spec Validation of text and scoring
  it should validate typed text
  it should validate text with <span style="color: #000000;">2</span> errors
  it should calculate score when typed text is <span style="color: #000000;">100</span><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">complete</span>
  it should calculate score when typed text is <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #7a0874; font-weight: bold;">complete</span>
  it should calculate score when typed text is incomplete
Finished <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">0.005</span> seconds
<span style="color: #000000;">2</span> tests, <span style="color: #000000;">24</span> assertions, <span style="color: #000000;">0</span> failures</pre></div></div>

<p>Dette fremprovoserer også det faktum at vi er nødt til å gjøre om scoring.js-modulen til å være <a href="http://www.commonjs.org/">Node/CommonJS</a>-kompatibel, da Node krever dette. Dette gjøres ved å legge til disse linjene i scoring:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> module <span style="color: #339933;">===</span> <span style="color: #3366CC;">'object'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    module.<span style="color: #660066;">exports</span> <span style="color: #339933;">=</span> TDD.<span style="color: #660066;">scoring</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Man kan da &#8220;hente&#8221; ut en referanse til scoring-modulen som en vanlig Node-modul slik:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">TDD.<span style="color: #660066;">scoring</span> <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;./src/server/scoring&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Buster</h2>
<p>Her kommer vi tilbake til <a href="http://busterjs.org/" target="_blank">Buster.js</a>. I tillegg til å være et flott testrammeverk på andre måter, gir Buster deg mulighet til å <a href="http://busterjs.org/docs/hybrid-testing/" target="_blank">kjøre klient- og servertester med samme test runner</a>. Buster.js er snart ute av beta, blir spennende å sjekke det ut nærmere.</p>
<h2>Skru alt sammen</h2>
<p>Når all JavaScript-logikken er ferdig implementert, gjenstår konfigurasjon av Node, slik at vi kan begynne å teste spillet. All denne konfigurasjonen gjøres i filen <a href="https://github.com/snorrebrandstadmoen/iTouch/blob/master/app.js" target="_blank">app.js</a>. Her ser vi hvordan vi oppretter et game-objekt, med alle dets avhengigheter.</p>
<p>Her er et artig lite avbrekk i en ellers hektisk prosjekthverdag:<br />
<span class='embed-youtube' style='text-align:center; display: block;'><iframe class='youtube-player' type='text/html' width='640' height='390' src='http://www.youtube.com/embed/kXEiXN3ezFI?version=3&amp;rel=1&amp;fs=1&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent' frameborder='0'></iframe></span></p>
<h2>Oppsummering</h2>
<p>Å komme fra en typisk hverdag der jeg skriver &#8220;mvn clean install&#8221; altfor mange ganger i løpet av en dag, er det utrolig frigjørende å se hvor raskt disse JavaScript-testene kjører. Når man først kommer inn i det, er JavaScript en fornøyelse å jobbe med, spesielt med tanke på egenskapene ved språket. TDD i JavaScript er definitivt ikke vanskelig, og det er like greit å lære seg teknikkene først som sist.</p>
<h3>On a side note:</h3>
<p>Magnar Sveen snakker om zombietdd-prosjektet sitt <strong>i morgen på </strong><a href="http://www.meetup.com/framsia/events/49837362/" target="_blank"><strong>Framsia at CiA 2012 &#8211; Responsive, realtime and Zombies</strong>!</a> Meetup&#8217;en omhandler forøvrig Web Sockets og Node.js, så det er ikke helt urelatert til det som blir tatt opp her!</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/4h5aOxoMB8w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/erfaringer-fra-testdrevet-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/erfaringer-fra-testdrevet-javascript/</feedburner:origLink></item>
		<item>
		<title>Innovasjon – en unnskyldning for å være vag?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/ZJroiOVIQsQ/</link>
		<comments>http://open.bekk.no/innovasjon-en-unnskyldning-for-a-vaere-vag/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 09:52:27 +0000</pubDate>
		<dc:creator>Stian Remåd</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Alexander Osterwalder]]></category>
		<category><![CDATA[innovasjon]]></category>
		<category><![CDATA[Innovasjonsstrategi]]></category>
		<category><![CDATA[Robert Wolcott]]></category>
		<category><![CDATA[strategi]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=8024</guid>
		<description><![CDATA[Siden dette er mitt livs første blogginnlegg synes jeg det er rett og rimelig å starte med en litt kontroversiell påstand. Selv har jeg jobbet for en av Norges mest anerkjente innovatører, og sjelden har jeg vært borti mer usikkerhet om hva innovasjon egentlig er. Dette kompliserer diskusjonene og bidrar til flere myter rundt innovasjon, [...]]]></description>
			<content:encoded><![CDATA[<p>Siden dette er mitt livs første blogginnlegg synes jeg det er rett og rimelig å starte med en litt kontroversiell påstand. Selv har jeg jobbet for en av Norges mest anerkjente innovatører, og sjelden har jeg vært borti mer usikkerhet om hva innovasjon egentlig er. Dette kompliserer diskusjonene og bidrar til flere myter rundt innovasjon, noe min kollega også tar opp i sin bloggpost.</p>
<p><strong>Den skoleflinke definisjonen</strong></p>
<p>Det skulle ikke være nødvendig å si for mye om viktigheten av tydelige målsetninger og en tydelig strategi for å nå sine mål. Vi kjenner viktigheten av å prioritere satsningsområder, og alle som en gang har bitt over for mye vet at for mye bredde ender opp i ingenting – masser av ingenting.</p>
<p>Likevel – når det kommer til innovasjon virker det som noe har gått tapt i hukommelsen. Det er lett å bli arrestert når en forsøker å konkretisere: “Innovasjon for dette selskapet er…” og man kommer sjelden veldig mye lenger før noen påpeker at innovasjon er både inkrementelle forbedringer, radikale innovasjoner og disruptive nyskapninger, eller at man må huske Doblin, som sier at innovasjon kan og bør romme forretningsmodeller, produkter og tjenester, prosesser, merkevarer, kundeopplevelser også videre…</p>
<p>Vurder denne definisjonen: “Innovasjon er store og små endringer i produkter, prosesser, forretningsmodeller og adferd som skaper verdi for kunden og selskapet selv”. Ganske dekkende? Hvor verdifull er den imidlertid? Selv mener jeg at den er lite verd, fordi den ikke utelukker noen ting &#8211; den er ikke et middel for å lede oss på rett vei. Men den er skoleflink!</p>
<p><strong>Diskuter bredt, iverksett smalt</strong></p>
<p>Innovasjonsutfordringen bør absolutt angripes fra mange kanter – i et innledende strategiarbeid. Ta gjerne en titt på Alexander Osterwalders business model canvas eller på Robert Wolcotts innovasjonsradar – dette er verktøy som hjelper selskaper med å skape et bredt perspektiv på innovasjonsspillerommet.</p>
<p>Problemet oppstår når selskaper ikke kommer seg ut av diskusjonen, og ender med en definisjon og en strategi like bred som da de begynte fordi de har fått formaninger om å ikke begrense kreativiteten og innspillene – også gaper de over for mye. Imidlertid, flere og flere ser at innovasjonsledelse, som i all ledelse, handler om fokus. Booz &amp; Co “avslører” vinnertrikset innenfor innovasjon som evnen til å velge noen få retninger. Robert Wolcott er enda mer spesifikk, da han konkluderer med at vinnerne velger mellom 2 og 5 strategiske retninger i hans 12-armede innovasjonsradar.</p>
<p>De som forsker på vinnere har talt: Smalt vinner over bredt når det gjelder gjennomføring.</p>
<p><strong>Innovasjon i klartekst</strong></p>
<p>Så la oss si at et selskap ser en fremtid der kunden kjøper varer gjennom flere kanaler, og velger leverandør basert på evnen til å yte service. Så selskapet etablerer en strategi basert på etablering i nye kanaler, og på økt kundeopplevelse i selskapets kontaktpunkter. Min hypotese er at et slikt selskap vil ha en langt lettere jobb når de skal etablere måleparametere, prosesser og påkrevet kompetanse for å skape nye og bedre løsninger, enn et selskap som skal skape “store og små endringer i produkter, prosesser, forretningsmodeller og adferd…” også videre.<br />
Den skotske filosofen Thomas Reid sa en gang: “There is no greater impediment to the advancement of knowledge than the ambiguity of words”. Så vær tydelig med hva innovasjon er for ditt selskap, avgrens fokuset til noen veldig få satsningsområder, og kall en spade for en spade. Veien er vanskelig nok i seg selv – la oss sette målet klart for øyet.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/ZJroiOVIQsQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/innovasjon-en-unnskyldning-for-a-vaere-vag/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://open.bekk.no/innovasjon-en-unnskyldning-for-a-vaere-vag/</feedburner:origLink></item>
		<item>
		<title>Hva er HashDOS og hva gjør jeg med det?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/-wkDBZnbxq0/</link>
		<comments>http://open.bekk.no/hva-er-hashdos-og-hva-gjor-jeg-med-det/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 22:43:16 +0000</pubDate>
		<dc:creator>Erlend Oftedal</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[hashdos]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[Sikkerhet]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7994</guid>
		<description><![CDATA[Rundt nyttår ble den årlige CCC-konferansen avholdt, og som vanlig ble det avdekket noen større sikkerhetssvakheter. Denne gangen var turen kommet til HashDOS. Dette er egentlig et gammelt problem (avdekket allerede i 2003) og gjelder Ruby on Rails, ASP.NET, java m.fl. En av få plattformer som ikke ble rammet var Perl, da de tok dette [...]]]></description>
			<content:encoded><![CDATA[<p>Rundt nyttår ble den årlige <a href="http://ccc.de/">CCC</a>-konferansen avholdt, og som vanlig ble det avdekket noen større sikkerhetssvakheter. Denne gangen var turen kommet til HashDOS. Dette er egentlig et gammelt problem (avdekket allerede i 2003) og gjelder Ruby on Rails, ASP.NET, java m.fl. En av få plattformer som ikke ble rammet var Perl, da de tok dette på alvor tilbake i 2003.</p>
<p><strong>Hva er HashDOS?</strong></p>
<p>En angriper kan, ved hjelp av relativt få ressurser, få CPUene på dine webservere til å gå i taket. Et eksempel fra <a href="http://events.ccc.de/congress/2011/Fahrplan/attachments/2007_28C3_Effective_DoS_on_web_application_platforms.pdf">slidesettet</a> viser f.eks. at man en java Tomcat kjørede på en i7 core kan utmattes med en ~6 kbits/s linje.</p>
<p><strong>Hva er det egentlig som skjer?</strong></p>
<p>Når en webapplikasjon mottar en POST-request, vil den, i de fleste rammeverk, lage en eller annen form for hashtabell eller hashmap som inneholder de parameterene som finnes i POST-requesten. En slik struktur benytter en hashfunksjon (derav navnet) for å fordele nøkler med tilhørende verdier på et begrenset antall med bøtter. Dette gjør det effektivt å slå opp verdier senere, fordi man ikke trenger å lete gjennom alle nøkler, men kan hashe nøkkelen, finne riktig bøtte, og se om nøkkelen med tilhørende verdi finnes i bøtta. </p>
<p>Men siden det er et begrenset antall bøtter, vil det naturligvis finnes flere mulige nøkler som hasher til samme bøtte (to strenger kan f.eks. gi samme hash). For å håndtere dette benyttes det gjerne en lenket liste i hver bøtte. Når man skal søke i denne bøtta, øker søketiden dermed lineært med antall nøkler i bøtta. Det samme gjelder innsettinger i tabellen. Før man kan sette inn et nytt element, må man sjekke om nøkkelen finnes der fra før. Og det er nettopp her problemet ligger.</p>
<p>En angriper sender f.eks. inn n=200,000 parametere som alle har navn med samme hash-kode. Når applikasjonen skal bygge opp hashtabellen, ender den da opp med å gjøre n^2 sammenligninger som i eksempelet blir 40,000,000,000 sammenligninger. Som man skjønner, kan dette bli svært kostbart CPU-messig.</p>
<p>Det er ikke spesielt vanskelig å finne slike strenger som gir samme hash. Hash-funksjonene som brukes i de forskjellige rammeverkene er ofte slik at der string A og B har samme hash, så vil AB (A konkatenert med B) få samme hash som BA, AA og BB. Dermed er det lett å lage permutasjoner som alle gir samme hash-verdi.</p>
<p><strong>Hvordan beskytter jeg meg?</strong></p>
<p>For flere rammeverkt, deriblant ASP.NET, leverer leverandøren av rammeverket en patch. Mange av patchene som har kommet baserer seg på at hash-funksjonen gjøres mindre forutsigbar. Hash-funksjonene har inntill nå, gitt samme hash-verdi for samme string hver gang man kjørte programmet. I noen rammeverk vil det nå være slik at en hash-funksjon alltid ville gi samme verdi for samme string innenfor samme prosess, men starter man applikasjonen på ny, endres hashfunksjonen slik at to verdier som før hadde samme hash, nå vil gi forskjellig hash. Dermed gjør man det nærmest umulig for en angriper å finne verdier som gir samme hash.</p>
<p>En annen mulighet som f.eks. PHP og Jetty benytter seg av, er å begrense hvor mange POST-parametere man kan ha. Man kan jo ganske greit argumentere for at man ikke trenger å kunne ha 200,000 POST parameter. De fleste klarer seg nok med under 100.</p>
<p>Dersom rammeverket man bruker enda ikke er patchet, kan man også begrense tillatt størrelse på POST-requester. For å sende 200,000 parametere må man kunne sende en POST-request på ca. 2 MB. Siden kompleksiteten er n^2, kan man ved å redusere til f.eks. 200KB, redusere fra 40,000,000,000 til 400,000,000. Og en lavere grense blir resultatet enda bedre. Men det beste er selvsagt om problemet håndteres i rammeverket eller webserveren.</p>
<p><strong>Ressurser</strong></p>
<ul>
<li><a href="http://www.youtube.com/watch?v=R2Cq3CLI6H8">Opptak av foredraget fra CCC</a></li>
<li><a href="http://events.ccc.de/congress/2011/Fahrplan/attachments/2007_28C3_Effective_DoS_on_web_application_platforms.pdf">Slides</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/-wkDBZnbxq0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/hva-er-hashdos-og-hva-gjor-jeg-med-det/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/hva-er-hashdos-og-hva-gjor-jeg-med-det/</feedburner:origLink></item>
		<item>
		<title>Emosjonell design – risky business? (6:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/u7edbuYqXPo/</link>
		<comments>http://open.bekk.no/emosjonell-design-%e2%80%93-risky-business-66/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 08:48:16 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7585</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. Innlegg nummer 6 avslutter vi med å se på utfordringer rundt emosjonell design.]]></description>
			<content:encoded><![CDATA[<h5><em>I de tidligere innleggene mine har jeg gitt en intro til emosjonell design gjennom boken “Design for emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a>, ved å snakke om “<a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/">Hva?</a>”, “<a href="https://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/trackback/">Hvorfor?</a>” og  “Hvordan?&#8221; (den siste gjennom <a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">psykologiske fellesnevnere</a>, <a href="https://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/trackback/">personlighet</a> og <a href="https://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/trackback/">praktiske fremgangsmåter</a>). Denne gangen skal vi avslutte med å se på utfordringer ved emosjonell design.</em></h5>
<h2>Dette virker da litt risky…</h2>
<p>I <a href="https://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/trackback/">det forrige innlegget mitt</a> så vi på tre ulike måter å implementere emosjonell design der de mer forsiktige kan ta vekk litt av riskfølelsen. Da vi snakket om emosjonell design gjennom <a href="https://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/trackback/">personlighet</a>, var vi også litt inne på det at dette kunne føles litt risky. Nå skal vi ta tyren ved hornene!</p>
<p>Å vise personlighet i design, som ellers i verden, innebærer alltid en liten risiko. Noen personligheter klikker rett og slett ikke. Dette kan høres veldig skummelt ut, og man kan fort bli fristet til å &#8220;safe&#8221; med å bare være generelt likandes og ikke så mye mer. Men tenk på hvordan det er i det vanlige liv; er det ikke bedre at folk knytter en følelse til deg, enn at du holder deg flat og nøytral og alle sier “ Nei, hun Nina er vel ok hun.. ”?</p>
<p>Det vil alltid være noen personligheter som ikke passer sammen, men dette kan faktisk være en ganske god reality-check. Dersom du har utviklet en personlighet som speiler brandet og systemet godt, og det er noen kunder som så ikke liker personligheten vår, har vi kanskje spart oss for et potensielt trøbblete kundeforhold i fremtiden? Og når vi på motsatt side ser alle dem som nå virkelig digger oss fordi vi har en bra personlighet, heller enn å bare si vi er ok – da er det vel win-win og en liten risk å ta?</p>
<h2>Hva annet enn personlighet er utfordrende?</h2>
<p>I tillegg til at personlighetene må passe, må man av og til overkomme skepsis, latskap og likegyldighet.</p>
<p>Det første er rett og slett å få brukerne til å stole på deg. Som nevnt i et <a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">tidligere innlegg</a>, er det da viktig at overflaten gir et tillitsvekkende ytre. Det er faktisk slik at når “panseret” tydelig har fått ettertanke og er gjennomarbeidet, da får man følelsen av at det som ligger bak sannsynligvis også er samvittighetsfullt og skikkelig gjort, og det er mindre grunn til å tro at du vil møte noe som ikke henger på greip senere i prosessen.</p>
<p>Folk er egentlig ikke så late, de bare leter etter minste motstands vei. Her kan man coache folk mot målet gjennom å gjøre prosessen nærmest til et spill ved å gi insentiver og premier som kommer nærmere og nærmere jo lenger brukeren kommer i prosessen. For eksempel bruker Dropbox en premie på 250MB lagringsplass som brukerne gradvis ser komme nærmere etterhvert som han bygger opp sin konto med bilder osv.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/dropbox.png"><img class="alignleft size-medium wp-image-7587" src="http://open.bekk.no/wp-content/uploads/2011/12/dropbox-300x175.png" alt="" width="300" height="175" /></a></p>
<p>Likegyldighet skjer når innholdet i siden er irrelevant eller dårlig presentert. Her er det rett og slett slik at</p>
<blockquote><p> &#8221;Great content delivered in an emotionally engaging manner is like kryptonite for apathy!&#8221;</p></blockquote>
<h2>Og når noe går galt…</h2>
<p>Enten man bruker emosjonell design eller ikke, vil systemer alltid feile. En eller annen gang har du downtime eller menneskelig feil eller lignende, og dette liker selvsagt ikke brukerne.</p>
<p>Men! Når du har en positiv emosjonell forbindelse med brukerne, da er det mye mer sannsynlig at de tilgir, og fortsetter å bruke og elske systemet. Når en feil skjer, vil responsen til brukerne være tuftet på hvordan forholdet deres til systemet allerede er. Dersom man allerede har et godt emosjonelt forhold og så takler feil med å kommunisere rolig og ærlig, og kommer med oppdateringer (“Vi jobber så hardt vi kan!”), forsikringer og beklagelser, kan man langt på vei roe negative følelser og vri disse tilbake til det positive.</p>
<blockquote><p> &#8221;Emotional deisgn is your insurance to maintain audience trust when things aren&#8217;t going your way&#8221;</p></blockquote>
<p><em>Dette var siste episode i seks-dels føljetongen om emosjonell design. Jeg håper det har vært interessant lesing og at du har fått lyst til å snuse på temaet!</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/u7edbuYqXPo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/emosjonell-design-%e2%80%93-risky-business-66/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/emosjonell-design-%e2%80%93-risky-business-66/</feedburner:origLink></item>
		<item>
		<title>Praktiske fremgangsmåter i emosjonell design (5:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/iA96LzRhCyk/</link>
		<comments>http://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 07:35:39 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7560</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. Innlegg nummer 5 ser vi på praktiske fremgangsmåter for emosjonell design!]]></description>
			<content:encoded><![CDATA[<h5><em>I de tidligere innleggene har jeg gitt en intro til emosjonell design gjennom boken “Design for emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a>, ved å snakke om <a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/">“Hva?”</a>, <a href="https://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/trackback/">“Hvorfor?”</a> og  “Hvordan?&#8221; (den siste gjennom <a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">psykologiske fellesnevnere</a> og <a href="https://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/trackback/">personlighet</a>). Denne gangen skal vi se videre på praktiske fremgangsmåter for “Hvordan?”.</em></h5>
<p>Ok, så da vet du en del om emosjonell design, og kanskje du er fristet til å prøve det. Kanskje har du til og med overtalt oppdragsgiver om at dette er veien å gå, og nå trenger du en plan for hvor dypt i bassenget dere skal plumpe. I boka forslår Aarron tre veier å gå, tilpasset hvor modig og moden man føler seg på området.</p>
<h2>Dypenden</h2>
<p>Som du kanskje har forstått, er den modige veien å gå å redesigne hele systemet og brandet med emosjonell design og fokus på en personlighet i høysetet. Dette er nok det som kan gi mest uttelling, og det finnes mange gode eksempler på dem som har gjort det meget bra her.</p>
<p>Et tidligere nevnt eksemple er MailChimp, der personligheten til systemet virkelig klikket med brukerne og man opplevde brukere som virkelig digget personligheten til systemet og ble sterke ambassadører for tjenesten, noe utallige positive Twitter-meldinger vitnet om.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/twitter-mailchimp.png"><img class="aligncenter size-full wp-image-7567" src="http://open.bekk.no/wp-content/uploads/2011/12/twitter-mailchimp.png" alt="" width="760" height="162" /></a></p>
<p>I tillegg kan vi nevne Tapbots, som er nyttige, små iPhone apper som for eksempel konverterer mellom ulike måleenheter eller hjelper deg å følge med på kroppsvekten din. Ganske kjedelige oppgaver, men gjennom å ha gitt sine interface personligheter, føler brukerne at de har en “partner in crime”. Personlighetene er inspirert av Pixarkarakteren WALL.E, og når brukerne omtaler tapbots bruker de begreper som “love”, “adore” osv.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/tapbots.png"><img class="alignleft size-medium wp-image-7570" src="http://open.bekk.no/wp-content/uploads/2011/12/tapbots-300x222.png" alt="" width="300" height="222" /></a></p>
<p>Det er også verdt å merke seg <a href="betabrand.com">Betabrand.com</a>, en nettbutikk som selger klær, men de velger å se seg selv som et online magasin som tilfeldigvis selger klær. Betabrand skriver om sine produkter på en utrolig morsom måte, og har et stort galleri av “amatør superhelter” som utsetter klærne for dagligdagse prøvelser. Det finnes en morsom historie bak hvert produkt og mange av brukerne, også noen som intielt var skeptiske, har blitt hard-core ambassadører for produktene!</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/betabrand-sammen.png"><img class="aligncenter size-full wp-image-7571" src="http://open.bekk.no/wp-content/uploads/2011/12/betabrand-sammen.png" alt="" width="760" height="350" /></a></p>
<h2>I det små</h2>
<p>Det går også an å begynne litt i det små. Du kan ta noen mindre, kanskje midlertidige stunt og følg emed på hvordan brukerne reagerer. Kanskje det kan være så enkelt som å vise mer personlighet i det du desverre må vise en feilmelding? Eller kanskje du rundt påske kan kjøre en påskeegg-jakt rundt på sidene dine?</p>
<p>CoffeCup Software kjørte en påskeeggjakt, der påskeeggene man skulle finne bare var synlige på enkelte tider av døgnet og etter så og så mange sidevisninger fra brukeren. Ved å samle påskeegg kunne man vinne cash og software-premier, og sidene opplevde voldsom trafikk. I tillegg gikk salget opp, og antall følgere på Facebook og Twitter like så.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/easteregg.png"><img class="alignleft size-full wp-image-7578" src="http://open.bekk.no/wp-content/uploads/2011/12/easteregg.png" alt="" width="482" height="260" /></a></p>
<h2>Den gyldne middelvei</h2>
<p>I<span style="color: #000000"> <a href="https://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/trackback/">mitt forrige innlegg</a> </span>snakket vi om MailChimp som virkelig hadde gått linja ut med emosjonell design. De var imidlertid ikke så selvsikre i begynnelsen, og innførte derfor et valg som kunne “slå av personligheten” til siten og få en “flat” versjon (de kalte denne “party pooper mode”!). Dette ga dem en trygghet og de følte seg sikre på at de nå ikke ville støte bort noen, men da de etter en stund gjorde noen analyser, viste det seg at bare 0,007% av brukerne ville være i party pooper mode!</p>
<p>Selv om det i MailChimps tilfelle viste seg at den “flate” løsningen nesten ikke var vits å ha, kan dette kanskje være en smart og trygg vei å gå for mange andre.</p>
<p><em>Da har vi vært gjennom “Hvordan?” og nå sitter sikkert noen og lurer på om alt er bare gull og grønne skoger, eller om det finnes noen risikoer her også. Og selvfølgelig gjør det det – de skal vi se på i <span style="color: #000000"><a href="https://open.bekk.no/emosjonell-design-–-risky-business-66/">mitt neste og siste innlegg</a> i føljetongen!</span></em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/iA96LzRhCyk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/</feedburner:origLink></item>
		<item>
		<title>Getting started with JS and TDD</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/1TwH-dMOHSg/</link>
		<comments>http://open.bekk.no/getting-started-with-js-and-tdd/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 07:00:26 +0000</pubDate>
		<dc:creator>Torstein Nicolaysen</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Grensesnittutvikling]]></category>
		<category><![CDATA[Kvalitet og testing]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[jasmine]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[jstestdriver]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test-driven development]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=6436</guid>
		<description><![CDATA[Introduction Are you working on unmaintainable JavaScript code? Are you afraid to make changes to your 5000+ lines long JS file? If so, you&#8217;ve probably not written tests or done TDD. Fear not! Read on, and we will show you how to get started with writing tests and setting up the needed tools. We will [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Are you working on unmaintainable JavaScript code? Are you afraid to make changes to your 5000+ lines long JS file? If so, you&#8217;ve probably not written tests or done TDD. Fear not! Read on, and we will show you how to get started with writing tests and setting up the needed tools. We will show by example how to create a small, yet complex, JS web application using TDD.</p>
<p>JavaScript is becoming increasingly popular for developing full-fledged applications &#8211; both <a href="http://en.wikipedia.org/wiki/Nodejs">server</a> and client side. Looking at the current trend of how JS is used, we can see that it’s being used for business critical applications and large-scale applications. With all this popularity and extensive use, we are under the impression that the testing and quality focus is lagging behind.</p>
<p>After reading this blog post, you will know how to get started with JS TDD using tools and frameworks we consider easy to use and relatively mature. If you already know <strong>why</strong> you should test your JS code, feel free to skip the background.</p>
<p>If you want to take a closer look at the example application, feel free to check out the entire project from GitHub @ <a href="http://github.com/bekk/jstdd">http://github.com/bekk/jstdd</a>.</p>
<h2>Background</h2>
<p><img class="size-full wp-image-7874" src="http://open.bekk.no/wp-content/uploads/2012/01/JavaScript-logo.png" alt="The JavaScript logo" width="192" height="192" align="right" /> JavaScript has received a popularity boost from browser vendor’s quest to write the fastest JS engine, as well as the popular programming language <a href="http://en.wikipedia.org/wiki/Nodejs">node.js</a>. In addition, jQuery has simplified the way we interact with the DOM and smooths over annoying browser differences &#8211; making JS more accessible for everyday developers. Focus have been primarily on producing functionality, and not on testing and good design/clean code. We believe that one reason is the lack of standardized or commonly available testing tools and frameworks. Another reason might be that traditionally JS have been written by UI and UX developers, who’s focus have been primarily on functionality &#8211; not on <em>Clean Code</em> and testability.</p>
<p>JS and all other dynamic programming languages is in dire need of tests since there is no compile-time checking. Tests can be used to ensure that the application <strong>behaves as expected</strong>, and gives developers confidence to make changes to existing code. Despite the obvious need for testing, many developers skimp on writing tests when developing large JS applications. All the advantages of TDD that applies for other programming languages, also applies for JS. Who does not want testable, maintainable, readable, well-designed, modular and working code? It’s well established that TDD has positive effects on code quality (read the chapter on TDD by Robert C. Martin in <a href="http://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073">The Clean Coder</a>).</p>
<p>Other popular programming languages like Java and C# have mature and well-documented testing-tools. At the time of writing, JS has <a href="http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript">several testing frameworks available</a>, but only a handful mature. Looking at the options, no one really stands out as a clear choice. To make things worse, getting started with JavaScript TDD can be challenging. There are so many ways of going about setting up a complete test-environment for JS. We have looked into this and had some experience with what works and what doesn&#8217;t.</p>
<h2>The runner</h2>
<p><a href="http://code.google.com/p/js-test-driver/">JsTestDriver</a> is (as it’s name implies) a tool that let you run your JS tests. You can run your tests directly from your favorite IDE (at least in theory) to get into your TDD rhythm. It runs from the command line and even on your continuous integration server. In our examples we’ll be running it from the command line.</p>
<p>A quote from their home site says it all: “The goal of JS Test Driver is to make JavaScript unit test development as seamless as and easy as Java unit tests.”</p>
<p>JsTestDriver supports testing in different browsers through capturing browsers as a slave machines. It includes it’s own limited assertion framework, but also supports add-ons, which opens for a wide range of <a href="http://code.google.com/p/js-test-driver/wiki/XUnitCompatibility">third party</a> assertion frameworks. We will be using Jasmine BDD through an adapter.</p>
<p>As with everything else, there is room for improvement. JsTestDriver&#8217;s configuration can sometimes be too simple, and advanced users may feel limited. In our simple example it works great, but expect some issues when scaling up. As a note, we did not get the IDE integration in IntelliJ IDEA to work properly.</p>
<p>Recently Buster.js was released as beta, and is worth checking out as an alternative to JsTestDriver.</p>
<h2>The framework</h2>
<p><img class="size-full wp-image-7875" src="http://open.bekk.no/wp-content/uploads/2012/01/jasmine_logo.png" alt="The Jasmine logo" width="282" height="90" align="right" /> We’ve picked out <a href="http://pivotal.github.com/jasmine/">Jasmine</a> because it is a mature (compared to most other frameworks) and a popular testing framework for JS. It features BDD syntax, which gives clear and readable tests with functionality in focus. It does not depend on any other framework and does not require a DOM. It can be run in the browser, through JsTestDriver or through node.js. It is well documented and is easy to get started with.</p>
<p>There are a few things to consider. They don’t separate between mocks, stubs and spies. All of that is packed into what Jasmine describes as a spy. The bundled matchers are good, but few. To get readable tests, it’s often necessary to write custom matchers to match the domain language. Still, we consider this one of the few viable options for doing TDD in JS.</p>
<p><a href="https://github.com/pivotal/jasmine/wiki">Installing, setting up and using Jasmine</a> is easy, and will not be detailed here. We’re using Jasmine through JsTestDriver, and have configured it thereafter.</p>
<p>QUnit was considered as an option, but it’s syntax did not help us achieve as readable and clear tests as Jasmine. It’s simplicity makes it very attractive and useful for beginners, but more advanced users will want more.</p>
<h2>Demo application</h2>
<p>As stated in the introduction, we’ll make a little application that does an “I feel lucky” search from Flickr. One of the choices we made was to have a minimal setup. No jQuery and third-party libraries in the production code, with the intention to reduce complexity and make the example more transparent as to how things work.</p>
<h3>Pre-requisites</h3>
<p>If you want to use the same setup as us, we recommend doing the following.<br />
(Or you can check out the entire project from GitHub @ <a href="http://github.com/bekk/jstdd">http://github.com/bekk/jstdd</a>).</p>
<h3>Download these libraries:</h3>
<ul>
<li><a href="https://github.com/ibolmo/jasmine-jstd-adapter">https://github.com/ibolmo/jasmine-jstd-adapter</a> (version 1.1.1)</li>
<li><a href="https://github.com/pivotal/jasmine">https://github.com/pivotal/jasmine</a> (version 1.0.1)</li>
<li><a href="http://code.google.com/p/js-test-driver/">http://code.google.com/p/js-test-driver/</a> (version 1.3.2)</li>
</ul>
<p>Create the following folder structure:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.
├── lib<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #666666; font-style: italic;"># 3rd party libs lies here</span>
│   ├── jasmine.js
│   ├── jasmine-jstd-adapter<span style="color: #000000; font-weight: bold;">/</span>
│   └── JsTestDriver-1.3.2.jar
├── spec<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #666666; font-style: italic;"># test/specs lies here</span>
├── src<span style="color: #000000; font-weight: bold;">/</span>  <span style="color: #666666; font-style: italic;"># application source lies here</span>
├── server.sh <span style="color: #666666; font-style: italic;"># Starts a JSTD server (symlinked)</span>
├── test.sh <span style="color: #666666; font-style: italic;"># Runs the test (symlinked)</span>
└── jsTestDriver.conf <span style="color: #666666; font-style: italic;"># JSTD configuration for our project</span></pre></div></div>

<p>server.sh and test.sh are just shortcuts to scripts bundled with js-test-driver.</p>
<p>Configure jsTestDriver.conf to match your setup.</p>
<h3>Getting familiar with the framework</h3>
<p>We started off with a simple test to get familiar with the syntax and to verify that everything is set up correctly. Consider it a warm-up exercise.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">describe<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Jasmine&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    it<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;makes testing JavaScript awesome!&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        expect<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toBeTruthy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Running it</h3>
<p>Running it the first time might seem a bit overly hard, but once you’re set up it’s easy to run the tests. Before you start the server, you need to write a little config file. Take a <a href="https://github.com/bekk/jstdd/blob/master/jsTestDriver.conf">look at ours</a> if you need an example.<br />
Starting the server can seem a bit tedious, but we found a shell-script that starts the server. All we had to do was modify the path to suit our project structure (see <a href="https://github.com/bekk/jstdd/blob/master/server.sh">server.sh</a>). Running it is just a matter of typing ./server and seconds later the server is up and running.</p>
<p>Example output from a test run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Running all tests
Chrome: Runner reset.
....
Total <span style="color: #000000;">1</span> tests <span style="color: #7a0874; font-weight: bold;">&#40;</span>Passed: <span style="color: #000000;">1</span>; Fails: <span style="color: #000000;">0</span>; Errors: <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1.00</span> ms<span style="color: #7a0874; font-weight: bold;">&#41;</span>
Chrome 12.0.742.112 Mac OS: Run <span style="color: #000000;">4</span> tests <span style="color: #7a0874; font-weight: bold;">&#40;</span>Passed: <span style="color: #000000;">1</span>; Fails: <span style="color: #000000;">0</span>; Errors <span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1.00</span> ms<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Next task is capturing browsers. We spun up browsers on each others computers and went to http://[my address]:9876/capture and the browser became a slave. Excellent! We used Safari, Firefox and Chrome to test. Make sure to keep the browser running while testing.</p>
<div id="attachment_6928" class="wp-caption aligncenter" style="width: 310px"><a href="http://open.bekk.no/wp-content/uploads/2011/10/Screen-shot-2011-10-21-at-18.04.51.png"><img class="size-medium wp-image-6928 " src="http://open.bekk.no/wp-content/uploads/2011/10/Screen-shot-2011-10-21-at-18.04.51-300x133.png" alt="Screenshot from captured browser" width="300" height="133" /></a><p class="wp-caption-text">Captured browser</p></div>
<p>JsTestDriver supports distributed test-running, but that is not something we will explore in this blog post. Now all that is left is telling the server to ask the browsers to run the tests. With the scripts, it’s just a matter of typing ./test in the shell and the tests are run.</p>
<p>The flow for starting the first time is the following:<br />
1. Start server<br />
2. Capture browsers<br />
3. Run tests</p>
<p>After than you just type ./test each time you want to run the tests.</p>
<h3>Working on LuckyFlickr</h3>
<h4>Start with the tests</h4>
<p>We decided to start with writing tests to verify output on the result page. The simplest possible test we could think of was to test for a message when no result was found.</p>
<p>Next, we added a new test to verify that if a result were received, the parser would pick the first result and display the image on the result page. Since we were doing unit testing we didn’t want to go all the way to Flickr when we ran the test, so we created a <a href="https://github.com/bekk/jstdd/blob/master/spec/result-stub.js">simple stub</a> that returned some JSON data on the expected flickr format so we could run the test in isolation. The specs for the parser read:</p>
<ul>
<li>&#8220;outputting result&#8221;</li>
<ul>
<li>&#8220;should not output an image when there are no results&#8221;</li>
<li>&#8220;should output the image from the result&#8221;</li>
</ul>
</ul>
<p dir="ltr">Note: When reading these specs, read them like “Outputting result should not output an image when there are no results”.</p>
<p>When pondering what to do next, we figured we could create a test for the component that would fetch data from flickr. Since we wanted to get out data from another site, we decided to use JSONP to overcome the cross-site problem. We also wanted the component to send the flickr request asynchronously, so we had to write a test that would handle that. To fix this we created setup code to temporarily replace the default XMLHttpRequest implementation in JS with our own. That way we could control what the response would be. We decided to let it respond with the same JSON stub as in the parser test.</p>
<ul>
<li>“when querying flickr”</li>
<ul>
<li>&#8220;should create a global function that handles the JSON-P callback&#8221;</li>
<li>“should do a search and call the callback function”</li>
</ul>
</ul>
<p>The last step was to create some tests to make sure the GUI was displaying the result in the right container in the result page. On this step, we saw that some of the components came together, and introduced the need for mocking. We mocked the result given by the “fetcher”. Doing so, we’re not dependent on a connection to flickr.com. We created 2 tests for this. The first asserts that the result from flickr is displayed in the result container, and the second one asserts that “Loading” is displayed while it is fetching data from flickr.</p>
<h4>The result</h4>
<p>Since our focus was unit testing, our implementation ended out with three separate “units” that each did one important thing. We have a “fetcher” that goes out and fetches the result from Flickr, a “result parser” that knows how to parse the JSON data structure from Flickr and finally the component that enables the user to do a search. No enterprisy patterns, no unneeded complexity, no silver bullets. Just enough to make things work. Also, the design emerged from writing the tests first.</p>
<h2>Our experiences</h2>
<p>We experienced a couple of notable challenges when doing TDD in JS. Doing TDD in it self is not a problem. Some challenges appear when doing browser-specific things with JS. Such as asynchronous callbacks, handling the DOM and the AJAX browser API.</p>
<p>The DOM is an issue. When not using jQuery, there are a lot of quirks that can mess up tests in specific browsers. Also, doing DOM-operations without jQuery results in a lot of ugly code that affects readability.</p>
<p>Testing AJAX without support from the test framework is problematic, and is why several tools exist and mitigate this (Sinon.js, Mockjax, etc.). Before we changed to JSONP, we wanted to do this with no extra support, and ended up with an extremely simplified version of what the mentioned tools provide. But for most people it would be simpler to use an existing tool to help you do AJAX-testing.</p>
<p>But all these things mentioned above are relatively easy to overcome and the upside of being able to write tests for your JS code easily outweighs the small quirks you may experience. And you won’t regret spending time on writing tests when your code base is expanding and you need to make a change.</p>
<h2>Give me more!</h2>
<p><a href="http://sinonjs.org/">Sinon.JS</a> &#8211; Standalone test spies, stubs and mocks for JavaScript. Works with any unit testing framework.<br />
<a href="http://docs.jquery.com/Qunit">QUnit</a> &#8211; alternative to Jasmine. Developed by the jQuery-team<br />
<a href="https://github.com/cucumber/cucumber-js">Cucumber.JS</a> &#8211; early stages. Could be good.<br />
<a href="http://busterjs.org/">Buster.js</a> &#8211; a new test framework (currently in beta) from Christan Johansen (the man behind Sinon.js)</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/1TwH-dMOHSg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/getting-started-with-js-and-tdd/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<feedburner:origLink>http://open.bekk.no/getting-started-with-js-and-tdd/</feedburner:origLink></item>
		<item>
		<title>MVC med Sammy og Handlebars</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/8Q9hALedPI4/</link>
		<comments>http://open.bekk.no/mvc-med-sammy-og-handlebars/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 11:51:08 +0000</pubDate>
		<dc:creator>Hans Magnus Inderberg</dc:creator>
				<category><![CDATA[Dynamiske språk]]></category>
		<category><![CDATA[Grensesnittutvikling]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7807</guid>
		<description><![CDATA[I disse dager hvor server-side er ut og klient-side er kult har det dukket opp mange avanserte JavaScript-rammeverk som flytter kompleksitet fra serveren til nettleseren. Backbone, Knockout og JavaScriptMVC er alle gode eksempler som kan brukes til å lage komplekse applikasjoner, uten antikvariske operasjoner som lasting av hele sider eller rendering av HTML på serveren. I denne [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/sammy.png"><img src="http://open.bekk.no/wp-content/uploads/2012/01/sammy.png" alt="" width="748" height="150" /></a></p>
<p>I disse dager hvor server-side er ut og klient-side er kult har det dukket opp mange avanserte JavaScript-rammeverk som flytter kompleksitet fra serveren til nettleseren. <a href="http://documentcloud.github.com/backbone/">Backbone</a>, <a href="http://knockoutjs.com/">Knockout</a> og <a href="http://javascriptmvc.com/">JavaScriptMVC</a> er alle gode eksempler som kan brukes til å lage komplekse applikasjoner, uten antikvariske operasjoner som lasting av hele sider eller rendering av HTML på serveren. I denne nye verden tilbyr serveren et REST-API, og all koden for å bruke dette API-et er Javascript som kjøres av brukerens nettleser.</p>
<p>Vi vil gjerne presentere én metode for å strukturere komplekse JS-applikasjoner, sammen med to flotte biblioteker: <a href="http://sammyjs.org/">Sammy</a> og <a href="http://handlebarsjs.com/">Handlebars</a>.</p>
<p><strong>Sammy</strong> er ikke like kjent eller kraftig som de tidligere nevnte rammeverkene, men er likevel svært godt til sitt bruksområde og fortjener en vurdering ved valg av rammeverk. Hovedsakelig brukes Sammy til routing, hvor en URL besvares av en JS-funksjon, og til å rendre HTML-en som skal vises på den aktuelle siden. Biblioteket er i seg selv svært lite, og delegerer det meste av funksjonalitet til sin strålende plugin-arkitektur. I dag er Sammy tungt avhengig av jQuery.</p>
<p><strong>Handlebars</strong> har den siste tiden fått masse oppmerksomhet, og bygger på det allerede kjente template-rammeverket Mustache. Handlebars brukes til å sammenflette data og HTML på en enklere og strukturert måte. Hensikten er å skille HTML- og DOM-maipulasjon fra resten av applikasjonen, og Handlebars inneholder mange hjelpemetoder som gjør dette ganske elegant.</p>
<p><strong>Model-View-Controller (MVC)</strong> er en type arkitektur som kan brukes til komplekse klient-side JS applikasjoner. I vår (svært) løse definisjon av MVC får vi følgende struktur:</p>
<ul style="font-size: 120%; line-height: 1.7em;">
<li><em>Datamodellene </em>håndterer entiteter og kommunikasjon med serveren.</li>
<li><em>View-modellene står </em>for oppførselen og strukturen til HTML-elementene.</li>
<li><em>Controllerene</em> knytter datamodeller og view-modeller sammen mot spesifikke URL-er.</li>
</ul>
<p>God struktur er vanskelig i komplekse JS-applikasjoner. Språket gir store muligheter og få begrensninger, og ingen forslag til hvordan strukturen bør være. Det hele kan fort bli uoversiktelig hvis man ikke baserer seg på velkjent struktur, som for eksempel MVC. I denne teksten bygger vi deler av en slik applikasjon.</p>
<p>I eksempelet har serveren en liste personer, som vi ønsker å få tak i, instansiere som modeller og vise en liste av i nettleseren. All kode i denne bloggposten kommer fra <a href="https://github.com/hinderberg/sammy-handlebars-blog-example">en minimal eksempelapplikasjon du finner på Github</a>. Last den gjerne ned og prøv resultatet i din nettleser. Koden kan også brukes som refferanse om det er noe som er uklart i teksten.</p>
<h2>Datamodeller og API-kall</h2>
<hr />
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/neurons.png"><img class="alignnone size-full wp-image-7919" src="http://open.bekk.no/wp-content/uploads/2012/01/neurons.png" alt="" width="748" height="150" /></a></p>
<p>Datamodellene tar seg av kommunikasjon med serveren via Ajax-baserte HTTP-kall mot et REST-API. Det er mange måter dette kan gjøres på, det finnes ingen fasit, men her kommer ett eksempel. Her har vi kodet modellene selv, men merk at på samme måte som Handlebars tar seg av templates, og Sammy tar seg av controller-ene, kunne vi brukt et tredje bibliotek til å ta seg av datamodellene. Men la oss lage noe selv.</p>
<p>Noen vil kanskje reagere på at datamodeller her potensielt defineres to steder &#8212; hos klienten og på serveren &#8212; men det er viktig å huske at disse modellene har lite felles funksjonalitet. Datamodellene på klientsiden er der utelukkende for å hjelpe view-modellene, ved å abstrahere bort funksjonalitet for kommunikasjon med serveren, formatering av modelldata og lignende.</p>
<p>Det er to <em>oppgaver</em> som kan skilles i datamodellene:</p>
<ul style="font-size: 120%; line-height: 1.7em;">
<li>Selve datamodellene som instansieres og har metoder for å jobbe med hver entitet,</li>
<li>og statiske metoder for hver klasse av modeller, som blant annet gjør API-kall.</li>
</ul>
<p>Vi har valgt å bruke standard prorotype-baserte JS objekter. I dette eksempelet lager vi en modell kalt “person”, lagt under namespacet “myapp.models”.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* prototype for alle data-modeller. */</span>
myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">datamodel</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/* Metode for å instansiere en modell. */</span>
myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>prototype<span style="color: #339933;">,</span> properties<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">merge</span><span style="color: #009900;">&#40;</span>Object.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>prototype<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> properties<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/* Prototype for person-instanser. */</span>
myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">person</span> <span style="color: #339933;">=</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">datamodel</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">firstname</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; &quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">lastname</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/* Instansiering. */</span>
<span style="color: #003366; font-weight: bold;">var</span> person <span style="color: #339933;">=</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">person</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> 
    firstname<span style="color: #339933;">:</span> “Foo”<span style="color: #339933;">,</span> 
    lastname<span style="color: #339933;">:</span> “Bar” 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Som sagt kan API-kall tilhørende hver modell skilles ut i egne moduler. Dette er flott når man skal teste systemet, og hjelper holde kompleksiteten nede. Her er et enkelt eksempel på API-kall for modellen:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* Metode for å lage mange instanser. */</span>
myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">createAll</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>prototype<span style="color: #339933;">,</span> propertiesList<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> propertiesList.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>properties<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>prototype<span style="color: #339933;">,</span> properties<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/* Metoder for å gjøre kall mot person-API. */</span>
myapp.<span style="color: #660066;">api</span>.<span style="color: #660066;">person</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    all<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>callback<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009966; font-style: italic;">/* Hent listen over alle personer fra serveren. */</span>
        $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> 
	    success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>serverdata<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                callback<span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">createAll</span><span style="color: #009900;">&#40;</span>
                    myapp.<span style="color: #660066;">models</span>.<span style="color: #660066;">person</span><span style="color: #339933;">,</span> 
                    serverdata<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
            ........
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009966; font-style: italic;">/* Bruk */</span>
myapp.<span style="color: #660066;">api</span>.<span style="color: #660066;">person</span>.<span style="color: #660066;">all</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>people<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #009966; font-style: italic;">/* “people” er her et array av person-instanser. */</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dette kan virke som mye kode for enkle operasjoner, men etterhvert som applikasjonen blir større er det fint å ha alt som har med serverkommunikasjon og datamodeller skilt fra resten av applikasjonen. La oss nå se hvordan disse datamodellene kan kobles sammen med rendring av HTML.</p>
<p>&nbsp;</p>
<h2>View-modeller med Handlebars</h2>
<hr />
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/handlebars1.png"><img class="alignnone size-full wp-image-7913" src="http://open.bekk.no/wp-content/uploads/2012/01/handlebars1.png" alt="" width="748" height="120" /></a></p>
<p>View-modellene knytter data sammen med HTML. Disse modellene holder på dataene som trengs for å vise en side, representert av datamodellene. I tillegg legger view-modellene på oppførsel, animasjoner og hendelser på siden-, eller delen av siden de representerer. Dette kan for eksempel være ting som skal skje når brukeren klikker på en link, flytter på elementer eller vil lagre eller endre data.</p>
<p>Poenget med å bruke view-modeller er å abstrahere bort alt som omhandler hvordan HTML skal produseres og oppføre seg. På samme måte som datamodellene innkapsulerer alt som har med entiteter og server-kall, tar view-modellene seg av all JS-kode som manipulerer DOM-en direkte. Målet er som alltid å ende opp med veldefinerte og klart avskillte moduler med hver sine oppgaver. Her er et eksempel på en view-modell:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">myapp.<span style="color: #660066;">view</span>.<span style="color: #660066;">people</span> <span style="color: #339933;">=</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">viewmodel</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    compile<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span> people<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">people</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    apply<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#people li&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; clicked!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>En view-modell jobber i to faser og trenger to forskjellige metoder. For det første har vi compile-metoden, som returnerer alle variabler som skal kunne brukes fra template-filen. Deretter har vi apply-metoden, som kalles etter at template filen har blitt renderet.</p>
<p>Den første metoden gjør altså klar variabler som skal brukes, mens den andre tar seg av all DOM-manipuilasjon etter at HTML-en er rendret. <em>Apply-metodene til view-modellene er altså de eneste stedene i applikasjonen JS-kode jobber direkte med HTML-elementer, noe som gjør det hele svært ryddig</em>. Se eksempelapplikasjonen på GitHub [g] for mer av koden som jobber med view-modeller.</p>
<p>View-modellen jobber med en eller flere template-filer, som spesifiserer strukturen på markup-en til den aktuelle siden. Her er et eksempel på en slik template-fil:</p>

<div class="wp_syntax"><div class="code"><pre class="handlebar" style="font-family:monospace;">&lt;div id=&quot;content&quot;&gt;
{{ &gt;search }}
    &lt;ul id=&quot;people&quot;&gt;
    {{ #each people }}
        &lt;li&gt;{{ name }}&lt;/li&gt;
    {{ /each }}
    &lt;/ul&gt;
&lt;/div&gt;</pre></div></div>

<p>I Handlebars bruker man Handlebar Expressions til å hente ut objekter ved å skrive {<em>{ objektnavn }}</em>, eller <em>{{{ objektnavn }}}</em> når man ønsker å un-escape. <em>people</em> er definert av view-modellen og brukes direkte i template-filen. <em>name</em> er definert av data-modellen for person-entiteten, som også brukes direkte i dette templatet.</p>
<p>I templaten har vi også en partial komponent, kalt <em>search</em>. Partials vil bli brukt der man ønsker å dele opp templates og lage gjenbrukbare deler som kan brukes på tvers av andre templates. Partial-templaten vil også ha direkte tilgang til view-modellen og dens innhold, men vil som oftest tilhøre en egen view-modell.</p>
<p>I tillegg til å kunne hente ut objekter og kjøre funksjoner, kan man bruke såkalte Block Expressions. Block Expressions gjør det mulig å kjøre Block Helpers som er hjelpefunksjoner for å eksempelvis gjøre operasjoner med lister og sjekke verdier med if/else spørringer. Handlebars kommer med ett sett innebygde helpers, men man kan også lage sine egne om dette skulle være nødvendig.</p>
<p>Her er et eksempel på en Block Helper, som kjører en loop inntil et visst maksimalt antall ganger:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* Definering av en egen hjelpemetode kalt “until”. */</span>
Handlebars.<span style="color: #660066;">registerHelper</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'until'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #339933;">,</span> block<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> max <span style="color: #339933;">=</span> block.<span style="color: #660066;">hash</span>.<span style="color: #660066;">max</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> ret <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> j <span style="color: #339933;">=</span> context.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> j<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&gt;=</span> max<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
        ret <span style="color: #339933;">=</span> ret <span style="color: #339933;">+</span> block<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="handlebar" style="font-family:monospace;">/* Bruk av denne hjelpemetoden i en template-fil. */
{{ #until persons max=&quot;3&quot; }}
    {{ name }}
{{ /until }}</pre></div></div>

<p>En annen interessant mulighet man har i Handlebars er å gjøre kall mot parent-objektet til det objektet man jobber med. Her er et eksempel hvor vi bruker notasjonen “../” til å aksessere en variabel som tilhører parent-objektet til det vi looper gjennom:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* Variabel definert i view-modellen. */</span>
<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">family</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> surname<span style="color: #339933;">:</span> “I skogen”<span style="color: #339933;">,</span> members<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
    <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> “Hans”<span style="color: #339933;">,</span> age<span style="color: #339933;">:</span> “<span style="color: #CC0000;">90</span>” <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> “Grete”<span style="color: #339933;">,</span> age<span style="color: #339933;">:</span> “<span style="color: #CC0000;">100</span>” <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#123;</span> <span style="color: #000066;">name</span><span style="color: #339933;">:</span> “Ulven”<span style="color: #339933;">,</span> age<span style="color: #339933;">:</span> “<span style="color: #CC0000;">120</span>” <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="handlebar" style="font-family:monospace;">/* Bruk av variabelen i template-filen. */
{{ #each family.members }}
    {{ name }} {{ ../surname }}
{{ /each }}</pre></div></div>

<p>Dette er selvfølgelig bare noen få av muligheten man har med Handlebars, men de viser hvordan komplekse templates kan spesifiseres i template-filer som jobber direkte mot en view-modell. Dette sørger for praktisk innkapsulering av alt som dreier seg om HTML og DOM-elementer i applikasjonen.</p>
<p>La oss nå se hvordan det hele kobles sammen ved hjelp av controller-ene og Sammy.</p>
<h2>Controllere med Sammy</h2>
<hr />
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/sammy.png"><img class="alignnone size-full wp-image-7916" src="http://open.bekk.no/wp-content/uploads/2012/01/sammy.png" alt="" width="748" height="150" /></a></p>
<p>Controller-ene er selve limet som holder applikasjonen sammen. Disse beskriver hva som skal skje når en bruker besøker en URL. Controlleren bruker datamodellene til å hente data som trengs på den aktuelle siden, og rendrer HTML ved hjelp av de tidligere nevnte view-modellene og deres representative template filer. Vi trenger både routing og template-rendring, altså er dette en perfekt oppgave for Sammy.</p>
<div style="background-color: #eee; line-height: 1.7em; padding: 1.5em; font-size: 120%; margin-bottom: 1em;">For å få et inntrykk av hva mer enn dette Sammy kan brukes til er det bare å se på listen over tilgjengelige <a href="https://github.com/quirkey/sammy/tree/master/lib/plugins">plugins</a>. Eksempler inkluderer templating med mange forskjellige biblioteker, Form Builder som minner om hvordan Ruby on Rails setter opp skjemaer, Storage som innkapsulerer mange forskjellige lokale lagringsmetoder i et enkelt API, eller OAuth-pluginen, forklart av sitt eget navn.</div>
<p>Vi ønsker å bruke Sammy-spesifikk kode utelukkende i controller-ene, og ikke i andre deler av applikasjonen. På denne måten vil minst mulig av applikasjonen bli avhengig av dette rammeverket, i tilfelle man skulle ønske bytte det ut på et senere tidspunkt. I tillegg blir applikasjonen enklere å teste, spesielt på enhetsnivå, da vi ikke trenger å bry oss om Sammy annet enn i controller-ene.</p>
<p>Her er en kodebit som kjøres når brukeren gjør en GET-request mot URL-en “/#people”:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* Jobb på HTML-elementet “#page”. */</span>
$.<span style="color: #660066;">sammy</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#page&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* Bruk Handlebars-plugin. */</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #003366; font-weight: bold;">use</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Handlebars'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'hb'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009966; font-style: italic;">/* Start routes. */</span>
    myapp.<span style="color: #660066;">route</span>.<span style="color: #660066;">person</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">run</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #009966; font-style: italic;">/* Route for person-listen. */</span>
myapp.<span style="color: #660066;">route</span>.<span style="color: #660066;">person</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>app<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* Definer en route. */</span>
    app.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009966; font-style: italic;">/* Gjør et kall mot serveren. */</span>
        myapp.<span style="color: #660066;">api</span>.<span style="color: #660066;">person</span>.<span style="color: #660066;">all</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>people<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
            <span style="color: #009966; font-style: italic;">/* Definer hvilken template-filer som trengs. */</span>
            <span style="color: #003366; font-weight: bold;">var</span> template <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;template/person-list.hb&quot;</span><span style="color: #339933;">;</span>
            <span style="color: #003366; font-weight: bold;">var</span> partials <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> searchbox<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;template/shared/searchbox.hb&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009966; font-style: italic;">/* Instansierer view-modellene */</span>
            <span style="color: #003366; font-weight: bold;">var</span> search <span style="color: #339933;">=</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">view</span>.<span style="color: #660066;">shared</span>.<span style="color: #660066;">searchbox</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #003366; font-weight: bold;">var</span> list <span style="color: #339933;">=</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span>myapp.<span style="color: #660066;">view</span>.<span style="color: #660066;">people</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> people<span style="color: #339933;">:</span> people <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009966; font-style: italic;">/* Bytt ut innholdet i &quot;#page&quot; med ny HTML. */</span>
            context.<span style="color: #660066;">renderAll</span><span style="color: #009900;">&#40;</span>template<span style="color: #339933;">,</span> partials<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span>list<span style="color: #339933;">,</span> search<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Den første kodebiten sier at Sammy skal jobbe på HTML-elementet med ID-en “page”, definert i den initsielle HTML-filen. Del to tar tak i URL-en ved hjelp av en <em>route</em>-funksjon. En <em>route</em> består av et <em>verb</em>, en <em>sti</em>, og en <em>callback-funksjon</em>. Verbet er et av de velkjente HTTP-metodene POST, PUT, GET eller DELETE. Stien kan enten være en vanlig URL, eller en hash-basert URL som i dette eksempelet.</p>
<p>Hver Sammy-rute tar inn et context-objekt som inneholder mye informasjon om tilstanden til applikasjonen. Dette objektet inneholder også mange nyttige hjelpefunksjoner. For at applikasjonen skal holde seg modulær er det viktig å kunn bruke dette objektet i controllerene. Hvis context-objektet blir med til datamodellene eller view-modellene, vil disse bli avhengig av Sammy-logikk, som igjen vil komplisere testing og vedlikehold.</p>
<p>Det meste skjer i context.renderAll-metoden. Denne rendrer et template, et sett partials og en samling view-modeller ved hjelp av Sammy’s context-render-metode:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">context.<span style="color: #660066;">helpers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #009966; font-style: italic;">/* En hjelpefunksjon for å rendre sider med mange view-modeller. */</span>
    renderAll<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>tmpl<span style="color: #339933;">,</span> partials<span style="color: #339933;">,</span> models<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       	<span style="color: #003366; font-weight: bold;">var</span> context <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
       	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span>tmpl<span style="color: #339933;">,</span> myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">compileAll</span><span style="color: #009900;">&#40;</span>models<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>html<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            context.<span style="color: #660066;">swap</span><span style="color: #009900;">&#40;</span>html<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            myapp.<span style="color: #660066;">model</span>.<span style="color: #660066;">applyAll</span><span style="color: #009900;">&#40;</span>models<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> partials<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>context.render</em> tar først inn stien til template-filen man vil bruke. Det neste argumentet er dataene man vil bruke til å rendre template-filen, i vårt tilfelle representert dataene av en view-modell. Denne view-modellen vil da være tilgjengelig for template-filen når den rendres av Handlebars-pluginen til Sammy.</p>
<p>Callback-argumentet <em>context.swap</em> tar imot ferdig rendret HTML, og bytter ut hva som allerede er i elementet som jobbes på (“#<em>page</em>”) med den nye HTML-en.</p>
<p>Det siste argumentet, “partials”, er et objekt som kan inneholde flere deler som hovedtemplaten er avhengig av, for eksempel en topp, meny og bunn. Render-metoden cacher template-filene, uten å laste de på nytt hver gang, slik at operasjonen blir kjappere andre gang denne kalles.</p>
<p>En fin måte å organisere disse Sammy-routene på er å ha én JS-fil pr side (hvis det gir mening i applikasjonens sidestruktur, vel å merke). Metoden <em>$.sammy</em> kan brukes på tvers av filer uten problemer. Hver side får ofte flere routes for forskjellige operasjoner, for eksempel:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* settings.js: routes for én side. */</span>
&nbsp;
$.<span style="color: #660066;">sammy</span><span style="color: #009900;">&#40;</span>“#page”<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Vise innstillinger</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span>“#<span style="color: #339933;">/</span>settings<span style="color: #339933;">/</span>profile”<span style="color: #339933;">,</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span>“#<span style="color: #339933;">/</span>settings<span style="color: #339933;">/</span>friends”<span style="color: #339933;">,</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Lagre innstillinger</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">put</span><span style="color: #009900;">&#40;</span>“#<span style="color: #339933;">/</span>settings<span style="color: #339933;">/</span>profile”<span style="color: #339933;">,</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span>“#<span style="color: #339933;">/</span>settings<span style="color: #339933;">/</span>friends”<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> … <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Med controllerene på plass er applikasjonens struktur komplett:</p>
<ul style="font-size: 120%; line-height: 1.7em;">
<li><strong>Datamodellene</strong> innkapsulerer alt som beskriver entiteter og serverkall.</li>
<li><strong>View-modellene</strong> innkapsulerer alt som beskriver HTML-en og oppførselen til DOM-elementer, og kobler dette med datamodellene.</li>
<li><strong>Controllerene</strong> tar det hele i bruk og bruker datamodellene og view-modellene til å rendre flott HTML når brukerne besøker forskjellige URL-er.</li>
</ul>
<h2></h2>
<h2>Oppsummering</h2>
<hr />
<p>Selv om en struktur som den presentert her kan virke overdrevet i starten av et prosjekt, vil det hjelpe etterhvert som kompleksiteten og kodemengden øker. Det viktigste er å starte med et godt utgangspunkt, og deretter kontinuerlig forbedre og utvikle arkitekturen.</p>
<p>Det er selvfølgeilig ulemper med tunge JS-applikasjoner. De setter store krav til nettleserens JS-motor, og til utviklernes testing på tvers av mange nettlesere. Språkets frie natur gjør det enkelt å skrive lite vedlikeholdbar kode, og det er sjelden klare svar på hvordan noe bør gjøres.</p>
<p>Til syvende å sist krever komplekse JS-applikasjoner mye av disiplin innen struktur og testing, men denne friheten betyr også at JS-programmering er veldig spennende. Med gode biblioteker som Sammy og Handlebars blir det hele enda morsommere.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/8Q9hALedPI4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/mvc-med-sammy-og-handlebars/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		<feedburner:origLink>http://open.bekk.no/mvc-med-sammy-og-handlebars/</feedburner:origLink></item>
		<item>
		<title>Ett år med Git og Github</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/JkcKgga-ZLA/</link>
		<comments>http://open.bekk.no/et-ar-med-git-og-github/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 07:05:11 +0000</pubDate>
		<dc:creator>Jøran Vagnby Lillesand</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Fri Programvare]]></category>
		<category><![CDATA[IT-rådgivning]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Virksomhet 2.0]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[versjonskontroll]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7775</guid>
		<description><![CDATA[For et drøyt år siden gikk prosjektet mitt over til Git og Github for versjonskontroll. Dette er en beskrivelse av noen av mine erfaringer fra året som har gått.]]></description>
			<content:encoded><![CDATA[<p>For et drøyt år siden besluttet prosjektet jeg sitter på å migrere fra internt hostet Subversion (SVN) til Git hostet på Github. Jeg var skeptisk. Jeg syntes SVN løste våre behov helt ok og så ikke helt behovet for å bruke tid og ressurser på å gå over til noe annet.</p>
<p>Dette handler om mine subjektive erfaringer med forskjellene fra tiden med SVN. Jeg kommer ikke til å skrive noe om hvordan vi migrerte til Git eller om tekniske forskjeller på de to versjonskontrollsystemene. Dette finnes det masse gode ressurser på allerede. Dette innlegget kommer til å handle om de forskjellene som faktisk har vært med på å endre min hverdag.</p>
<h2>Branch og merge</h2>
<p>Det er umulig å komme utenom den uovertrufne støtten for branching og merging i Git. Med Subversion opplevde jeg branching og den påfølgende mergingen som tungvint og vanskelig. Med Git er det lett å lage og håndtere flere branches. Github gjør veldig enkelt å holde oversikt over status på hver enkelt branch ved hjelp av verktøy som for eksempel <a target="_blank" title="network graph" href="https://github.com/blog/39-say-hello-to-the-network-graph-visualizer">network graph</a> og branch view.</p>
<p>Dette har for oss vist seg å være en god støtte for å øke hyppigheten for produksjonssettinger. Når det er lett å håndtere branches er det enkelt å holde master-branchen helt ren, slik at vi kan produksjonssette når vi ønsker.</p>
<p><img src="http://open.bekk.no/wp-content/uploads/2012/01/branch-small-e1326729553879.png" alt="Github network graph" /></p>
<h2>READMEs</h2>
<p>En av de tingene som &#8211; kanskje overraskende &#8211; har vist seg å være mest nyttig er READMEs på Github. Github støtter en <a target="_blank" title="rekke markup-språk" href="https://github.com/github/markup">rekke markup-språk</a>. Selv om det i utgangspunktet er en veldig enkel sak å skrive dokumentasjon for alle prosjektene og legge det et sted, har det vist seg svært kraftig at dette er så nært koden som mulig &#8211; og så synlig som mulig. Her har Github sin løsning vært utmerket for oss! Her legger vi instruksjoner om hvordan man kommer i gang med utvikling fra scratch (nye folk inn på prosjektet), tips til utvikling, informasjon om hvordan man deployer og så videre. At dokumentasjonen er så kodenær og synlig oppfordrer også til scripting og automatisering, som det har blitt mer og mer av.</p>
<h2>Sosial versjonskontroll</h2>
<p>Github kaller seg sosial versjonskontroll. Selv om dette er noe som opprinnelig ble lagd med fokus på open source prosjekter, gir det muligheter som også passer utmerker til vanlig enterprise-utvikling. Å ha en side man kan besøke for å se statusen til kildekontrollen veldig nyttig.</p>
<p>Sosiale features på GitHub som vi benytter oss hyppig av:</p>
<ul>
<li>Diskutere commits &#8211; helt ned på enkeltlinjer om ønskelig.</li>
<li>Følge med på ulike branches (hvor mange commits de er bak/foran master).</li>
<li>Sende pull requests på ferdige feature branches</li>
</ul>
<h2>Pris</h2>
<p>Github har en hyggelig prismodell &#8211; hvertfall hvis man sammenlikner med andre enterprisy tilbydere av versjonskontroll. Standardprisene deres gjelder ved hosting av data i skyen (hos Rackspace). Hvorvidt det er aktuelt å hoste koden sin hos en tredjepart varierer naturligvis fra prosjekt til prosjekt. Dersom cloud hosting ikke er aktuelt finnes det et <a target="_blank" title="enterprise-alternativ" href="https://github.com/blog/978-introducing-github-enterprise">enterprise-alternativ</a>.</p>
<h2>Snill læringskurve</h2>
<p>Git er et avansert versjonskontrollsystem. Likevel har det i utgangspunktet en veldig snill læringskurve. De første månedene brukte jeg Git omtrent akkurat som jeg tidligere brukte SVN. Først ved behov og lyst begynte jeg gradvis å ta i bruk mer og mer avansert funksjonalitet &#8211; funksjonalitet som jeg nå bruker omtrent hver dag.</p>
<h2>Tilgjengelighet</h2>
<p>Siden Github er hostet i skyen kan man få tak i det fra hvor som helst i verden, uten å måtte bruke VPN. De har også veldig god oppetid: vi har opplevd nedetid én gang på godt over ett år. Det er veldig sannsynlig at et internt hostet versjonskontrollsystem vil ha adskillig mye mer nedetid i løpet av et år enn det Github vil ha. Sikkerhet og tilgangskontroll er ivaretatt ved bruk av SSH-nøkler for hver enkelt utvikler.</p>
<h2>Konklusjon</h2>
<p>Git og Github har hos oss vært en revolusjon som ikke har føltes som en revolusjon. Ved å være litt bedre på så godt som alle aspekter av versjonskontroll har det fjernet masse små irritasjoner hos oss utviklere &#8211; og dermed git oss mulighet til å fokusere mer på kundens krav. I tillegg har det store antallet nyttige småting i kombinasjonen Git og Github gitt oss de verktøyene vi trenger til å endre prosessen vår til å møte kundens behov bedre.</p>
<p>Når man tar med i vurderingen av kostnaden for å gå over er ganske lav, er dette egentlig en no brainer for meg: <em>Jeg anbefaler Git!</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/JkcKgga-ZLA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/et-ar-med-git-og-github/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://open.bekk.no/et-ar-med-git-og-github/</feedburner:origLink></item>
		<item>
		<title>Personlighet i emosjonell design – hvordan? (4:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/dlqpVbVDPzw/</link>
		<comments>http://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 08:19:44 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7550</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. Innlegg nummer 4 fortsetter vi å se på hvordan vi kan få til emosjonell design gjennom å bygge personlighet!]]></description>
			<content:encoded><![CDATA[<h5><em>I de tidligere innleggene har jeg gitt en intro til emosjonell design gjennom boken “Design for emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a>, ved å snakke om <span style="color: #ff0000"><a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/">“Hva?”</a></span>, <span style="color: #ff0000"><a href="https://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/trackback/">“Hvorfor?”</a></span> og begynne så smått på <span style="color: #000000"><a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">“Hvordan?” gjennom å snakke om psykologiske fellesnevnere.</a></span> Denne gangen skal vi se videre på “Hvordan?” gjennom personlighet.</em></h5>
<h2>Personlighet</h2>
<p>Ved siden av å kunne bruke følelser som psykologiske fellesnevnere i emosjonell design (som vi snakket om i <span style="color: #000000"><a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">mitt forrige innlegg</a></span>), kan vi jobbe med den emosjonelle komponenten som ligger oppå følelsene, nemlig personlighet.</p>
<p>I denne sammenheng er det møtet mellom personligheter som er interessant. Personligheten til brukerne er selvsagt til stede, så den komponenten det må jobbes med her er systemets personlighet. Dette kan kanskje høres litt rart ut, men husk at det er først i møtet mellom personligheter at følelser oppstår! I boka snakker derfor Aarron om å jobbe med å gi systemet personlighet.</p>
<p>Alle kjenner til hvordan personligheter opererer i det vanlige liv, og alle vet at disse kan være uforutsigbare, og at av og til er det full krasj! Det kan derfor føles litt risky å introdusere noe som er så åpent for tolkning i våre dyrebare systemer, og det er lett å forstå hvorfor mange kan stille seg litt skeptisk til dette.</p>
<p>Nå har det seg imidlertid slik at vi kanskje bare må innse at tiden har kommet. Tidligere, da nettet var ungt og fortsatt i stor grad ble oppfattet som (og i noen tilfeller var!) useriøst og farlig, føltes det viktig å virke streit og veldig seriøs i sin fremstilling. Mange siter ble veldig like, og man kunne i stor grad skjule seg bak en generisk, flat og forretningsmessig fasade. Dette henger i stor grad igjen selv om nettet har modnet, og gjør at nettet er fylt med et mye flatere persongalleri enn verden ellers! Tiden har kommet for å skille seg ut i mengden ved å vise litt mer av seg selv!</p>
<h2>Å finne sin personlighet</h2>
<p>Men hva skal så denne personligheten være? Man skal selvsagt ikke finne opp en personlighet til systemet sitt sånn helt uten videre – falske personligheter fungerer sjelden! Det man velger å vise av personlighet må være ekte, og virkelig være det systemet står for og det bedriften bak virkelig er. Mange kjenner sikkert til teknikken “personas”. Personas brukes vanligvis til å beskrive personligheten til brukere i systemets målgruppe, slik at man kan bruke dette som en styrepinne for å treffe målgruppen. Aarron foreslår at man drar dette enda lengre, og faktisk utvikler en persona for systemet eller til og med brandet. Det er rett og slett “mannen i maskinen” som skal beskrives, slik at brukerne møter nettopp dette; en mann heller enn en maskin. Først når dette er på plass kan de gode møtene mellom brukerpersonligheter og systempersonligheter oppstå!</p>
<p>Aarron tilbyr en <a href="http://aarronwalter.com/design-personas/">mal</a> for hvordan å jobbe frem en brand- eller sitepersona på sine nettsider.</p>
<h2>Suksess!</h2>
<p>Det finnes en mengde gode eksempler på systemer som har fått til treffende og ekte personligheter. Et eksempel er MailChimp, et mailprogram som fremstår som lekent og hjelpsomt, og som til og med går så langt som å ha en liten maskot-ape. Apen har en solid kropp og et sympatisk fjes – noe som hinter om et solid system med en vennlig overflate!</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/mailchimp2.png"><img class="aligncenter size-full wp-image-7556" src="http://open.bekk.no/wp-content/uploads/2011/12/mailchimp2.png" alt="" width="521" height="378" /></a></p>
<p>&nbsp;</p>
<p>For de systemene som bruker litt humor i sin personlighet er dette “omvendt-håkkisveis” prinsippet viktig; vi kan godt ha party in the front, men vi må vise at vi mener business in the back! Apen blander seg nemlig aldri inn i arbeidsflyen, og kommer aldri med tips eller kommentarer til selve arbeidet (som var der den beryktede bindersen til Microsoft i sin tid feilet – han kom med irrelevante og forstyrrende tips…), men han endrer seg stadig og sier morsomme og forfriskende ting. Folk får rett og slett lyst å arbeide seg gjennom for å se hva han gjør!</p>
<p>Nå er det slett ikke meningen at alle skal ha en maskot og bruke humor for alle penga, og i noen tilfeller fungerer ikke humor og lettbenthet i det hele tatt, f.eks ville det vært vanskelig å se for seg hos Kirkens Nødhjelp. Da er varme og personlige historier ofte en god vei å gå. Poenget er uansett at gjennom å gi noe med mer personlighet og ektehet, er man et steg på veien mot å knytte emosjonelle bånd.</p>
<p><em>Da har du fått mye bakgrunn for hvordan emosjonell design kan anvendes. I tillegg er det alltid kjekt med noen helt konkrete praktiske veier å gå, og disse kommer i <span style="color: #000000"><a href="https://open.bekk.no/praktiske-fremgangsmater-i-emosjonell-design-56/">mitt neste innlegg</a></span>.</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/dlqpVbVDPzw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/</feedburner:origLink></item>
		<item>
		<title>Folkevare</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/QBW0T7Gj468/</link>
		<comments>http://open.bekk.no/folkevare/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 12:18:45 +0000</pubDate>
		<dc:creator>Holger Ludvigsen</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Kvalitet og testing]]></category>
		<category><![CDATA[Prosjektledelse]]></category>
		<category><![CDATA[Teknologi]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7698</guid>
		<description><![CDATA[Har du tenkt på at utvikling handler om tre aspekter? Det er maskinvaren, det vi kan ta og føle på. Det er programvaren, et abstrakt domene. Og det er folkene som gjør det hele mulig, utviklerne, som for eksempel deg og meg.]]></description>
			<content:encoded><![CDATA[<p><strong><br />
Har du tenkt på at utvikling handler om tre aspekter? Det er maskinvaren, det vi kan ta og føle på. Det er programvaren, et abstrakt domene. Og det er folkene som gjør det hele mulig, utviklerne, som for eksempel deg og meg.</strong></p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/1.jpg"><img class="aligncenter size-full wp-image-7723" src="http://open.bekk.no/wp-content/uploads/2012/01/1.jpg" alt="" width="748" height="259" /></a></p>
<p>For 25 år siden ble det utgitt en bok Peopleware &#8211; Productive Projects and Teams. Dette er en klassiker, og jeg synes det er sunt å minnes på de prinsippene som den omhandler. I tillegg til hardware og software er det en viktig del som vi kan kalle peopleware. Det er det menneskelige aspektet ved utvikling. Det er bare én måte å få frem de systemene og løsningen som vi utvikler, og det er gjennom mennesker. Dette er smarte, høyt utdannede mennesker med en driv for teknologi.</p>
<p>Disse folkene er katalysatoren for det vi lager. Hvordan oppnår vi da de beste resultatene? Svaret er ikke kynisk eller maskinelt. Peopleware er fortsatt utrolig relevant, og det er ikke til å kimse av etter hele 25 år. Årsaken er at folk fortsatt er folk. De har de samme behovene, motivasjonene og relasjonene. Det er lett å fokusere på hvor raskt vår bransje utvikler seg teknologisk. Men folkene bak, de som gjør det hele mulig, de som skaper selve verdien. De er like menneskelige som før.</p>
<p>Det er en utbredt illusjon i databransjen, at det vi jobber med er high tech. Vi jobber med avanserte, kompliserte tekniske systemer. Det er teknologi på sitt ypperste. Datamaskiner er noe av det mest imponerende og kraftige mennesker har utviklet. Og nøkkelen til å lykkes er å forstå og benytte den mest avanserte, den høyeste, teknologien. Når de teknologiske grensene pushes går vår verden fremover, og fremskritt og konkurransefortrinn blir mulig.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/2.jpg"><img class="aligncenter size-full wp-image-7724" src="http://open.bekk.no/wp-content/uploads/2012/01/2.jpg" alt="" width="748" height="259" /></a></p>
<h2>Mennesker vs. teknologi</h2>
<p>Men tilfellet er at databransjen ikke er high tech. Dette er ikke rakettforskning. De fleste systemer har ikke behov for eller berører avansert datavitenskap eller teknologi. Mange prosjekter er avarter av create, read, update og delete, eller handler om å vise data som allerede finnes på en ny måte til brukeren. Det er som oftest ingen fysikk eller matematikk bak systemene vi lager. Selv om hardwaren er avansert og datamaskinen fundamentalt kompleks, så kan vi ikke lure oss selv til å tro at vi er i high-tech-bransjen. Det er fristende å tenke slik. At å løse de tekniske, teoretiske problemene er nøkkelen til suksess. Det er på en måte en &#8220;enkel&#8221; løsning. Det er mer håndterbart å finne den optimale algoritmen enn å forstå hvorfor Arne ikke jobber produktivt. Men suksessfulle prosjekter og effektive team handler ikke om teknologi. Det handler ofte om menneskene bak. Vår bransje er teknisk, men det er ikke teknologien som skaper suksess. Om det bare hadde vært så enkelt.</p>
<p>Har du noen gang vært på et dream team? Fått følelsen av at dere sammen jobber nær optimalt og har høy produktivitet? Har du noen gang jobbet i det motsatte? En samling mennesker som ikke får utrettet store ting. Et team på papiret, men ikke i praksis? Resultatetene fra et dream team er ikke basert på teknologien de bruker, men heller av dynamikken mellom menneskene i teamet. De utfyller hverandre. De kommuniserer godt. De vet hvor de har hverandre, og hvordan de kan bruke hverandre. Teamet er støpt. De har høy suksess med sine prosjekter, og grunnen er at de kan bruke all innsats på å løse prosjektets problemer og klientens behov, i stedet for andre ikke-verdiskapende utfordringer.</p>
<p>Hva kjennetegner et slikt team? Et tegn er at de er kvalitetsorienterte. De vet hvilke kvalitative ting som gjør prosjektet vellykket, og de fokuserer på dem. Kvalitet i datasystemer ses ofte på som en kostnad, og noe man oppnår ved å ofre andre ting, som for eksempel penger og tid. Men the dream team oppnår suksess med kvalitet som en drivfaktor. Kvaliteten gir to verdier: Man unngår bortkastet tid på å &#8220;rydde opp&#8221; om man gjør det ordentlig fra første stund. Og kvalitet er en motivasjonsfaktor i seg selv.</p>
<p>I stedet for å &#8220;cut the corners&#8221; vil the dream team gjøre det ordentlig. Det man oppnår med dette er en jevn fremgang uten skitne overraskelser som for eksempel at man ikke har noen enhetstester, eller at man har hardkodete verdier som senere ønskes å endres. Progresjonen blir kanskje lavere enn et forhastet team, men den er forutsigbar uten teknisk gjeld og andre overraskelser.</p>
<p>Jeg ble engang forsøkt rekruttert av et større IT-selskap. Jeg spurte dem rett ut: Hvorfor bør jeg jobbe hos dere? Svaret deres var: Fordi vi er den beste aktøren i markedet og har de mest fornøyde kundene. Vi er de beste og mest suksessfulle. Rekruttererne tenkte nok at dette var imponerende, men jeg tenkte &#8220;what&#8217;s in it for me?&#8221;. Folk har lyst til å realisere seg seg selv, og sine behov. Ikke bedriftens behov og finansielle målsetninger. Heldigvis finnes det en synergi her. Ved å oppfylle arbeidernes behov, kan bedriftens mål nås. Kvalitet er en motivasjon og drivkraft i seg selv. Forteller du et team at kvaliteten i det de gjør ikke er så viktig, så vil selvrespekten og moralen følge derhen. Mennesker har en iboende kraft til å realisere seg selv, å lage ting som er så bra som de har kraft til å få til.</p>
<p>Et slikt støpt team utvikler elitiske holdninger. Det er et godt tegn. De er stolte av seg selv, og har tro i sine evner. Slike team vil også tendere mot å være selvledende. Siden motivasjonen er høy, og de ønsker å nå organisasjonens mål vil de selv ta grep for å få dette til. Fra et manager-perspektiv er dette en drømmesituasjon; og bør være et mål i seg selv.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/3.jpg"><img class="aligncenter size-full wp-image-7725" src="http://open.bekk.no/wp-content/uploads/2012/01/3.jpg" alt="" width="748" height="260" /></a></p>
<h2>Miljø</h2>
<p>Mennesker er i høy grad et produkt av omgivelsene rundt en. Disse omgivelsene kan løfte en frem og få det beste ut av en, eller de kan stikke kjepper i hjulene. Har du noen gang jobbet på kontoret sent på kvelden eller i helgen? Kontorlandskapet er tomt, det er stille og øde. Der sitter du, på din sedvanlige plass. Har du lagt merke til at man ofte er høyst effektiv i dette miljøet? Man har kanskje satt av en liste med oppgaver man må få ferdig. Det ble ikke plass til dem i den vanlige arbeidstiden, så man setter opp en økt på kvelden eller i helgen. Man pløyer gjennom de oppgavene. Man går hjem med følelsen av at i dag var jeg effektiv. God progresjon i dag, godt jeg tok meg tid til den ekstra økten.</p>
<p>En viktig årsak er nok rett og slett at du fikk være i fred. Det er en tendens for åpne kontorlandskap i vår bransje. Fra åtte om morgenen til fire om ettermiddagen er det folk rundt deg. Disse folkene skaper støy, uro og avbrytelser. På grunn av den innebygde forsinkelsen vårt sinn tar for å komme ordentlig i gang med en mental oppgave kan disse forstyrrelsene hindre produktiviteten. Vi jobber i en kunnskapsbransje, og tankekraft er essensen i produktene vi skaper. God konsentrasjon er avgjørende, men til dels ikke mulig i et støyende og kollektivt kontorlandskap. Det er en kontradiksjon egentlig; vi har høy utdannelse, jobber med kompliserte abstrakte konsepter som ikke har noen fysisk manifestasjon. Men allikevel er en lukkbar kontordør en luksus bedriften ikke tar seg råd til.</p>
<p>I Peopleware foretok de en programmeringsøvelse hvor et spesifisert system skulle implementeres. De gruppene som gjorde det godt ble sammenlignet med de som ikke nådde milepælene på samme tid:</p>
<table>
<tbody>
<tr>
<td></td>
<td>Den beste fjerdedelen</td>
<td>Den svakeste fjerdedelen</td>
</tr>
<tr>
<td>Hva er ditt eget arbeidsområde?</td>
<td>7 m2</td>
<td>4 m2</td>
</tr>
<tr>
<td>Er arbeidsområde stille?</td>
<td>57 % ja</td>
<td>29 % ja</td>
</tr>
<tr>
<td>Er arbeidsområdet privat?</td>
<td>62 % ja</td>
<td>19 % ja</td>
</tr>
</tbody>
</table>
<p>Resultatene er kanskje ikke overraskende. De som gjorde det best hadde avlukkede kontorer som de delte med 0, 1 eller 2 andre. De svakeste jobbet i åpne områder. Mange kan nok si seg enige i at kollektive rom hemmer konsentrasjonen. Men har du kvantifisert hvor mye plassbesparelsene koster i produktivitet?</p>
<h2>Management</h2>
<p>Hva er jobben til en manager? Han driver ikke direkte med verdiskapningen. Det er det utviklerne som gjør. Det er de som løser kunden og brukernes problemer. En av managerens viktigste oppgaver er å få de under ham til å gjøre en god jobb. Den beste jobben gitt deres forutsetninger. Det finnes mange ulike synspunkter på hvordan man får dette til. En viktig management-oppgave er å sette deadlines. Slike frister kan brukes som et virkemiddel i seg selv. Parkinsons &#8220;lov&#8221; sier at arbeid utvider seg selv til å fylle tiden det er satt av til. Vi kjenner alle godt til rasjonalen bak. Om man har press på seg skynder man seg. Om noe ikke haster kan man ta seg bedre tid. Dette leder til en logikk som er mye brukt i management. Tighte, kanskje urealistiske deadlines virker motiverende og øker produktiviteten. Bare pass på å ikke avslør at deadlinen er kunstig tidlig!</p>
<p>I praksis fungerer det ikke. Utviklerens produktivitet og arbeidsmetode er avhengig av deadlines, men en urealistisk deadline kan være høyst demoraliserende. En undersøkelse ble foretatt blant flere titalls prosjekter. Det ble sett på hvem som utførte tidsestimatetene, og hvor høy produktiviteten var for hver oppgave. Hvor utvikleren gjorde estimatet var produktiviteten 8. Dette er så klart et relativt tall. Hvor utviklerens sjef gjorde estimatet var produktiviteten 6.6. Haha, tenker man så klart. Dumme manageren tror han vet bedre enn gutta på gulvet!</p>
<p>Men i tilfeller hvor en ekstern system-analytiker gjorde estimeringen var produktiveten enda høyere med 9.5. Hva er grunnen til dette? Det kan være at systemanalytikeren er en profesjonell estimerer med god erfaring fra tilsvarende implementasjoner. At hans estimater er nærmere det egentlige innsatsbehovet kan være motiverende i seg selv. Realistiske deadlines er gir dermed høyst produktivitet. Et interessant resultat oppsto i oppgaver hvor intet estimat i det hele tatt var gitt. Her var produktiviteten 12, og dermed høyest. Dette kontradikterer helt tydelig Parkinsons lov, og setter i tvil dens effektivetet som management-verktøy.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2012/01/4.jpg"><img class="aligncenter size-full wp-image-7726" src="http://open.bekk.no/wp-content/uploads/2012/01/4.jpg" alt="" width="748" height="260" /></a></p>
<h2>Dream manager</h2>
<p>Et dream team krever en dream manager. Men hva kjennetegner en slik manager? Det er kanskje ikke hva en tradisjonelt forbinder med ledelse. Et dream team har en iboende egenskap å gjøre det godt, og en dream manager <em>enabler</em> dette. Det er ikke så lett å måle en managers evne til å enable sitt team, men det er allikevel en av det viktigste egenskapene. Det motsatte ville vært defensivt management. En defensiv manager stoler ikke på sine &#8220;undersåtter&#8221;. Han er opptatt av sitt eget bilde, og forsvarer det mot eventuelle utfordringer. Han ser på seg selv om drivkraften bak teamets progresjon og suksess, og underminerer deres evne til fatte de riktige avgjørelsene selv.</p>
<p>Et godt motivert og fungerende team er en drivkraft i seg selv. En god manager vil utnytte disse kreftene og enable og løfte teamet. Hindre i veien elimineres, og byråkratiske eller organisatoriske problemer løses. Manageren er oljen i teamets maskineri. Disse egenskapene er ikke alltid like lette å observere på overflaten. Kanskje manageren virker overflødig på grunn av teamets selvstendighet og effektivitet. Men nettopp dette kan være resultatet av en managers dedikerte arbeid bak kulissene.</p>
<h2>Folkevare</h2>
<p>Data og systemutvikling er tilsynelatende en teknologisk, komputasjonell bransje. Men faktum er at det er menneskene som jobber med dette som er drivkraften. De teknologiske utfordringene er interessante og nyttige som et minstemål. Men løsningene bunner alltid ut i mennesker som jobber sammen. Mennesker med sine behov, sine mål og sine motivasjoner. Disse endrer seg ikke i samme takt som prosessorkraft og minnestørrelse.</p>
<p>Det er ikke like lett å analysere sosiologien bak utvikling som det er å drøfte teknologien, men x-faktoren i systemutvikling er menneskene bak. Mens maskinvare og programvare skyter fremover, er det fortsatt de samme type mennesker som jobber med disse tingene. Kun ved å forstå disse temaene kan man få det meste ut av teknologien og lykkes i sine prosjekter.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/QBW0T7Gj468" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/folkevare/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/folkevare/</feedburner:origLink></item>
		<item>
		<title>Java til Scala #4: null som ukjent</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/p1-ZYiroh0M/</link>
		<comments>http://open.bekk.no/java-scala-null/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 12:39:34 +0000</pubDate>
		<dc:creator>Eivind Waaler</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[option]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=6243</guid>
		<description><![CDATA[Et typisk problem med Javakode er bruken av null for objekt-referanser som ikke har noen verdi. Typisk vil et API returnere null i de tilfeller den etterspurte egenskapen ikke har noen verdi. For eksempel slik, ikke alle personer har noen registrert partner: // Returns &#34;null&#34; if no partner Person partner = customer.getPartner&#40;&#41;; &#160; // Potensial [...]]]></description>
			<content:encoded><![CDATA[<p>Et typisk problem med Javakode er bruken av <code>null</code> for objekt-referanser som ikke har noen verdi. Typisk vil et API returnere <code>null</code> i de tilfeller den etterspurte egenskapen ikke har noen verdi. For eksempel slik, ikke alle personer har noen registrert partner:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Returns &quot;null&quot; if no partner</span>
Person partner <span style="color: #339933;">=</span> customer.<span style="color: #006633;">getPartner</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Potensial NullPointerException</span>
doStuff<span style="color: #009900;">&#40;</span>partner.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Safe use - ugly code</span>
<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>partner <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  doStuff<span style="color: #009900;">&#40;</span>partner.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>De fleste kodebaser på Java-prosjekter har mange <code>null</code>-sjekker, og de får gjerne fler etter at man oppdager <code>NullPointerException</code> på steder man ikke hadde forutsett. Dette gjør koden stygg og uoversiktlig. Og enda verre blir det hvis man har flere nøstede objekter:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>partner <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">Name</span> partnerName <span style="color: #339933;">=</span> partner.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>partnerName <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> partnerFirstName <span style="color: #339933;">=</span> partnerName.<span style="color: #006633;">getFirstName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>partnerFirstName <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      doStuff<span style="color: #009900;">&#40;</span>partnerFirstName.<span style="color: #006633;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Hvordan kan man løse dette problemet i Scala? Jo, ved å ta i bruk <a href="http://www.scala-lang.org/api/current/index.html#scala.Option" target="_blank"><code>Option</code>-typen</a>. Den har enten verdien <code>None</code> hvis det ikke er noen verdi, eller <code>Some[T]</code> hvis det er noen verdi. Selve verdien kan hentes på en rekke forskjellige måter. Det som er fint er at <code>None</code> også er et objekt med metoder, slik at man slipper exceptions om man ikke eksplisitt sjekker om verdien er satt.</p>
<p>Hvis vi selv skriver koden kan vi la verdien returnere en <code>Option</code> av typen i stedet for <code>null</code>/typen direkte:</p>

<div class="wp_syntax"><div class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #008000; font-style: italic;">// Returns Option[Person] instead of Person directly</span>
<span style="color: #0000ff; font-weight: bold;">val</span> partner <span style="color: #000080;">=</span> customer.<span style="color: #000000;">getPartner</span>
&nbsp;
<span style="color: #0000ff; font-weight: bold;">if</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">!</span>partner.<span style="color: #000000;">isEmpty</span><span style="color: #F78811;">&#41;</span> <span style="color: #F78811;">&#123;</span>
  doStuff<span style="color: #F78811;">&#40;</span>partner.<span style="color: #000000;">get</span>.<span style="color: #000000;">getName</span><span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></div></div>

<p>Dette så jo ikke spesielt kult ut. Hvis vi fortsatt må sjekke om verdien er satt kan vi jo like godt sjekke for <code>null</code>? Men siden vi har masse funksjonelle godsaker tilgjengelig trenger vi ikke gjøre det. Metoden <code>foreach</code> vil bare la være å gjøre noe om verdien er <code>None</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="scala" style="font-family:monospace;">partner.<span style="color: #000000;">foreach</span><span style="color: #F78811;">&#40;</span>doStuff<span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>.<span style="color: #000000;">getName</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></pre></div></div>

<p>Det nøstede eksempelet løses fint med metoden <code>map</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="scala" style="font-family:monospace;">partner.<span style="color: #000000;">map</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>.<span style="color: #000000;">getName</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">map</span><span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>.<span style="color: #000000;">getFirstName</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">foreach</span><span style="color: #F78811;">&#40;</span>doStuff<span style="color: #F78811;">&#40;</span><span style="color: #000080;">_</span>.<span style="color: #000000;">toUpperCase</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span></pre></div></div>

<p>Eller tilsvarende med <code>for-comprehension</code> om man synes det blir rotete med alle metodene (mindre-enn tegnet blir dessverre feil her):</p>

<div class="wp_syntax"><div class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #0000ff; font-weight: bold;">for</span> <span style="color: #F78811;">&#123;</span>
  name <span style="color: #000080;">&amp;</span>lt<span style="color: #000080;">;</span>- partner.<span style="color: #000000;">getName</span>
  firstName <span style="color: #000080;">&amp;</span>lt<span style="color: #000080;">;</span>- name.<span style="color: #000000;">getFirstName</span>
  upperCaseName <span style="color: #000080;">&amp;</span>lt<span style="color: #000080;">;</span>- firstName.<span style="color: #000000;">toUpperCase</span>
<span style="color: #F78811;">&#125;</span> <span style="color: #F78811;">&#123;</span>
  doStuff<span style="color: #F78811;">&#40;</span>upperCaseName<span style="color: #F78811;">&#41;</span>
<span style="color: #F78811;">&#125;</span></pre></div></div>

<p><code>Option</code> løser altså problemet med <code>null</code>-sjekker. En siste liten detalj er at <code>Some(null)</code> er <code>None</code>. Det vil si at om du bruker et eksisterende Java-API som kan returnere <code>null</code> kan du bare pakke rundt med <code>Some</code> og slippe <code>null</code>-sjekk uansett. For eksempel om man henter parametre fra en http request, metoden <code>getOrElse</code> lar deg sette en default verdi hvis verdien er <code>None</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="scala" style="font-family:monospace;"><span style="color: #008000; font-style: italic;">// Typical http request in Java-servlet-api</span>
<span style="color: #0000ff; font-weight: bold;">val</span> name <span style="color: #000080;">=</span> Some<span style="color: #F78811;">&#40;</span>request.<span style="color: #000000;">getParameter</span><span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;name&quot;</span><span style="color: #F78811;">&#41;</span><span style="color: #F78811;">&#41;</span>.<span style="color: #000000;">getOrElse</span><span style="color: #F78811;">&#40;</span><span style="color: #6666FF;">&quot;empty-name&quot;</span><span style="color: #F78811;">&#41;</span></pre></div></div>

<p>Konklusjonen er at bruken av <code>null</code> som default/ukjent verdi i Java utgjør et problem for de som skal benytte koden. Dersom man programmerer i Scala kan man bruke <code>Option</code> for å vise ta verdien ikke nødvendigvis er satt, i tillegg til at man tillater funksjonell bruk uten eksplisitt sjekking av verdien.</p>
<p>Må man skrive kode i Java kan det være lurt å ta i bruk en egen klasse for å representere slike verdier. For eksempel en av disse implementasjonene:</p>
<ul>
<li><a href="https://github.com/npryce/maybe-java">https://github.com/npryce/maybe-java</a></li>
<li><a href="http://blog.tmorris.net/maybe-in-java/">http://blog.tmorris.net/maybe-in-java/</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/p1-ZYiroh0M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/java-scala-null/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/java-scala-null/</feedburner:origLink></item>
		<item>
		<title>5 myter om innovasjon</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/mzuWCK2fjyk/</link>
		<comments>http://open.bekk.no/5-myter-om-innovasjon/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 08:46:55 +0000</pubDate>
		<dc:creator>Per Gunnar Hagevik</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[BEKK Management Consulting]]></category>
		<category><![CDATA[Strategi og Forretningsutvikling]]></category>
		<category><![CDATA[Forretningsmodell]]></category>
		<category><![CDATA[Forretningsmodellinnovasjon]]></category>
		<category><![CDATA[forretningsutvikling]]></category>
		<category><![CDATA[innovasjon]]></category>
		<category><![CDATA[Innovasjonsledelse]]></category>
		<category><![CDATA[ledelse]]></category>
		<category><![CDATA[myter]]></category>
		<category><![CDATA[strategi]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7650</guid>
		<description><![CDATA[Gjennom vårt arbeid med store og mellomstore virksomheter har vi erfart at det er mange myter knyttet til innovasjonsbegrepet. Ofte ser vi at disse mytene er årsaken til at innovasjonsarbeidet i mange bedrifter ikke gir synlige resultater. Men først, hva legger vi i begrepet innovasjon? Hva er innovasjon? Vi i BEKK har en enkel formel [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Gjennom vårt arbeid med store og mellomstore virksomheter har vi erfart at det er mange myter knyttet til innovasjonsbegrepet. Ofte ser vi at disse mytene er årsaken til at innovasjonsarbeidet i mange bedrifter ikke gir synlige resultater. Men først, hva legger vi i begrepet innovasjon?</strong></p>
<h2>Hva er innovasjon?</h2>
<p>Vi i BEKK har en enkel formel for innovasjon. Vi kaller det <strong>”Innovasjon = Kreativitet x Gjennomføringsevne”</strong>. Med kreativitet mener vi evnen til å identifisere og beskrive de riktige idéene. Idéer som kan komme fra interne og eksterne gjennom fysiske og digitale arenaer. I gjennomføringsevne ligger evnen til å velge, videreutvikle og realisere de beste ideene. Gjennomføring innebærer blant annet å etablere prosesser, sammensetning av tverrfaglige team, utarbeidelse av implementeringsplan og definering av evalueringskriterier.</p>
<p>Det finnes utallige andre definisjoner av innovasjon der ute, noe som i sum er med på å skape flere myter om innovasjon.</p>
<h2>Myter om innovasjon</h2>
<h5><em>Myte 1: Innovasjon handler bare om å generere idéer.</em></h5>
<p><strong><em></em></strong><strong>Vår erfaring:</strong> Som vår definisjon over viser må idéer bli realisert for at de skal kunne kalles innovasjoner. Innovasjon handler derfor i like stor grad om å velge ut og realisere idéene som å generere de. I tillegg er det ikke tilstrekkelig å generere idéer – idéene må være riktige i forhold til virksomhetens fokus og strategi for å gi reell verdi. Vår erfaring er at en omforent innovasjonsstrategi på tvers av organisasjonen er med på å skape en felles forståelse for hvorfor, på hvilke områder og hvordan virksomheten skal jobbe med innovasjon.</p>
<h5><em>Myte 2: Vellykket innovasjonsarbeid dreier seg bare om å samle organisasjonens idéer.</em></h5>
<p><strong>Vår erfaring:</strong> Å la de ansatte komme med, og utforske, egne idéer er først å fremst viktig for å få tilgang til de gode og riktige idéer. Dette fordi de ansatte ser og forstår virksomhetens problemstillinger og kontekst . I tillegg bidrar denne involveringen til å skape engasjement og deltagelse fra de ansatte. Vi ser allikevel at i de tilfellene hvor det er et mål å oppnå større/mer radikale innovasjoner er det ofte hensiktsmessig å kombinere den medarbeiderdrevne innovasjonen med en mer fokusert FoU- organisasjon og -prosess.</p>
<h5><em>Myte 3: Innovasjon handler bare om å endre et helt marked gjennom radikale og grensesprengende produkter</em>.</h5>
<p><strong>Vår erfaring:</strong> Innovasjon kan handle om å gjøre noe helt nytt, men kan også handle om å gjøre noe man allerede gjør bedre for å øke lønnsomheten og/eller kvalitet uten å endre markedet. De fleste virksomheter fokuserer på prosess- og produktinnovasjon, men statistikk og vår erfaring tilsier at det er innovasjon av forretningsmodellen og kundeopplevelse som gir størst verdi. Forståelse for at ulike typer innovasjon krever ulike typer prosesser, verktøy og kompetanse er essensielt for å lykkes.</p>
<h5><em>Myte 4: Gjennomføring av innovasjonsprosjekter gjøres internt i det enkelte forretningsområde eller avdeling</em></h5>
<p><strong>Vår erfaring:</strong> Mange inkrementelle forbedringer kan gjøres av det enkelte forretningsområde eller avdeling, men for større prosjekter er det viktig med en tverrfaglig teamsammensetning. Et viktig moment ved gjennomføring av innovasjonsprosjekter er å først identifisere hvilken kompetanse og ferdigheter som trengs for å kunne realisere idéen. Deretter settes et team sammen med personer som innehar disse egenskapene på tvers av organisasjonen. I mange tilfeller er det også hensiktsmessig å inkludere ekstern kompetanse og perspektiver. Dette dedikerte teamet må underveis i gjennomføringen samarbeide tett med aktuelle forretningsområder og ressurser, som vil få ansvaret for gevinstrealiseringen.</p>
<h5><em>Myte 5: Innovasjon innebærer stor risiko og mye ressurser.</em></h5>
<p><strong>Vår erfaring:</strong> Mange virksomheter bruker i dag betydelige ressurser på innovasjonsinitiativ uten å se de store resultatene. En utfordring for mange av disse virksomhetene er at prosjekter ikke fanges opp og stoppes tidlig, om det viser seg at satsningen er feilslått. Effektivt innovasjonsarbeid innebærer å jobbe strukturert og iterativt. Risikoen knyttet til innovasjon er liten om man ved å bruke litt – lærer mye i hvert enkelt prosjekt. Det å gjøre hyppige evaluering underveis basert på trender og utvikling <em>(fremtid)</em> og ikke bare data <em>(fortid)</em>, vil det være mulig å omdisponere midlene til innovasjonsinitiativ på tvers av prosjekter. Det må samtidig påpekes at det å bruke litt – lære mye ikke betyr det samme som å gjøre noe halvhjertet, og balansen mellom de to er krevende å finne.</p>
<p>&nbsp;</p>
<p>Dette var et utvalg av de mytene vi møter når vi jobber med våre kunder. Kanskje kjenner du deg igjen i disse, eller kanskje har du andre myter som kan diskuteres?</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/mzuWCK2fjyk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/5-myter-om-innovasjon/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://open.bekk.no/5-myter-om-innovasjon/</feedburner:origLink></item>
		<item>
		<title>Psykologiske fellesnevnere i emosjonell design – hvordan? (3:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/ooqypcpCLqA/</link>
		<comments>http://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 08:40:41 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7514</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. I innlegg nummer 3 begynner vi å se på hvordan vi kan få til emosjonell design gjennom følelser - våre psykologiske fellesnevnere!]]></description>
			<content:encoded><![CDATA[<h5><em> I de to tidligere innleggene har jeg gitt en intro til emosjonell design gjennom boken “Design for emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a>, ved å snakke om <span style="color: #ff0000"><a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/">“Hva?”</a></span> og <span style="color: #ff0000"><a href="https://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/trackback/">“Hvorfor?”</a></span>. Denne gangen skal vi se på hva Aarron sier om “Hvordan?”.</em></h5>
<p>Hvordan å få til emosjonell design er selvsagt et godt spørsmål, og her har Aarron dessverre ikke noen ut-av-boksen fasit. (Som alle andre ting i designverden er anvendelsen veldig avhengig av kontekst, brukere osv.). Det som imidlertid er klart, er at det finnes en del triks man kan benytte seg av, og disse deles i to kategorier. Den første kategorien, som vi skal se på i dette innlegget, kan vi kalle psykologiske fellesnevnere. Den andre, som vi skal ta for oss i <span style="color: #000000">mitt neste innlegg</span>, er personlighet.</p>
<h2>Vi er like på bunnen!</h2>
<p>Heldigvis er det slik at vi mennesker har en god del psykologiske fellesnevnerer, og følelsene våre er én av disse. Man kan godt si at følelser er morsmålet til alle mennesker helt fra vi er født, og det finnes noen ting man kan jobbe med som vil utløse positive følelser hos mennesker nesten samme hva!</p>
<h4>Det gyldne snitt</h4>
<p>Alle mennesker har det til felles at vi prøver å se oss selv i alt rundt oss, for å kunne knytte oss til det. Et kjent eksempel her er “the babyface-bias” som gjør at mennesker får positive følelser mot alt som ligner på ansikt, og spesielt baby-ansikt. Dette betyr ikke at man skal dekke siden sin med happy baby-fjes, dette stikker nemlig dypere, og her kan man være mer sofistikert enn å kjøre på med babyer.</p>
<p>Du har sikkert hørt om Det gyldne snitt, men visste du at Det gyldne snitt faktisk finnes i våre ansikter? Dette fører til at når vi ser et maleri, en bygning eller en webside vi liker på grunn av balanse basert på det gyldne snitt, er det egentlig speilbildet av oss selv i det vi observerer som trigger oss! Dette betyr at design som inneholder det gyldne snitt har en stor sjanse for å vekke underbevisste, positive følelser. Twitter brukte dette aktivt i redesignet av sitt grensenitt.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/twitter-golden-ratio.png"><img class="alignleft size-medium wp-image-7532" src="http://open.bekk.no/wp-content/uploads/2011/12/twitter-golden-ratio-300x190.png" alt="" width="300" height="190" /></a></p>
<h4>Kontrast</h4>
<p>Videre er det slik at vi underbevisst alltid leter etter mønster, rett og slett for å automatisk kunne plukke ut når det skjer noe uregelmessig rundt oss (= kontrast), slik at oppmerksomheten kan kobles inn og vi kan reagere. Som designere finnes det to typer kontrast vi kan benytte oss av; visuell kontrast og kognitiv kontrast.</p>
<p>Visuell kontrast er det ganske opplagt at må brukes i layout, farger og typografi (selvsagt med forsiktighet, hjerna kan få overload av kontrast!), og gjennom dette kan vi lede brukeren til det som er viktig på siden. Tumblr bruker dette aktivt i sitt sign-up-form.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/tumblr.png"><img class="alignleft size-medium wp-image-7537" src="http://open.bekk.no/wp-content/uploads/2011/12/tumblr-300x231.png" alt="" width="300" height="231" /></a></p>
<p>Når det gjelder kognitiv kontrast, dreier det seg om at når noe skiller seg ut, blir dette oppfattet med en identitet heller enn som en del av massen. Dersom denne identiteten er positiv, har vi begynnelsen på et sterkt posisjonert brand. Designeren Richard Mestre bruker dette på sin portfolioside duplos.org &#8211; dette ligner ikke på så mange andre portfoliosider!</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/duplos.org-red.png"><img class="size-full wp-image-7538 alignleft" src="http://open.bekk.no/wp-content/uploads/2011/12/duplos.org-red.png" alt="" width="532" height="577" /></a></p>
<p>&nbsp;</p>
<h4>Aesthetics usability effect</h4>
<p>I tillegg til det gyldne snitt og kontrast, har vi “the aesthetics usability effect”. Noen kan av og til komme i skade for å si at utseendet bare er “glasur på kaka”, men da kjenner de ikke sannheten. Det er nemlig slik at når noe ser fint ut, får vi positive følelser knyttet til det, positive følelser gjør oss mer kreative, og når vi er mer kreative løser vi problemer enklere (og da oppfatter vi systemet som lettere å bruke!). I tillegg er det vel ikke fritt for at vi dømmer etter utseende – ville du ansatt han med en glimrende cv dersom han møtte opp på intervju i en skitten pysjamas?</p>
<p>Videre er det faktisk slik at når “panseret” tydelig har fått ettertanke og er gjennomarbeidet, da får man følelsen av at det som ligger bak sannsynligvis også er samvittighetsfullt og skikkelig gjort, og det er mindre grunn til å tro at du vil møte noe som ikke henger på greip senere i prosessen.</p>
<h4>Variable rewards</h4>
<p>Til sist kan vi nevne “variable rewards”. Dette er en avhengighetsskapende tendens alle mennesker har, og det er trangen til å fortsette med en aktivitet i håp om at rundt neste sving venter den store gevinsten/ noe veldig morsomt/ noe spesielt og sjelden osv. Det er dette som gjør at vi kan utvikle spillegalskap, og selv om ikke det er noe mål, kan man som designer jobbe med de samme mekanismene for å få folk til å føle spenning og gi dem lyst til å bruke tid på systemet. MailChimp er et eksempel på et system som gjennom morsomme og varierende beskjeder og kommentarer til brukeren gir folk lyst til å fortsette gjennom sidene for å se hva som blir sagt rundt neste sving.</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/mailchimp.png"><img class="aligncenter size-full wp-image-7543" src="http://open.bekk.no/wp-content/uploads/2011/12/mailchimp.png" alt="" width="463" height="412" /></a></p>
<p><em> Det var altså noen triks man kan bygge på som vil vekke følelser og oppførsel styrt av følelser hos så og si alle mennesker. Oppå dette minste felles multiplum av følelser som gjør oss til mennesker &#8211; der har vi alle en personlighet. Dette er en annen emosjonell komponent vi kan jobbe med, og denne skal vi ta for oss i <span style="color: #000000"><a href="http://open.bekk.no/personlighet-i-emosjonell-design-hvordan-46/trackback/">mitt neste innlegg</a></span>!</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/ooqypcpCLqA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/</feedburner:origLink></item>
		<item>
		<title>Responsive design med Enonic CMS</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/NGSQI1X7Ws4/</link>
		<comments>http://open.bekk.no/responsive-design-med-enonic-cms/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 07:00:26 +0000</pubDate>
		<dc:creator>Per Allan Dahl Johansson</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[Grensesnittutvikling]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[Enonic]]></category>
		<category><![CDATA[Responsive]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7617</guid>
		<description><![CDATA[Det er mange måter å lage responsive design på og da er det viktig å ta en nøye titt på verktøykassa til den tekniske plattformen som skal ligge i bunnen av løsningen. Enonic CMS følger med i timen og det er flere muligheter i malverket til CMS&#8217;et som kan være greit å titte litt nærmere [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Det er mange måter å lage responsive design på og da er det viktig å ta en nøye titt på verktøykassa til den tekniske plattformen som skal ligge i bunnen av løsningen. Enonic CMS følger med i timen og det er flere muligheter i malverket til CMS&#8217;et som kan være greit å titte litt nærmere på.</strong></p>
<p>1. april 2011 lanserte <a href="http://www.enonic.com/">Enonic</a> sin CMS som open source i tillegg til sin standard Enterprise utgave. Enonic CE 4.6 (Community Edition) er det offisielle navnet. De har opprettet en egen sone på <a title="Enonic's profile on GitHub" href="https://github.com/enonic" target="_blank">GitHub</a> der all koden ligger og man kan samtidig følge utviklingen av versjon 5.0 som er under utvikling. Det mest spennende som er å finne på GitHub er <a title="CMS Packages" href="https://github.com/enonic/cms-packages" target="_blank">pakkemalene</a>. Her kan man plukke funksjonalitet som er gjennomtestet og som funker veldig bra som et utgangspunkt, og det vil også funke 100 % slik de allerede er på et mindre nettsted. Man trenger da kun å endre på designelementer og CSS&#8217;en.</p>
<p>Når du har lastet ned Enonic CE fra GitHub og du har installert den lokalt for testing står det veldig greit i dokumentasjonen om hvordan du kommer i gang.</p>
<h2>Walkthrough</h2>
<ul>
<li>Connect to WebDAV and upload the resources.</li>
<li>Edit your site and set the Internal Resources to &#8216;/config/*&#8217; where * contains a valid config.xml file</li>
<li>Set the Public Resources to &#8216;/_public/themes/&#8217;</li>
<li>Set Device Classification Script to &#8216;/libraries/resolvers/device-classification.xsl&#8217;</li>
</ul>
<p>Start developing!</p>
<p>Etter du har logget deg inn i adminkonsollet kan du laste ned og konfigurere en del innholdstyper for å teste CMS&#8217;et. Eksempler på innholdstyper, som passer med pakkemalene du har lastet opp via WebDAV, finner du <a title="Innholdstyper til Enonic CMS" href="https://github.com/enonic/cms-packages/tree/master/contenttypes" target="_blank">her</a>. Disse xml-filene skal ikke lastes opp i WebDAV men du må gjøre litt god gammeldags cut&#8217;n'paste inn i konsollet. Når du har dette på plass kan du opprette mapper/kategorier i <strong>Innholdsarkivet</strong> og komme igang med litt innholdsproduksjon. Å produsere innhold er alltid tidkrevende og kan du i prosjektsammenheng definere innholdet på et så tidlig tidspunkt som mulig og før siten er ferdig kodet opp kan innholdsprodusentene få startet arbeidet sitt så tidlig som mulig.</p>
<p>Sett at du har en del testinnhold klart og skal begynne å implementere maler (xslt). Hvor skal man begynne? På hvilket nivå skal man tenke responsivt? Er det behov for responsivt design? Det er jo ikke helt sikkert at det er det. Hvis det er et eksisterende nettsted som skal lages på nytt kan det være lurt å ta en titt på besøksstatistikken og spesielt da forholdet mellom besøkende med og uten mobiltelefon eller tablet. Når man har en god oversikt over hvilke nettlesere og enheter som besøker siten må man se på målgrupper og strategi. Men det er utenfor scope av denne artikkelen så nå er det på tide å hoppe inn i malverket.</p>
<p>I Enonic CMS ligger det støtte for en device-detektor. Den hekter du på nettstedet ditt i adminkonsollet om du vil bruke denne som utgangspunkt. Det er lurt å ta denne i bruk uavhengig om du skal ha responsivt design eller ikke. Det er her informasjonen til hvilke breddeverdier de forskjellige regionene på sidene dine innehar. Dette brukes igjen til dynamisk skalering av bilder.</p>
<p>I pakkene som du allerede har lastet opp kan du starte med å titte på <em>theme.xml</em>. Denne xml-fila finner du på roten av siten din. Du finner den i dav&#8217;en her omtrent:</p>
<p>dav: /themes/&lt;navn-på-demosite&gt;/<em>theme.xml</em></p>
<p>Når man jobber med denne fila er det greit å ha oversikt over designet som skal implementeres. Man trenger å vite maksbredder på bilder/grafikk i de forskjellige regionene som siden kan deles opp i. Vi tar en liten titt på xml&#8217;en</p>
<pre>&lt;theme&gt;
    &lt;region-prefix/&gt;
    &lt;accessibility&gt;
        ...
    &lt;/accessibility&gt;
    &lt;device-classes&gt;
        &lt;device-class name="pc,unknown,mobile"&gt;
            &lt;layout name="default"&gt;

                &lt;area width="950"&gt;
                    &lt;region name="north"&gt;
                        &lt;width&gt;950&lt;/width&gt;
                        &lt;margin&gt;
                            &lt;bottom&gt;10&lt;/bottom&gt;
                        &lt;/margin&gt;
                    &lt;/region&gt;
                &lt;/area&gt;
                &lt;area width="950"&gt;
                    &lt;region name="center" role="main" element="section" class="wide"&gt;
                        &lt;padding&gt;
                            &lt;right&gt;30&lt;/right&gt;
                            &lt;left&gt;30&lt;/left&gt;
                            &lt;top&gt;30&lt;/top&gt;
                            &lt;bottom&gt;30&lt;/bottom&gt;
                        &lt;/padding&gt;
                        &lt;scalable&gt;true&lt;/scalable&gt;
                        &lt;system&gt;true&lt;/system&gt;
                    &lt;/region&gt;
                    &lt;region name="single-sidebar" element="aside" role="complementary"&gt;
                        &lt;width&gt;180&lt;/width&gt;
                        &lt;margin&gt;
                            &lt;right&gt;10&lt;/right&gt;
                        &lt;/margin&gt;
                    &lt;/region&gt;
                    &lt;region name="east"&gt;
                        &lt;width&gt;180&lt;/width&gt;
                        &lt;margin&gt;
                            &lt;left&gt;10&lt;/left&gt;
                        &lt;/margin&gt;
                    &lt;/region&gt;
                &lt;/area&gt;
                &lt;area width="950"&gt;
                    &lt;region name="south"&gt;
                        &lt;width&gt;950&lt;/width&gt;
                    &lt;/region&gt;
                &lt;/area&gt;
            &lt;/layout&gt;
            &lt;image&gt;
                ... bilder
            &lt;/image&gt;
            &lt;styles&gt;
                ... css-filer
            &lt;/styles&gt;
            &lt;scripts&gt;
                ... js-filer
            &lt;/scripts&gt;
        &lt;/device-class&gt;
        &lt;device-class name="pc,unknown,mobile"&gt;
            ...... ipad spesifikk kode
        &lt;/device-class&gt;
    &lt;/device-classes&gt;
&lt;/theme&gt;</pre>
<p>Strukturen er oversiktlig nok når man er vant til malverket til Enonic men det er regionene her som er interessante.</p>
<pre>&lt;region name="single-sidebar" element="aside" role="complementary"&gt;
&lt;region name="center" role="main" element="section"&gt;</pre>
<p>Det er støtte for html5-elementer i malverket og man kan definere det enkelt ved å bruke dette oppsettet her. Dette er da tenkt som globale elementer i html-kilden. Strukturen settes opp her og støttes videre med global css slik at rammeverket sitter dønn selv uten innhold på siden. Det er fint å kunne teste siten så tidlig som mulig.</p>
<p>Disse navnene på regionene, hhv. <em>single-sidebar</em> og <em>center</em>, blir nå hardkodete navn som må gjenspeiles i sidemalen som til slutt skriver ut html-koden på sidenivå. Denne fila heter <em>page.xsl</em> og den finner du på samme nivå som <em>theme.xml</em>. Når du senere skal lage flere siter er det fint å klone disse filene, opprette ny mappe under /themes/, dumpe filene her, opprette nytt nettsted i Enonic og deretter koble de nye malene på nettstedet og sidemalen og du er i gang med å lage site nr 2. Gjenbruk er gull.</p>
<p>Hvis vi tar en titt på page.xsl ser man kjapt hvor regionene defineres</p>
<pre>&lt;!-- regions --&gt;
  &lt;xsl:param name="north"&gt;
    &lt;type&gt;region&lt;/type&gt;
  &lt;/xsl:param&gt;
  &lt;xsl:param name="single-sidebar"&gt;
    &lt;type&gt;region&lt;/type&gt;
  &lt;/xsl:param&gt;
  &lt;xsl:param name="center"&gt;
    &lt;type&gt;region&lt;/type&gt;
  &lt;/xsl:param&gt;
  &lt;xsl:param name="east"&gt;
    &lt;type&gt;region&lt;/type&gt;
  &lt;/xsl:param&gt;
  &lt;xsl:param name="south"&gt;
    &lt;type&gt;region&lt;/type&gt;
  &lt;/xsl:param&gt;</pre>
<p>Disse navnene må være like som i theme.xml. Når det er på plass kan man starte utviklingen. I theme.xml har jeg satt opp 960px som bredde for standardoppsettet mitt. Hadde jeg konfigurert nettstedet også for tablet og smartphone ville jeg lagt på to device-classes og definert breddene som f.eks. 768px og 320px eller eventuelt ytterpunktene med høyest oppløsning i landscape-modus. Dette vil da være størrelsen som bilder som skrives ut i de forskjellige regionene vil ha. Alt skjer via dynamiske funksjoner som man kan laste opp fra pakkene og bruke fritt i malene. I en artikkelmal kan man tenke seg at man kaller på et bilde slik:</p>
<pre>&lt;xsl:call-template name="image"&gt;
	&lt;xsl:with-param name="size" select="'wide'"/&gt;
	&lt;xsl:with-param name="image-path" select="image/@key"/&gt;
	&lt;xsl:with-param name="class" select="'list-image'"/&gt;
&lt;/xsl:call-template&gt;</pre>
<p>Her sier jeg til bildefunksjonen at den skal skrive ut bildet med full bredde i widescreen-format og samtidig legge på en klasse med navn &#8220;list-image&#8221;. Hvis man bruker standardoppsettet uten noen som helst form for tweaking blir dette en fast størrelse på bildet og ikke så skalerbart. Nå gjelder det å ta en titt på include-fila som skriver ut bilder. Den heter <em>image.xsl</em> og den finner du her: /libraries/utilities/<em>image.xsl</em></p>
<p>Se etter templaten som heter &#8220;<strong>image.display-image</strong>&#8220;. Den er stor og kompleks og du trenger ikke endre så mye her, bare kommentere ut bredden og høyden til bildet som til slutt skrives ut. Se etter:</p>
<pre>&lt;xsl:if test="$width"&gt;
	&lt;xsl:attribute name="width"&gt;
		&lt;xsl:value-of select="$width"/&gt;
	&lt;/xsl:attribute&gt;
&lt;/xsl:if&gt;
&lt;xsl:if test="$height"&gt;
	&lt;xsl:attribute name="height"&gt;
		&lt;xsl:value-of select="$height"/&gt;
	&lt;/xsl:attribute&gt;
&lt;/xsl:if&gt;</pre>
<p>Når dette er kommentert ut er det bare å styre bredden til bildene enkelt via css slik:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;">img <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">max-width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">auto</span> !important
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Ganske enkelt egentlig. Nå er det opp til deg og dine CSS-Ninja-egenskaper for å gjøre resten, men husk, vær smart og bruk device-detektoren i malene og scope hva slags enhet du jobber mot. Det vil optimalisere ytelsen og farten på siten. Du kan også justere innholdet og tilpasse siten på en mye enklere måte. Du kan gjøre dette helt ute i rammeverket og inne i portletene. Lag sjekker på device og tilpass bildet ditt. Ikke noe vits i skrive ut et 960px bilde for så å skalere det ned til 320px på en iPhone. Da er det bedre å bruke dette opplegget og skrive ut et bra skalert bilde fra serveren som passer til den devicen du har i målgruppen din. Malverket til Enonic baserer seg på XSLT og er du god på XSLT, XHTML og CSS er det bare moro herfra og frem til siten skal lanseres.</p>
<p>Lykke til.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/NGSQI1X7Ws4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/responsive-design-med-enonic-cms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/responsive-design-med-enonic-cms/</feedburner:origLink></item>
		<item>
		<title>Hvorfor bry seg om emosjonell design? (2:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/1gG4JOOR--s/</link>
		<comments>http://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 13:23:08 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7505</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. Innlegg nummer 2 handler om hvorfor emosjonell design er noe å ta hensyn til!]]></description>
			<content:encoded><![CDATA[<h5><em>“Designing for Emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a> er den lilla stripen i den herlige regnbuen med små, nyttige, lettleste bøker fra <a href="http://www.abookapart.com/">A Book Apart</a>. I en aldri så liten føljetong på seks deler kan du få en god oppsummering av boken og noen refleksjoner rundt den. I <span style="color: #000000"><a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/">mitt forrige innlegg</a></span> ga jeg en intro, og i dette innlegget skal jeg gå videre fra “Hva?” til “Hvorfor?”.</em></h5>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/abookapart2-red.png"><img class="aligncenter size-full wp-image-7511" src="http://open.bekk.no/wp-content/uploads/2011/12/abookapart2-red.png" alt="" width="760" height="300" /></a></p>
<p>Så, bortsett fra ønsket om å være den o store kokken som har laget en nydelig, ikke bare spiselig mat, eller den o heldige kunden som får spise dette (ref. pyramiden i<a href="https://open.bekk.no/en-intro-til-emosjonell-design/trackback/"> mitt forrige innlegg</a>) – hvorfor skal vi bry oss om emosjonell design? Er ikke dette med emosjonell design bare litt glasur og moro på toppen for designere som vil ha det gøy eller brukere som vil rote bort tiden på noe annet enn jobb? Nei, slik er det definitivt ikke &#8211; det går mye dypere enn som så.</p>
<blockquote><p>&#8220;Emotional design is not about nice-to-have warm fuzzy experiences, it&#8217;s central to daily life and the decision-making process for consumers. The more effectively you can apply emotional design in your site, the better conversion rates and sales will be.&#8221;</p></blockquote>
<p>Det har seg nemlig slik at opplevelser vi knytter følelser til (“emotional engagement”) faktisk lager dype inntrykk i langtidsminnene våre. Når vi opplever noe bra, settes en mental post-it i hjernen vår, som gjør det mulig for oss å fremkalle minnet av den gode opplevelsen. Når vi gjør dette får vi ikke bare lyst på mer av samme gode opplevelse, vi blir også mer tilbøyelige til å tilgi når ting går galt, og til og med til å snakke varmt om opplevelsen til andre!</p>
<p>(Hvorfor er det slik, spør du? Vel, dersom vi ikke satt disse mentale post-itene på ting som fremkalte betydelige følelser, ville vi ikke kunne gledet og over gode minner, og heller ikke kunnet lært av ubehagelige opplevelser. Vi ville vært dømt til å prøve og feile oss uendelig gjennom livet -uff!)</p>
<p>Som designere kan vi ha god nytte av dette – her har vi mulighet til å posisjonere både et brand og et system ganske hardt hos brukeren gjennom å trigge de rett følelsene. Når kundene vil ha mer blir de trofaste brukere som bruker mer tid og penger hos oss, og når de skryter av oss til bekjente blir de en ambassadør vi måtte betalt ganske mange marketing-kroner for å matche! Med andre ord – emosjonell design kan få uttelling rett på bunnlinja!</p>
<p><em>Da har vi noen gode argumenter på plass for “Hvorfor?”, og i <span style="color: #000000"><a href="https://open.bekk.no/psykologiske-fellesnevnere-i-emosjonell-design-hvordan-36/trackback/">mitt neste innlegg</a></span> skal jeg gå inn på “Hvordan?”. Følg med!</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/1gG4JOOR--s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/</feedburner:origLink></item>
		<item>
		<title>En intro til emosjonell design (1:6)</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/bOoNNKbY3QA/</link>
		<comments>http://open.bekk.no/en-intro-til-emosjonell-design/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 12:18:02 +0000</pubDate>
		<dc:creator>Nina Volstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[psykologi og design]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7488</guid>
		<description><![CDATA[Krysningen design og psykologi er i vinden som aldri før, og gjennom seks innlegg skriver Nina om kunnskap og refleksjoner fra boken “Designing for Emotion” av Aarron Walter. Innlegg nummer 1 er en intro til emosjonell design, og gir en fin smakebit av temaet!]]></description>
			<content:encoded><![CDATA[<h5><em>Den siste tiden har det blitt økende fokus på krysningen design og psykologi. Det finnes etterhvert en hel del gode og interessante bøker om temaet der ute, og jeg har i et <a href="https://open.bekk.no/psykologi-for-designere/">tidligere blogginnlegg</a> skrevet om <a href="http://www.whatmakesthemclick.net/">Susan Weinschenks</a> bøker. Denne gangen har jeg kost meg med “Designing for Emotion” av <a href="http://aarronwalter.com/">Aarron Walter</a> &#8211; den lilla stripen i den herlige regnbuen med små, nyttige, lettleste bøker fra <a href="http://www.abookapart.com/">A Book Apart</a>. Jeg kommer til å dele fra denne boka og mine tanker om den i seks innlegg over de neste ukene – følg med!</em></h5>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/a-book-apart-redigert.png"><img class="aligncenter size-full wp-image-7490" src="http://open.bekk.no/wp-content/uploads/2011/12/a-book-apart-redigert.png" alt="" width="760" height="338" /></a></p>
<p>Boka er en kjempefin intro til design og psykologi, og dersom du er spesifikt interessert i emosjonell design, vil jeg absolutt anbefale at du begynner hos Aarron – boka er ypperlig for dem som lurer på, eller trenger skyts til, hvorfor emosjonell design er et aktuelt tema!</p>
<p>Dersom du vil ha en enda kortere intro enn boka eller bloggpostene, eller kanskje du trenger noen andre eksempler, da kan du lese <a href="http://thinkvitamin.com/design/emotional-interface-design-the-gateway-to-passionate-users/">blogginnlegget</a> av Aarron på ThinkVitamin.</p>
<h3>Hva er emosjonell design?</h3>
<p>Så, hva er emosjonell design? Her har Aarron en figur som er veldig konkret og som lett kan knyttes til en velkjent design-hverdag, og han har også noen gode forklaringer rundt emosjonell design. (Figuren har forøvrig vært nevnt før i forbindelse med <a href="https://open.bekk.no/sa-vidt-spiselig-eller-et-herremaltid/">Aral Balkans foredrag</a> på konferansen The Big M).</p>
<p>For å begynne med figuren; Denne sammenligner interface design med Maslows velkjente behovspyramide. (Navnet interface design er ikke så viktig her, man kunne likegodt sagt interaction design eller noe annet; i denne sammenheng er det ikke er så viktig akkurat hvor bredt eller smalt man ser på dette). Prinsippet i en slik pyramide er at behovene i en lavere del av pyramiden må være dekket før man kan klatre seg oppover i lagene, og en høyere del av pyramiden kan aldri komme på bekostning av en lavere!</p>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/12/interface-maslow1.png"><img class="alignleft size-medium wp-image-7494" src="http://open.bekk.no/wp-content/uploads/2011/12/interface-maslow1-300x225.png" alt="" width="300" height="225" /></a></p>
<p>De nederste lagene i interfacepyramiden er functional, realiable og usable. Disse sikter til at systemet har de funksjonene brukerne trenger, at systemet er til å stole på med tanke på f.eks oppetid og at det ikke mister data, og at systemet er brukervennlig. Å ha en solid base i pyramiden er selvsagt ekstremt viktig og her kan bl.a kognitiv psykologi hjelpe oss, men når vi skal begynne å klatre i pyramiden er det den emosjonelle delen av psykologien vi skal spille på lag med.</p>
<p>Aarron påpeker at hittil, i interface designets barndom, har vi for det meste hatt nok med å kave rundt i de nederste nivåene. Det har vært utfordrende nok å komme seg opp på usable-nivået, der brukervennlighet ligger, men nå som vi er på vei inn i ungdommen holder faktisk ikke dette lenger; vi må vekk fra hygienefaktor-designet og opp i toppen av pyramiden! (Jeg er så enig, så enig!)</p>
<p>Det er nemlig på toppen vi finner de opplevelsene som er “pleasurable” – det er her man har ting som delight, joy og fun! Og det er jo dette vi alle drømmer om å både bruke og lage – skikkelig digge opplevelser som bare har D-E-T!</p>
<p>Så over til forklaringen. Emosjonell design er ikke en spesifikk type design, heller en angrepsvinkel for oppnå det vi alle drømmer om å bruke og lage. Emosjonell design kan ikke masseproduseres, og når man lykkes med emosjonell design, vil det føles som om det er en person man interagerer mer, ikke en maskin.</p>
<blockquote><p>&#8220;Emotional design uses psychology and craftsmanship to create experiences for users that make them feel like there&#8217;s a person, not a machine at the other end of the connection&#8221;</p></blockquote>
<p>For å utdype dette sier Aarron noe smart, han påpeker nemlig at Human Computer Interaction (HCI) er et forferdelig og utdatert ord. Det får det jo til å høres ut som om vi etterstreber at det skal merkes at det er en maskin med i bildet, heller å strebe etter at interaksjonene føles så &#8220;pleasurable&#8221; som en god samtale kan være. I det vi tar steget opp i de høyere delene av pyramiden burde vi samtidig slutte å snakke om at det er en computer med i samtalen!</p>
<p><em>Da har du fått en liten intro til temaet, og jeg håper du titter innom <span style="color: #000000"><a href="https://open.bekk.no/hvorfor-bry-seg-om-emosjonell-design/trackback/">mitt neste innlegg</a></span> også! Dette vil komme første uka i januar, og vil gå mer i dybden på “Hvorfor bry seg om emosjonell design?”</em></p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/bOoNNKbY3QA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/en-intro-til-emosjonell-design/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://open.bekk.no/en-intro-til-emosjonell-design/</feedburner:origLink></item>
		<item>
		<title>Agile database schema management with Liquibase</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/5LhhhsBggLY/</link>
		<comments>http://open.bekk.no/agile-database-schema-management-with-liquibase-2/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 20:00:49 +0000</pubDate>
		<dc:creator>Kai Bjørnstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Fri Programvare]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[friprog]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[smidig]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7475</guid>
		<description><![CDATA[NoSQL is on the offensive these days and, among other tings, promises schema-less databases with structured data. Sounds great!&#8230; It&#8217;s just that most of us will be stuck with the good old relational databases and their schema&#8217;s for several years to come. So, how can we do agile SQL schema management a bit more painless? [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a href="http://en.wikipedia.org/wiki/Nosql" title="NoSQL" target="_blank">NoSQL</a> is on the offensive these days and, among other tings, promises schema-less databases with structured data. Sounds great!&#8230; It&#8217;s just that most of us will be stuck with the good old relational databases and their schema&#8217;s for several years to come. So, how can we do agile SQL schema management a bit more painless?</strong></p>
<p>More than once have I come across projects and software which have their database schema defined in a single SQL file. Ok, sometimes there are several, one for each database vendor. This, often big, master SQL file is updated by the developers for each release/revision/sprint and shipped with the software.</p>
<p>This approach often result in projects/software creating their ad-hock schema management system for rolling out new schema releases. Some use manual procedures, others use <em>Perl</em>, <em>Shell</em> og <em>Python</em> scripts, some use various procedural languages and yet others use specialized tools from the database vendor. In my previous company I ended up using a combination of <em>Pyhon</em> scripts, <em>PL/pgSQL</em> and home grown code generators to manage the schema.</p>
<p>After being fed up by having to maintain my own custom code for schema management, I started searching for an alternative. To my excitement a friend of mine came across <a title="Liquibase" href="http://www.liquibase.org" target="_blank">Liquibase</a>. And since then that&#8217;s what I&#8217;ve been using&#8230;.</p>
<p>Liquibase is a small Open Source tool implemented in Java that summarizes its purpose with a great question: <em>&#8220;You never develop code without version control, why do you develop your database without it?&#8221;</em> The Liquibase homepage has decent documentation and even some introduction videos for getting started.<br />
Note that Liquibase also easily be set up to integrate with <em>Ant</em>, <em>Maven</em>, <em>Spring</em> or even directly in a Java Servlet container for more automation than the basic command-line.</p>
<p>But, if you are like most programmers, you&#8217;re probaly not happy until you reach perfection and total enlightenment, so here are some other alternatives:</p>
<ul>
<li>If you are fed up with Java tools using XML for configuration or you just have a case of general XML-allergies,<br />
I suggest having a look at <a title="Migrate4J" href="http://migrate4j.sourceforge.net" target="_blank">Migrate4J</a></li>
<li>First released the 2010.04.20 <a href="http://code.google.com/p/flyway/" title="flyway" target="_blank">Flyway</a> isn&#8217;t that old, but worth checking out.</li>
</ul>
<p>I have not tried these on a real-life project yet so feedback will be much appreciated!</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/5LhhhsBggLY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/agile-database-schema-management-with-liquibase-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/agile-database-schema-management-with-liquibase-2/</feedburner:origLink></item>
		<item>
		<title>Java til Scala #3: Unngå “boiler plate” kode</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/apfHKQtIAMM/</link>
		<comments>http://open.bekk.no/java-til-scala-3-unnga-boiler-plate-kode/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 18:56:59 +0000</pubDate>
		<dc:creator>Kai Bjørnstad</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Fri Programvare]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[friprog]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7431</guid>
		<description><![CDATA[Når det snakkes om &#8220;boiler plate&#8221; kode trekkes Java fort frem som den store synderen. De fleste av oss er kjent med frustrasjonen som bygger seg opp når vi ser diverse API&#8217;er/bibliotek som krever en Java-Bean som argument. For vi vet alle hva dette betyr: En lang liste med bla. &#8220;getters and &#8220;setters&#8221;. Så, når [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Når det snakkes om &#8220;boiler plate&#8221; kode trekkes Java fort frem som den store synderen. De fleste av oss er kjent med frustrasjonen som bygger seg opp når vi ser diverse API&#8217;er/bibliotek som krever en <a href="http://en.wikipedia.org/wiki/JavaBean" title="Java-Bean" target="_blank">Java-Bean</a> som argument. For vi vet alle hva dette betyr: En lang liste med bla. &#8220;getters and &#8220;setters&#8221;.</p>
<p>Så, når min frustrasjon tidvis når nye høyder hender det jeg tar enda en kikk på <a href="http://www.scala-lang.org/" title="Scala" target="_blank">Scala</a>. Alt skal jo være enklere i Scala!<br />
Nå sitter det sikkert en og annen leser og er litt oppgitt, enda en bloggpost med &#8220;java bashing&#8221; tenker du kanskje? Vel, jeg skal være ærlig, det var det som var utgangspunktet, men da jeg begynte å gjøre litt &#8220;research&#8221; fant jeg ut at Java fortsatt kan henge med i svingene&#8230;.</strong></p>
<h5>Getters and Setters&#8221;</h5>
<p>Så, hva skal man med disse get&#8217;erne og set&#8217;erne i utgangspunktet? Vel, intensjonen med disse funksjonene er å oppnå såkalt &#8220;<a href="http://en.wikipedia.org/wiki/Encapsulation_%28object-oriented_programming%29" title="encapsulation" target="_blank">encapsulation</a>&#8221; slik at implementasjonen av klassen og dens felt er uavhengig av det eksterne grensesnittet. Dette er en veldig bra tanke i teorien, men i praksis er det ofte ingen forskjell på klassens interne felt og og det eksterne grensesnittet!<br />
Vi vil heller ikke aksessere feltet direkte (ingen &#8220;encapsulation&#8221;), men vi ønsker heller ikke intetsigende get&#8217;ere og set&#8217;ere i koden når vi ikke har behov dem. Samtidig vil vi ha mulighet til å lage/endre på klassens interne representasjon av et felt uten å forandre på klassens eksterne grensesnitt.</p>
<p>Java &#8220;løste&#8221; dette opprinnelig med Java-Bean &#8220;standarden&#8221; som vi alle kjenner, men her har Scala overgått Java:</p>
<h5>Scala og &#8220;accessor methods&#8221;</h5>
<p>I Scala genererer kompilatoren såkalte &#8220;accessor methods&#8221; for alle felt. Dette betyr at når man definerer følgende Scala klasse:<br />
<code><br />
/* MyScalaClass.scala */<br />
class MyScalaClass {<br />
  var stringField: String = _<br />
}<br />
</code> </p>
<p>Genereres følgende &#8220;accessor methods&#8221;:<br />
<code><br />
// Getter:<br />
stringField()</p>
<p>// Setter<br />
stringField_$eq(stringField : String)<br />
</code></p>
<p>Og hva så med muligheten til å endre på klassens interne representasjon samtidig som man beholder grensesnittet? Det gjøres enkelt ved å eksplisitt definere &#8220;accessor&#8221; metodene:<br />
<code><br />
/* MyScalaClass.scala */<br />
class MyScalaClass {<br />
  var modifiedStringField: String = _ </code><code><br />
  def stringField() = modifiedStringField</p>
<p>  def stringField_= (stringField: String) {<br />
    modifiedStringField = stringField<br />
  }<br />
}<br />
</code></p>
<p>Her er en enkel Junit test skrevet i Java som viser hvordan Scala &#8220;accessor metods&#8221; ser ut fra den siden:<br />
<code><br />
/* MyScalaClassTest.Java */<br />
@Test<br />
public void MyScalaClassTest() {<br />
     MyScalaClass myScalaClass = new MyScalaClass();<br />
     myScalaClass.stringField_$eq("foo");<br />
     assertEquals("foo", myScalaClass.stringField());<br />
}<br />
</code></p>
<p>Her er tilsvarende test med scalatest:<br />
<code><br />
/* MyScalaClassSuite.scala */<br />
test("Test accessors ") {<br />
    val mc = new MyScalaClass()<br />
    mc.stringField = "foo"<br />
    assert("foo" == mc.stringField)<br />
}<br />
</code></p>
<h5>&#8220;accessor method&#8221; != JavaBean Getter/Setter</h5>
<p>Alt er rosa og fint i Scala-land, men igjen bør vi løfte blikket og ta en titt på den virkelige verden. Hvis vi vil bruke scala er sannsynligheten høy for at vi må integrere enten med eksisterende Java kode/bibliotek (for eksempel Hibernate eller JAXB). Og denne Java koden forventer sannsynligvis JavaBean get&#8217;ere og set&#8217;ere ikke og &#8220;accessor methods&#8221; har lite for seg.<br />
Men igjen har Scala løsningen: <em>@scala.reflect.BeanProperty</em>. Denne annoteringen gjør akkurat det du forventer: genererer JavaBean get&#8217;ere og set&#8217;ere:<br />
<code><br />
/* MyScalaClass.scala */<br />
class MyScalaClass {<br />
    @scala.reflect.BeanProperty<br />
    var stringField: String = _<br />
}<br />
</code></p>
<p><code><br />
/* MyScalaClassTest.Java */<br />
@Test<br />
public void MyScalaClassTestWithBeanProperties() {<br />
    MyScalaClass2 myScalaClass = new MyScalaClass2();<br />
    myScalaClass.stringField_$eq("foo");<br />
    assertEquals("foo", myScalaClass.stringField());<br />
    myScalaClass.setStringField("bar");<br />
    assertEquals("bar", myScalaClass.getStringField());<br />
    assertEquals(myScalaClass.stringField(), myScalaClass.getStringField());<br />
}<br />
</code></p>
<h5>Java klamrer seg fast</h5>
<p>Jaja, fint for de som har muligheten til å kode i Scala tenker du kanskje&#8230;. Men vent, det finnes løsninger for Java også! Se bare på koden under:<br />
<code><br />
/* MyJavaClass.Java */<br />
@Setter<br />
@Getter<br />
public class MyJavaClassMinimal {<br />
    private String stringField;<br />
    private Integer integerField;<br />
    private Date dateField;<br />
}<br />
</code></p>
<p><code><br />
/* MyJavaClassTest.Java */<br />
@Test<br />
public void MyJavaClassTest() {<br />
    MyJavaClass myJavaClass = new MyJavaClass();<br />
    myJavaClass.setStringField("foo");<br />
    assertEquals("foo", myJavaClass.getStringField());<br />
}<br />
</code></p>
<p>Så hvor kom disse magiske <em>@Setter</em> og <em>@Getter</em> annoteringene fra? Ta en titt på <a href="http://http://projectlombok.org/" title="Project Lombok" target="_blank">Project Lombok</a>!<br />
Personlig barberte jeg vekk over 6000 linjer &#8220;boiler plate&#8221; Java kode fra nåværende prosjekt ved hjelp av &#8220;Lombok&#8221;, så dette er verd å bruke noen minutter på!</p>
<p>Men dette er jo ikke en del av Java språket tenker du kanskje. Og du har helt rett &#8220;Lombok&#8221; er et separat bibliotek, men det kan hende vi slipper dette i Java 8 <a href="http://old.nabble.com/abbreviating-getters-and-setters-proposal-for-java-8-td31661210.html" target="_blank">Abbreviating getters and setters proposal for Java 8</a>?</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/apfHKQtIAMM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/java-til-scala-3-unnga-boiler-plate-kode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/java-til-scala-3-unnga-boiler-plate-kode/</feedburner:origLink></item>
		<item>
		<title>Hvordan “booste” din personlige produktivitet?</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/bEi3IpExR_k/</link>
		<comments>http://open.bekk.no/hvordan-booste-din-personlige-produktivitet/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 20:38:57 +0000</pubDate>
		<dc:creator>Jørn Hunskaar</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Prosjektledelse]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[kanban]]></category>
		<category><![CDATA[personlig produktivitet]]></category>
		<category><![CDATA[pomodoro]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7395</guid>
		<description><![CDATA[Det å være “effektiv” handler om å få gjort mer arbeid innenfor den tiden du har til rådighet. Har du ikke tid til å lese hele bloggposten? Da tar vi produktivitetstipsene med én gang: Hold oversikt over antall oppgaver du har pågående Begrens antall samtidige oppgaver, fokuser på å fullførere eksisterende oppgaver fremfor å starte [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>Det å være “effektiv” handler om å få gjort mer arbeid innenfor den tiden du har til rådighet. Har du ikke tid til å lese hele bloggposten? Da tar vi produktivitetstipsene med én gang:</p>
<ol>
<li>Hold oversikt over <strong>antall oppgaver du har pågående</strong></li>
<li><strong>Begrens antall samtidige oppgaver</strong>, fokuser på å fullførere eksisterende oppgaver fremfor å starte opp nye</li>
<li><strong>Sett av tid til “isolerte” arbeidsstunder</strong> på 25 min for å rydde unna rutineoppgaver</li>
</ol>
<p>Disse rutinene fungerer som regel godt, men de fungerer ikke likt i alle sammenhenger. La meg forklare litt om tankene bak.</p>
<h3 dir="ltr">Typisk prosjekthverdag</h3>
<p>Jeg er prosjektleder og jobber med store og små systemutviklingsprosjekter. I løpet av en vanlig arbeidsdag bruker jeg mange timer på å arbeide <strong>i team</strong> og på å arbeide <strong>med team</strong>. I et godt team “dyttes” man til en viss grad fremover av hverandre, i en kjede av regelmessige og uregelmessige hendelser.</p>
<h3 dir="ltr">Når arbeidssituasjonen endres&#8230;</h3>
<p>For en stund siden startet jeg i et nytt prosjekt, men til forskjell fra “vanlige” systemutviklingsprosjekter er jeg inne i en tidligere fase. Vi etablerer prosjektet, vi arbeider med selve fundamentet. Vi ser på forretningsverdien og på hvordan det nye systemet vil fungere i organisasjonen og påvirke hvordan folk jobber. Vi spør: “Bør prosjektet i det hele tatt startes opp?”. Dette er en annerledes situasjon å være i, for ofte er beslutningene tatt og vurderingene gjort (eller faktisk ikke gjort) når vi begynner å bygge løsningen.</p>
<p>Arbeidet er spennende og utfordrende, men jeg jobber mye mer på egenhånd enn jeg gjør i min normale prosjekthverdag. Det krever selvdisiplin. Det er større fokus på at “jeg” skal levere enn at “vi” skal levere. Dette førte til at jeg ikke lenger følte meg like produktiv som jeg ønsker å være. Ingen faste prosjektdeltakere (utenom meg selv), men mange i organisasjonen involvert på deltid og på forespørsel. Her er det ingen kjede av hendelser som “dytter” prosjektet fremover.</p>
<p>Det er riktignok ganske vanlig at en konsulents arbeidshverdag forandres. Nye prosjekter startes opp, og prosjekter avsluttes. Vi starter å arbeide med nye kunder, og relasjoner må bygges på nytt.</p>
<p>Når arbeidssituasjonen endres kommer man fort ut av det som er normal arbeidsrytme. Da tar det gjerne litt tid før man får strukturert ting, finner tilbake til den gode følelsen og klarer å utnytte det produktive potensialet. Jeg har opplevd disse endringene et utall ganger og er blitt opptatt av å skaffe meg gode arbeidsvaner og lære meg teknikker som gjør at jeg raskt finner igjen balansen og blir produktiv.</p>
<h3 dir="ltr">Personlig Kanban kombinert med Pomodoro</h3>
<p>De siste månedene har jeg benyttet en <a href="http://www.personalkanban.com/pk/">personlig Kanban-tavle</a>, en <a href="http://kanbanery.com/">digital sådan</a>, der jeg holder styr på oppgavene mine og flytter disse mellom kolonnene <em>backlog</em>, <em>denne uken</em>, <em>pågående</em> og <em>utført</em>.</p>
<p>Hva er de forskjellige kolonnene?</p>
<ul>
<li><strong>Backlog</strong>: Oppgaver jeg skal gjennomføre eller følge opp.</li>
<li><strong>Denne uken</strong> (“This week”): Oppgaver jeg har plukket fra backlog som jeg skal gjennomføre inneværende uke. Som regel plukkes disse fra backloggen kun én gang i uken, dvs. at oppgaver som ligger i backloggen er oppgaver som trygt kan ligge til neste uke. Oppgaver som dukker opp fortløpende, og som må utføres relativt raskt, legges som regel direkte inn i denne kolonnen.</li>
<li><strong>Pågående</strong> (“Doing”): Oppgaver jeg arbeider med eller følger opp akkurat nå. Dukker det opp en ny oppgave jeg må starte på med en gang går den rett inn i denne kolonnen.</li>
<li><strong>Utført</strong> (“Done”): Fullførte oppgaver, tømmes ukentlig.</li>
</ul>
<div>
<p><a href="http://open.bekk.no/wp-content/uploads/2011/11/pk_overview_basic.png"><img class="size-full wp-image-7397" title="pk_overview_basic" src="http://open.bekk.no/wp-content/uploads/2011/11/pk_overview_basic.png" alt="" width="655" height="253" /></a></p>
<address>Eksempel på en enkel personlig Kanban-tavle </address>
<p>Ser du spesielt godt etter på skjermbildet, vil du se at det er en <a href="http://en.wikipedia.org/wiki/Work_in_process">WIP-begrensning</a> på 4 oppgaver i pågående-kolonnen. Dette betyr at jeg har satt en begrensning på antall samtidige oppgaver som kan ligge i denne kolonnen. Årsaken til denne begrensningen er at det øker fokus på å fullføre oppgaver, slik at jeg unngår problemer som <a href="http://prprat.no/2011/01/17/peak-attention/">peak attention</a>. Denne fremgangsmåten har fungert veldig godt lenge, men til tross for dette følte jeg meg ikke like effektiv som vanlig i denne nye arbeidssituasjonen.</p>
<p>I min kontinuerlige søken etter å bedre effektiviteten kom jeg over <a href="http://paulklipp.com/images/PersonalProductivity.pdf">denne artikkelen</a>. Her beskrives <strong>en kombinasjon av personlig Kanban og <a href="http://www.pomodorotechnique.com/">Pomodoro-teknikken</a></strong>- altså en potensielt god match for meg siden jeg allerede benytter personlig Kanban.</p>
<p>Kort fortalt er Pomodoro en teknikk der du definerer en oppgave som kan utføres i løpet av 25 minutter, stenger omverdenen ute og arbeider fokusert <span style="text-decoration: underline;">kun</span> med denne oppgaven inntil tiden er ute. Oppgaven skal da være fullført, deretter kan du ta 5 minutters pause (hente kaffe, svare på e-post, e.l.).</p>
<p>Hva som får <span style="text-decoration: underline;">deg</span> til å arbeide mest mulig effektivt, med færrest mulig avbrudd, avhenger nok både av situasjonen og personlige preferanser. Noen bør sette seg på et stillerom og fjerne tilgangen på alle fristelser (e-post, Twitter, eller kanskje internett generelt). For min del blir jeg sittende i det åpne kontorlandskapet, tar på meg headsettet og spiller musikk jeg kjenner godt fra før.</p>
<p>Konkret har Pomodoro-teknikken, kombinert med min personlige Kanban, ført til at jeg har opprettet en egen Pomodoro-kolonne på tavlen min. Denne ligger etter pågående-kolonnen og har en WIP-begrensning på én. <strong>Har jeg tid eller behov for en svært fokusert arbeidsstund flytter den utvalgte oppgaven over til Pomodoro-kolonnen.</strong> Merk at jeg da minimerer pågående-kolonnen, slik at fokus kun ligger på den ene oppgaven jeg skal fullføre. Oppgaven er av en slik størrelse at den kan gjennomføres på 25 minutter. Er den større splittes den opp i mindre deler før en av deloppgavene flyttes over i Pomodoro-kolonnen. Når den er ferdig flyttes oppgaven videre over til <em>utført</em>.</p>
<address><img class="size-full wp-image-7398  alignnone" title="pk_overview_pomodoro" src="http://open.bekk.no/wp-content/uploads/2011/11/pk_overview_pomodoro.png" alt="" width="671" height="249" /><br />
<em>Personlig Kanban-tavle med egen Pomodoro-kolonne. Pågående-kolonnen er minimert.</em></address>
<p>I tillegg til at dette visualiseres på min personlige Kanban-tavle, <strong>teller jeg antall Pomodoro-økter jeg får gjennomført hver arbeidsdag</strong>. Dette ligger lett synlig på arbeidsplassen min, slik at jeg stadig får en påminnelse om at én eller flere Pomodoro-økter kan hjelpe meg til å få ryddet unna enkelte oppgaver.</p>
<address><a href="http://open.bekk.no/wp-content/uploads/2011/11/pomodoro_count.jpg"><img class="size-full wp-image-7399  alignnone" title="pomodoro_count" src="http://open.bekk.no/wp-content/uploads/2011/11/pomodoro_count.jpg" alt="" width="288" height="384" /><br />
</a>Visualiseringen av antall Pomodoro-økter ligger lett synlig på arbeidsplassen.</address>
<p>Det er ikke noe mål i seg selv å gjennomføre flest mulig Pomodoro-økter, dette avhenger i stor grad av tid og sted, men visualiseringen er likevel viktig slik at jeg får en påminnelse om <span style="text-decoration: underline;">muligheten</span>:</p>
</div>
<h3 dir="ltr">Erfaringer?</h3>
<p>For meg fungerer Pomodoro-teknikken veldig bra sammen med personlig Kanban. Jeg har klart å øke fokus på å fullføre oppgavene mine ytterligere, og jeg opplever et skikkelig produktivitetsløft på visse typer oppgaver &#8211; spesielt rutinepregede oppgaver.</p>
<p>Det å estimere størrelsen på en oppgave er (som alltid) svært vanskelig, og jeg klarer ikke alltid å fullføre oppgavene innenfor avsatt tidintervall (25 min). I blant må det både to og tre Pomodoro-økter til før jeg blir ferdig med en oppgave, men jeg merker at jeg blir stadig flinkere i å splitte oppgavene opp i hensiktsmessig størrelse. Klarer jeg ikke å avslutte oppgaven i tide er ikke dette utelukkende negativt heller &#8211; dette motiverer meg enda mer til å ville fullføre oppgaven.</p>
<p>Det er generelt vanskelig å endre måten man arbeider på, men jeg tror en bevisstgjøring av måten man arbeider på alene kan hjelpe på effektiviteten. Dessuten øker nysgjerrigheten på å finne ut av hvordan man kan bli mer effektiv.</p>
<p>Teknikken jeg har beskrevet her fungerer godt for meg akkurat nå, men det er ikke sikkert du kan bruke denne teknikken på nøyaktig samme måte. <strong>Finn din egen stil og legg deg til en vane med å prøve ut nye teknikker.</strong></p>
<p><em>Hvilke grep tar du for å arbeide mer effektivt?</em></p>
</div>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/bEi3IpExR_k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/hvordan-booste-din-personlige-produktivitet/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://open.bekk.no/hvordan-booste-din-personlige-produktivitet/</feedburner:origLink></item>
		<item>
		<title>Java til Scala #2: Higher order functions</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/iV97_HKwL2E/</link>
		<comments>http://open.bekk.no/scala-higher-order-functions/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 07:11:50 +0000</pubDate>
		<dc:creator>Frode Nerbråten</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Teknologi]]></category>
		<category><![CDATA[funksjonell programmering]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7105</guid>
		<description><![CDATA[Man finner ofte eksempler på repeterende kode som gjør tilnærmet det samme, men med en liten variasjon. Det kan være enkelt å se mønsteret, men vanskelig å trekk det ut for gjenbruk. Det finnes mange måter å løse dette på i Java, men ofte ville det vært enklere med higher order functions. Vi skal se på hvordan slike problemer kan løses i Scala.]]></description>
			<content:encoded><![CDATA[<style type="text/css">
  code {
    font-family: monospace;
    font-size: 1.3em;
  }
  ul {
    font-size: 1.2em;
  }
</style>
<p><strong>Man finner ofte eksempler på repeterende kode som gjør tilnærmet det samme, men med litt variasjon. Det kan være enkelt å se mønsteret, men vanskelig å trekk det ut for gjenbruk. Det finnes mange måter å løse dette på i Java, men ofte ville det vært enklere med higher order functions. Vi skal se på hvordan slike problemer kan løses i Scala.</strong></p>
<p>Dette blogginnlegget viser kort hva higher order functions er og hvordan syntaksen for disse er i Scala. Deretter vises et praktisk eksempel på programmatisk transaksjonshåndtering i Spring med Scala og higher order functions.</p>
<h2>Høyere enn hva?</h2>
<p>Higher order functions, eller høyere ordens funksjoner, er funksjoner som tar inn én eller flere funksjoner som parametre eller returnerer en funksjon. Disse finner man i funksjonelle språk og andre språk som behandler funksjoner som &#8220;first class citizens&#8221; som betyr at funksjoner kan opprettes, tilordnes til variabler og sendes som parametre.<br />
Et vanlig bruksområde for higher order functions er å samle gjentagende kode på ett sted for gjenbruk. Scalas collection-API inneholder mange eksempler på bruk av higher order functions:</p>
<p><script src="https://gist.github.com/1331710.js?file=gistfile1.scala"></script></p>
<p>I dette eksemplet er <code>map</code> en higher order function. Den tar inn en funksjon som blir kalt for hvert element i listen og resultatene returneres som en ny liste. Traversering av listen er altså felleslogikken som er trukket ut i en gjenbrukbar funksjon. Den som bruker apiet trenger kun å konsentrere seg om hvordan hvert element skal transformeres.</p>
<h2>Din egen higher order function i Scala</h2>
<p>Et enkelt eksempel på en higher order function er følgende funksjon som skriver ut en tekststreng formatert av en annen funksjon:</p>
<p><script src="https://gist.github.com/1331750.js?file=eksempel2.scala"></script></p>
<p>Funksjonen print tar to argumenter: text som er av typen String og decorate som er av typen funksjon fra String til String. Altså en funksjon som tar en String som parameter og som returnerer en String. Selve implementasjonen kaller decorate-funksjonen med text som argument og skriver ut resultatet. Det er altså println-kallet og formateringen av teksten som er funksjonaliteten som kan gjenbrukes med print-funksjonen. I eksemplet brukes Scalas kompaktnotasjon for anonyme funksjoner der parameteret brukes kun én gang: <code>"&lt;html&gt;" + _ + "&lt;/html&gt;</code>. _ (underscore) brukes her for å referere til tekststrengen som funksjonen tar som parameter. Det er ikke nødvendig å deklarere typen da Scala kan utlede den fra deklarasjonen av print-funksjonen. Eksemplet nedenfor viser hvordan en navngitt funksjon med full signatur kan sendes som argument til print:</p>
<p><script src="https://gist.github.com/1331765.js?file=eksempel3.scala"></script></p>
<h2>Eksempel: Programmatisk transaksjonshåndtering med Spring</h2>
<p>Spring tilbyr flere måter å håndtere transaksjoner på: Via aspects definert i xml, annotations og programmatisk. Jeg har ofte endt opp med å bruke annotations fordi det er relativt enkelt å sette opp og det fremgår ganske tydelig i koden hva som kjøres i en transaksjon. Likevel er ikke annotations så fleksibelt og enkelt som det burde være. Noen ulemper:</p>
<ul>
<li>Feil oppdages ikke før runtime</li>
<li>Man må (bør) vite en del om den underliggende implementasjonen</li>
<li><code>@Transactional</code> krever en no-args default constructor hvis man ikke har et interface på klassen. Kjedelig hvis man bruker constructor-basert injection og ikke har behov for interfacet i koden</li>
<li>Man kan ikke gjøre interne kall mot en metode med @Transactional fra samme klasse. Dette medfører noen ganger uheldig oppdeling av klasser</li>
</ul>
<p>Når man ønsker litt mer kontroll, er programmatisk transakasjonshåndtering et godt alternativ. Med TransactionTemplate er det enkelt å eksplisitt kjøre kode i en transaksjon. <strong>Jeg skal vise hvordan man ytterligere kan forenkle dette med Scala og higher order functions.</strong></p>
<h3>Java</h3>
<p><script src="https://gist.github.com/1335846.js?file=javaeksempel.java"></script></p>
<p>Eksemplet viser hvordan man kaller TransactionTemplate sin execute-metode med en anonym implementasjon av interfacet TransactionCallback. Dette er i praksis en higher order function i Java. Men siden Java ikke støtter å sende en metode som parameter til en annen metode må metoden, her doInTransaction, wrappes i et interface. Slike en-metodes-funksjonsklasser er ganske vanlig i Java. Ulempen med denne løsnigen er:</p>
<ul>
<li>Unødvendig mye boilerplatekode</li>
<li>Koden blir mindre lesbar</li>
<li>Mindre fokus på hva som er oppførselen til funksjonen</li>
<li>Man må ha ulike funksjonsinterface for å støtte ulikt antall parametre</li>
</ul>
<h3>Scala</h3>
<p>Med scala kan vi lage en egen higher order function som en wrapper for TransactionTemplate sin execute-metode. Denne definerer vi som følger:</p>
<p><code>def doInTransaction[T](action: (TransactionStatus) => T): T</code></p>
<p>Vi ønsker at funksjonen skal kunne returnere en vilkårlig type så vi bruker et type-parameter T. Funksjonen tar ett parameter: <code>action</code> som er av typen <code>(TransactionStatus) => T</code>, altså en funksjon som tar inn TransactionStatus og returnerer T. Dette er identisk med TransactionCallback.doIntransaction som har signaturen:</p>
<p><code>T doInTransaction(TransactionStatus status);</code></p>
<p>Vår nye doInTransaction-funksjon kaller TransactionTemplate.execute på samme måte som i Javaeksemplet:</p>
<p><script src="https://gist.github.com/1335877.js?file=doInTransaction.scala"></script></p>
<p>Funksjonen kaller <code>action</code> inne i transaksjonen. Vi har dermed trukket ut all boilerplatekoden i en gjenbrukbar funksjon. Javaeksemplet vil nå kunne skrives (i Scala) som:</p>
<p><script src="https://gist.github.com/1335883.js?file=printMessageFromDB.scala"></script></p>
<h2>Konklusjon</h2>
<p>Higher order functions er et kraftig konsept som gjør det mulig å organisere koden på en mer effektiv måte og dermed redusere behovet for boilerplate og repetisjon. Scalas kompakte syntaks og støtte for higher order functions gir oss muligheten til å forenkle måten vi programmerer mot kjente Java-apier som Springs TransactionTemplate, JdbcTemplate og en rekke andre.</p>
<p>Kildekoden til eksemplene, samt oppsett av maven for Scala, Spring og transaksjoner, er tilgjengelig på <a href="https://github.com/froden/scala-spring-transactions">GitHub</a>.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/iV97_HKwL2E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/scala-higher-order-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/scala-higher-order-functions/</feedburner:origLink></item>
		<item>
		<title>Usability Week 2011</title>
		<link>http://feedproxy.google.com/~r/BekkOpen/~3/FYqfgBaTpZQ/</link>
		<comments>http://open.bekk.no/usability-week-2011/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 12:13:24 +0000</pubDate>
		<dc:creator>Christian Holthe</dc:creator>
				<category><![CDATA[BEKK]]></category>
		<category><![CDATA[Design og Brukeropplevelse]]></category>
		<category><![CDATA[FUNK]]></category>
		<category><![CDATA[brukeropplevelse]]></category>
		<category><![CDATA[funksjonalitet og brukeropplevelse]]></category>
		<category><![CDATA[konferanse]]></category>

		<guid isPermaLink="false">http://open.bekk.no/?p=7241</guid>
		<description><![CDATA[Oj, vi skal til London! Forventningene var høye når Christian Holthe og Mari Torgersrud Haug deltok på Usability Week 2011 i London forrige uke. Konferansen ble arrangert av Nielsen Norman Group, startet av Jacob Nielsen og Don Norman. Det skal sies at vi ble noe “starstruck” da Jacob Nielsen ruslet inn på forelesningen første dag for å ta bilder av [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://open.bekk.no/wp-content/uploads/2011/11/usabilityweek_pic.jpg"><img class="aligncenter size-full wp-image-7254" title="usabilityweek_pic" src="http://open.bekk.no/wp-content/uploads/2011/11/usabilityweek_pic.jpg" alt="Usability Week banner, Jacob Nielsen, London by Night" width="760" height="300" /></a></p>
<h2>Oj, vi skal til London!</h2>
<p>Forventningene var høye når Christian Holthe og Mari Torgersrud Haug deltok på <a title="Usability Week" href="http://www.nngroup.com/events/" target="_blank">Usability Week</a> 2011 i London forrige uke. Konferansen ble arrangert av Nielsen Norman Group, startet av <a href="http://www.useit.com/jakob/" target="_blank">Jacob Nielsen</a> og <a title="Don Norman" href="http://www.jnd.org/bio-sketch.html" target="_blank">Don Norman</a>. Det skal sies at vi ble noe “starstruck” da Jacob Nielsen ruslet inn på forelesningen første dag for å ta bilder av kollegaer og seminardeltakere.</p>
<p>NN Group jobber blant annet med å forske på designtrender, så de sitter på mye statistikk om forbrukere og atferdsmønstre på nett. Visste du for eksempel at:</p>
<ul>
<li>vi bruker 70 % av tiden på å se på venstre halvdel av en nettside</li>
<li>vi ser bare på 42 % av bildene vi kommer over på nettet</li>
<li>at multitasking egentlig er umulig for oss mennesker</li>
<li>vi mennesker ikke klarer og lagre mer enn 5 til 7 ting i korttidshukommelsen vår &#8211; Millers magic number 7 +-2</li>
<li>lojale kunder tenderer til å kjøpe 4 ganger mer enn førstegangsbesøkere på nett</li>
<li>vi bruker kun 10 sekunder på å bedømme om en nettside er interessant eller ikke</li>
</ul>
<h2>Hvordan tenker vi nettbrukere egentlig?</h2>
<p>NN Group har gjennom sin årelange forskning funnet flere mønstre på bruk av nett. Bannere og seksjoner som ligner reklame ser vi rett og slett ikke på, fordi vi er vant til at dette ikke er relevant for den informasjonen vi søker. Og vi liker å ha kontroll! Nettsider med lyd eller video som starter automatisk når vi laster en side, gjør at vi instinktivt ser etter måter vi kan slå av dette på. Det samme med bildekaruseller. Vi ønsker å ha mulighet til å velge det vi synes er relevant, og slippe å sitte og vente på at noe automatisk kommer rullende tilbake i synsfeltet vårt. Så tipset er å tilgjengeliggjøre funksjonalitet som lar brukerne styre bildekaruseller, lyd og video etter eget ønske. Det skaper både tillit og troverdighet, som kan bety mye for konverteringen og salg.</p>
<h3>Multitasking og design av brukergrensesnitt</h3>
<p>Vi mennesker liker å tro at vi kan multitaske. Sannheten er at ingen mennesker faktisk kan gjøre to ting nøyaktig samtidig. Noen er gode til å ta opp igjen tråden på påbegynte oppgaver raskt, men mange glemmer fort hva de egentlig holdt på med. I vår hverdag er det mer og mer vanlig at vi sitter med flere programmer, nettsider og enheter samtidig. Det er derfor nyttig at vi legger til rette for denne type bruk. Ved å vise hvilket søkeord som ble søkt på, (ja, noen glemmer faktisk dette) og markere besøkte linker legger vi til rette for at nettbrukere lettere skal huske hva de egentlig holdt på med. I tillegg bør vi fortelle brukerne hvor de er i nettstedlandskapet ved hjelp av brødsmuler og hvilket steg de befinner seg på i en bestillingsflyt.</p>
<h3>Mennesker og mentale modeller</h3>
<p>Hvilke forventninger vi har til et ett nettsted eller brukergrensesnitt bygger på tidligere opplevelser, vår kultur og vår hukommelse. Ting vi lett kjenner igjen og har brukt tidligere, krever mindre kognitiv anstrengelse når vi skal ta det i bruk.</p>
<p>Jacob Nielsen snakket om hvordan nye design patterns raskere blir standard i dag enn tidligere, fordi vi er mer mottakelige for nye ting. Mye av dette bygger på vår trang til og utforske og leke, som har fulgt oss siden barneåra. Når det er sagt, er det viktig at vi ikke tøyer grensene, og en gradvis introduksjon til nye og mer moderne design patterns er fortsatt å anbefale.</p>
<p>Kanskje noe av det viktigste <a title="Marieke McCloskey" href="http://www.nngroup.com/about/people/obdeyn.html" target="_blank">Marieke McCloskey</a> konkluderte med, som også snakket litt om mentale modeller. Var at det sjelden er match, mellom en designers mentale modell og en ordinær brukers mentale modell. Det er derfor svært viktig at vi samler inn data og analyserer tidlig i alle faser, slik at gapet mellom hva vi lager og hva brukere forventer blir minst mulig.</p>
<h2>Du trenger ikke finne opp hjulet på nytt</h2>
<p>Standard komponenter og konvensjoner vil fungere best i 90 % av tilfellene på nett, hevder Jacob Nielsen. Vi ser automatisk opp i høyre hjørnet når vi ikke finner det vi leter etter og vil prøve å søke etter informasjon. Blå understreket tekst er fortsatt beste måten å fremstille en link på. Og <a title="Fitt's law" href="http://en.wikipedia.org/wiki/Fitts's_law" target="_blank">fitt&#8217;s law</a> er fortsatt like gyldig i dag som for 20 år siden. Det var mye av dette vi forventet å høre etter å ha sett på websiden hans, <a title="useit.com" href="http://www.useit.com/" target="_blank">useit.com</a>.</p>
<p>Det er mye Jacob Nielsen sier som begynner å bli &#8220;common sense&#8221;, og som er gammelt nytt for oss som jobber i denne bransjen. Men det er få selskaper i verden som gjør så mye forskning på bruksadferd som NN Group. Forskningsresultatene gir oss verdifull kunnskap, som vi bør ta med oss videre inn i prosjekter og i vårt tankesett når vi designer løsninger.</p>
<h2>Vi er i fremtiden</h2>
<p>Don Norman holdt konferansens keynote med tittelen &#8220;Vi er i fremtiden&#8221;. Inntrykket av Don Norman er at han er meget oppegående, og fremstår som en slags bestefarfigur som man automatisk får mye respekt for. Denne mannen har mye og komme med. Norman snakket om at vi befinner oss i et univers av teknologi. I det daglige blir vi konstant konfrontert med ny teknologi som gjør at hverdagen vår blir litt enklere og mer praktisk. I bilen, i huset, på bussen, på jobben. Overalt er det ny teknologi, og vi tilpasser oss mer og mer en teknologi drevet hverdag. Norman trakk spesifikt frem appen SIRI, nylig lansert på iPhone, og hans kommentar var ”Artificial intelligence actually works”.<br />
I kjent Don Norman stil hadde han noen spådommer rundt mennesker og teknologi. Vi har plukket ut de viktigste punktene.</p>
<ul>
<li>”Smarttelefoner, nettbrett og pc’er vil smelte sammen og bli uniformt”</li>
<li>”Det kommer mange flere enheter som vil forandre markedet”</li>
<li>”Touch gestures vil bli mer vanlig for andre typer enheter som eksempelvis i hjemmet”</li>
<li>”Se opp for ASIA. De er i sterk vekst både økonomisk og innovativt”</li>
<li>”Det største fremtidige problemet for teknologien vil være knyttet til sikkerhet, brukskvalitet og personvern”</li>
<li>”Websider kommer til å bli APPS, og webdesignere blir APP designere”</li>
</ul>
<h2>Var det verdt å delta på Usabilty Week?</h2>
<p>Usability Week er ikke konferansen du drar på hvis du ønsker å vite hva som er nytt på teknologifronten eller du søker inspirasjon til å tenke nytt. Usability Week er en konferanse som baserer seg på forskningsresultater og erfaringer av hva som fungerer over tid. Foredragsholderne er proffe og det er også deilig å slippe presentasjoner hvor halve tiden går med til å reklamere for et firma eller produkt.</p>
<img src="http://feeds.feedburner.com/~r/BekkOpen/~4/FYqfgBaTpZQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://open.bekk.no/usability-week-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://open.bekk.no/usability-week-2011/</feedburner:origLink></item>
	</channel>
</rss>
