<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7928985878402740088</id><updated>2011-11-15T23:09:30.732+01:00</updated><category term='mentor'/><category term='domain model'/><category term='NFR'/><category term='encoding'/><category term='actors'/><category term='javadoc'/><category term='mock'/><category term='domain driven security'/><category term='behaviour driven development'/><category term='sql injection'/><category term='scrum master'/><category term='dog-food'/><category term='requirement'/><category term='validation'/><category term='application security'/><category term='entity'/><category term='exceptions'/><category term='psychology'/><category term='TDD'/><category term='statistical analysis'/><category term='agile'/><category term='backlog'/><category term='unit test'/><category term='planning'/><category term='BDD'/><category term='owasp'/><category term='xss'/><category term='DDD'/><category term='code'/><category term='product owner'/><category term='user story'/><category term='database'/><category term='story'/><category term='philosophical'/><category term='knowledge'/><category term='scala'/><category term='refactoring'/><category term='process'/><category term='domain driven design'/><category term='Java'/><category term='value object'/><category term='versioning'/><category term='scrum'/><category term='coach'/><category term='domain event'/><category term='ubiquitous language'/><category term='design by contract'/><category term='project management'/><category term='release'/><category term='model'/><category term='architecture'/><category term='tech story'/><title type='text'>Dear Junior - Letters to a Junior Programmer</title><subtitle type='html'>Thoughts on Programming; what we do, and how we do it</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>72</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-8727254855639220950</id><published>2011-11-15T22:54:00.001+01:00</published><updated>2011-11-15T23:09:30.753+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Akka 1.2 Made it Simple to Get Started</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;Dear Junior&lt;br /&gt;&lt;br /&gt;The release of Akka 1.2 is about a month old, but it contains a change that is makes it much easer to try out Akka. It is not some revolutionary new feature, quite the contrary. They have simplified the package structure of Akka so much that the core Akka actor package now has &lt;i&gt;no&lt;/i&gt; external dependencies. Correct: no, none, zip external dependencies - stands for itself.&lt;br /&gt;&lt;br /&gt;Earlier, if you wanted to try out Akka, you had the problem that Akka relied on a ton of other open source libraries. So, if you just wanted to try out to write a simple actor, you still had to download a long list of other jars. Well, that can be handled by maven, or by the wonderful little tool "sbt" (Simple Build Tool), but still that is a threshold to get over before getting started. And that threshold has noting to do with "understanding actors".&lt;br /&gt;&lt;br /&gt;In Akka 1.2 they have done a wonderful job of splitting out dependencies and managed to refine to "core actor" parts to be self-contained, i e it does not require any other libraries in place to work.&lt;br /&gt;&lt;br /&gt;To get started writing your first Akka actor, simply download Akka 1.2 and put "akka-actor-1.2.jar" on your classpath. Ready to start hakking.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;An Example&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;In InteillJ, I create a new project "akka12" in a library with the same name:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;dajob05:akka12 danbj$ pwd&lt;br /&gt;/Users/danbj/var/tmp/akka12&lt;br /&gt;dajob05:akka12 danbj$ ls -l&lt;br /&gt;total 8&lt;br /&gt;-rw-r--r--  1 danbj  staff  796 15 Nov 15:55 akka12.iml&lt;br /&gt;drwxr-xr-x  2 danbj  staff   68 15 Nov 15:55 src&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Well, I happen to use IntelliJ, but any other modern IDE would work as well.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, I create a "lib" directory for third party libraries (i e Akka), download akka and put the jar in "lib"&lt;br /&gt;&lt;code&gt;&lt;br /&gt;mkdir lib&lt;br /&gt;curl http://akka.io/downloads/akka-actors-1.2.zip &amp;gt;akka-1.2.zip&lt;br /&gt;unzip akka-1.2.zip akka-actors-1.2/lib/akka/akka-actor-1.2.jar&lt;br /&gt;mv akka-actors-1.2/lib/akka/akka-actor-1.2.jar lib/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now the self-contained Akka jar is in the lib directory.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;dajob05:akka12 danbj$ ls lib&lt;br /&gt;akka-actor-1.2.jar&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I add the jar as a project library in my IntelliJ project, and now I can create an actor class together with a small script that sends a message to that actor.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import akka.actor.Actor&lt;br /&gt;&lt;br /&gt;object helloworld extends App {&lt;br /&gt;&amp;nbsp; val worlder = Actor.actorOf[Worlder]&lt;br /&gt;&amp;nbsp; worlder.start()&lt;br /&gt;&amp;nbsp; worlder ! "hello"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Worlder extends Actor {&lt;br /&gt;&amp;nbsp; def receive = {&lt;br /&gt;&amp;nbsp; &amp;nbsp; case msg =&amp;gt; println(msg + " world") &lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Running it (from inside the IDE) gives the expected&lt;br /&gt;&lt;code&gt;&lt;br /&gt;hello world&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;I just love what the Typesafe crowd have done to make it so easy to get started.&lt;br /&gt;&lt;br /&gt;Happy hakking&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-8727254855639220950?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/8727254855639220950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/11/akka-12-made-it-simple-to-get-started.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8727254855639220950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8727254855639220950'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/11/akka-12-made-it-simple-to-get-started.html' title='Akka 1.2 Made it Simple to Get Started'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-3524686598180787684</id><published>2011-10-13T09:26:00.001+02:00</published><updated>2011-10-13T09:26:19.731+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala Actors and Estragon's Bad Memory</title><content type='html'>&lt;div class="Lpande"&gt;&lt;/div&gt;&lt;div class="Lpande"&gt;&lt;/div&gt;&lt;div class="Lpande" style="text-align: justify;"&gt;&lt;br /&gt;&lt;div class="p1"&gt;Dear Junior&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;The event-based actor model in Scala is obviously so much more memory-efficient than the thread-based, so there must be a catch somewhere.&amp;nbsp; There sure is, the price we pay is that the code does not always behave in the way we intuitively expect. And unfortunately the coding model does not shield us completely from those situations.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;The reason I think this is important is that I want to walk the road towards Akka. Once we get there it will be obvious why Akka’s design give us both an efficient runtime model and a carefully guiding programming model.&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;Unintuitive Effects of Event-Based Model&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Let us return to the programming model of event-based actors in Scala standard library, and the things that might baffle us.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;One of the things that might happen is that inside one instance of actor, &lt;i&gt;consecutive&lt;/i&gt; lines of code&lt;i&gt; &lt;/i&gt;might be executed by&lt;i&gt; different&lt;/i&gt; threads. That is not what we expect.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Let us pick apart an event-based actor to see what is going on, and the same with a thread-based actor – just for reference.&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;Dissecting Thread-Based Vladimir&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;To see how that can happen, let us start with a simple thread-based actor – our dear friend Vladimir. In a small script, we create an actor, start it and send it the message (Godot) that it is waiting for. OK, in the play &lt;i&gt;Waiting for Godot&lt;/i&gt;, the point is that Godot never shows up, but let us be nice to poor Vladimir.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;object vladimirwaitandrun extends Application {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def T() = "T" + Thread.currentThread().getId&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Creating actor " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; val vlad = new Vladimir(42)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Starting actor " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; vlad.start()&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Sending Godot message " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; vlad ! Godot&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Finished script " + T())&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="p3"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;The Godot-waiting actor Vladimir is implemented as a subclass to “actors.Actor” of the Scala standard library.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Vladimir(id : Int) extends Actor {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def T = "T" + Thread.currentThread.getId&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def name: String = "Vladimir" + id&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def act() {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; println(name + " is waiting " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; receive {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; case Godot =&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; println(name + " saw Godot arrive! " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;All set up – let us run the script.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;danbj$ scala godot.vladimirwaitandrun&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Creating actor T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Starting actor T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Vladimir42 is waiting T11&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Sending Godot message T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Finished script T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Vladimir42 saw Godot arrive! T11&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;First we note that the script and the actor are run by different threads: T1 and T11 respectively – no surprise. We also note that both lines of Vladimir where run by the same thread. No surprise that either, the thread-based model gives each actor a thread and when the actor pauses (waiting for Godot), the thread pauses.&lt;/div&gt;&lt;div class="p1"&gt;But let us walk through this just to see the difference when we come to the event-based model.&lt;/div&gt;&lt;ul class="ul1"&gt;&lt;li class="li5"&gt;An actor of the class Vladimir is created and started – its “act” method start executing in a thread of its own (T11) starting with a print.&lt;/li&gt;&lt;li class="li5"&gt;The actor executes the method “receive” (still in thread 11). The call to receive takes an argument, which is the so-called “message handler” – a code-block to be used when matching the incoming message. To be precise, the argument is an anonymously defined function, which is passed as the argument to “receive”. &amp;nbsp;&lt;/li&gt;&lt;li class="li5"&gt;As there is no message in the actor’s mailbox, “receive” puts the thread (T11) to sleep.&amp;nbsp;&lt;/li&gt;&lt;li class="li5"&gt;Message “Godot” is dropped into Vladimir’s mailbox (by T1). Waiting thread T11 is notified. Thereafter the script finishes.&lt;/li&gt;&lt;li class="li5"&gt;T11 wakes up and starts applying the message-handler to the arrived message. There is a match in the (only) case-clause and T11 prints “Vladimir42 saw Godot arrive! T11”&lt;/li&gt;&lt;li class="li5"&gt;Execution of message handler is finished. As there is no more code in “act” the thread returns.&lt;/li&gt;&lt;/ul&gt;&lt;div class="p6"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;OK, there are more subtleties going on, but this will do for now.&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;Dissecting Event-Based Estragon&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Now let us look at the same thing happening with an event-based actor: our dear friend Estragon.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;object estragonwaitandrun extends Application {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def T() = "T" + Thread.currentThread().getId&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Creating actor " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; val estragon = new Estragon(42)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Starting actor " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; estragon.start()&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Sending Godot message " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; estragon ! Godot&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; println("Finished script " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;The Godot-waiting actor Estragon is also implemented as a subclass to “actors.Actor”, and the only difference is that it uses another method for awaiting a message in the mailbox. Instead of “receive” it uses “react”.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Estragon(id : Int) extends Actor {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def T = "T" + Thread.currentThread.getId&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def name: String = "Estragon" + id&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def act() {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; println(name + " is waiting " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; react {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; case Godot =&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; println(name + " saw Godot arrive! " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="p3"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;All set up. Let us run this.&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;danbj$ scala godot.estragonwaitandrun&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Creating actor T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Starting actor T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Estragon42 is waiting T10&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Sending Godot message T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Finished script T1&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Estragon42 saw Godot arrive! T13&lt;/span&gt;&lt;/div&gt;&lt;div class="p3"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Now, let us walk through this run and see what actually happened.&lt;/div&gt;&lt;ul class="ul1"&gt;&lt;li class="li5"&gt;An actor of the class Estragon is created and started. A thread (T10) is taken from the thread pool and connected to the actor. The thread start running the “act” method, which starts with a print.&lt;/li&gt;&lt;li class="li5"&gt;The actor executes the method “react” (still in T10). The call to react takes an argument, which is the so-called “message handler” – a code-block to be used when matching the incoming message. To be precise, the argument is an anonymously defined function, which is passed as the argument to “react”.&amp;nbsp;&lt;/li&gt;&lt;li class="li5"&gt;As there is no message in the actor’s mailbox, “react” disconnects the thread from the actor. The message-handler is registered at the event handler. The thread goes back to the thread pool.&lt;/li&gt;&lt;li class="li5"&gt;Message “Godot” is dropped into Estragon’s mailbox from the script (by T1). The event-handler is notified. The script thereafter finishes.&lt;/li&gt;&lt;li class="li5"&gt;The event-handler picks an available thread (T13) from the thread pool and connects it with the actor. The thread is given the message-handler to run and starts applying the message-handler to the arrived message. There is a match in the case-clause and T13 prints “Estragon42 saw Godot …”&lt;/li&gt;&lt;li class="li5"&gt;Execution of message handler is finished. Thread is disconnected and goes back to pool.&lt;/li&gt;&lt;/ul&gt;&lt;div class="p3"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Note that there are two different threads (T10 and T13) involved in executing the actor Estragon42. Having a pool of threads does not only mean that one thread can serve many actors (thus conserving resources). It does also mean that different threads might be involved in running the same actor during its lifespan.&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;To be honest, I must admit that I did run the script a few times before I got a run with different threads in “is waiting” and “saw Godot arrive”. The allocation of threads is non-deterministic from the point of view of the program, and the first few runs happened to reuse same thread in both phases – but that would not serve to make my point.&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;The Difference in Short&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Let us focus on the core difference between these two examples; first thread-based Vladimir.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; println(name + " is waiting " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; receive {&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; case Godot =&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; println(name + " saw Godot arrive! " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #38761d; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Here the same thread (T10, marked as &lt;span class="Apple-style-span" style="color: #38761d;"&gt;green&lt;/span&gt;), execute the consecutive lines. It executes the println and the receive, makes a small pause, and finish with the matching case clause and the last println.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;This is execution of code as we learned in Programming 101.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Now, time for event-based Estragon&lt;/div&gt;&lt;div class="p2"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #0b5394; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; println(name + " is waiting " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="color: #0b5394;"&gt;&amp;nbsp; &amp;nbsp; react&lt;/span&gt; &lt;span class="Apple-style-span" style="color: #741b47;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #741b47; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; case Godot =&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #741b47; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; println(name + " saw Godot arrive! " + T)&lt;/span&gt;&lt;/div&gt;&lt;div class="p2"&gt;&lt;span class="Apple-style-span" style="color: #741b47; font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;&lt;div class="p4"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Here two threads are involved. First one (marked &lt;span class="Apple-style-span" style="color: #0b5394;"&gt;blue&lt;/span&gt;) execute println and react, ending with registering the message-handler. Then at a later point of time some other thread (marked &lt;span class="Apple-style-span" style="color: #741b47;"&gt;purple&lt;/span&gt;) executes the case-clause and the last println.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;The result is that consecutive lines of code inside the same actor object is executed by different threads.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Not what we learned in Programming 101.&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;Does it Matter?&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;OK, but does it matter? Unfortunately there are situations where this makes a difference for us as programmers. For example, many security frameworks take user credentials of the authenticated user and stuff it into thread locals. In that way the credentials need not to be passed around explicitly but can be fetched from the thread when needed. Alas, that does not work if the code “suddenly changes horses midrace”.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;There are also other situations where the code behaves in unintuitive ways due to this “thread switching” and where the programming model does not shield us programmers from strange effects and risk of making errors. More on that later.&amp;nbsp;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;i&gt;Estragon’s Bad Memory&lt;/i&gt;&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;On a side not the difference in execution model can also explain one aspect of the play Waiting for Godot. In the play, Estragon suffers from a severe memory condition. When the Act II starts on the morning of the second day, it seems like Estragon has no recollection at all from what happened in Act I the previous day. This is enormously frustrating for his companion-in-waiting Vladimir, who clearly remembers how they waited in vain for Godot to show up.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Now given the knowledge about threading it is obvious why Vladimir remembers the previous day. Thread-based Vladimir is in Act II connected to the same thread of execution as in Act I – so the events in Act I happened to “the same memory-line” as Act II. Event-based Estragon on the other hand is not necessarily connected to the same thread in Act II as he was in Act I, so Estragon in Act II is not “the same memory-line” as Estragon in Act I. In a way Estragon experience the same situations as a person with multiple-personality disorder. Even if it is the same Estragon-body (object, actor), it is not the same Estragon-mind (thread) from time to time.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;That might be an explanation for Estragon’s bad memory. It would be interesting to diagnose it more closely, like if we could probe his mind for what is going on from time to time.&lt;/div&gt;&lt;div class="p1"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="p1"&gt;Yours&lt;/div&gt;&lt;div class="p1"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-3524686598180787684?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/3524686598180787684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/10/scala-actors-and-estragons-bad-memory.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3524686598180787684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3524686598180787684'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/10/scala-actors-and-estragons-bad-memory.html' title='Scala Actors and Estragon&apos;s Bad Memory'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-5945173230277201315</id><published>2011-09-16T08:24:00.000+02:00</published><updated>2011-09-16T08:56:09.615+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Public final and data encapsulation</title><content type='html'>&lt;br /&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;We were discussingimmutable value objects and using "public final" data-fields fortheir representation. In that discussion I started off mixing up immutabilityand encapsulation. Now that &lt;a href="http://dearjunior.blogspot.com/2011/09/public-final-is-also-immutable-again.html"&gt;we have covered immutability&lt;/a&gt;, let us return toencapsulation. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Obviously, declaring afield as public will break data encapsulation. You lose your freedom to changedata representation without having to bother the clients. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us have a look at aname-class with some actual usage.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public class Name {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;public final&lt;/b&gt; String &lt;b&gt;fullname&lt;/b&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Name(Stringfullname) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!fullname.matches("[a-zA-Z\\ ]+"))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw new IllegalArgumentException();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.fullname = fullname;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String[] &lt;b&gt;names()&lt;/b&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return fullname.split(" ");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The public API of thisclass consists of three parts: the construction of a name from a string, theattribute “fullname” (accessible through property data field), and theattribute “names (accessible through accessor method).&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;An example of whatclient code looks like we can find in the tests.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public class NameTest {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final Stringdanbjson = "Dan Bergh Johnsson";&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public voidshouldHaveFullNameAsAttribute() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.assertEquals(danbjson, new Name(danbjson)&lt;b&gt;.fullname&lt;/b&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test(expected =IllegalArgumentException.class)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; public voidshouldNotAllowWeiredCharsInName() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;newName("#€%&amp;amp;/");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public voidshouldSplitIntoNamesAtSpaces()&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;Assert.assertEquals(&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new String[] {"Dan", "Bergh","Johnsson"},&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;new Name(danbjson)&lt;b&gt;.names()&lt;/b&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Imaging that we want tochange the internal data representation to using a char-array instead. Doing sowill break all the clients as they rely on having that public data-field“fullname”. Thus, it is a bad design. Or?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I would argue that itis still a good design. Using modern tools it is easy to add the encapsulationwhen needed. Applying "Encapsulate Field" in e g IntelliJ yields.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public class Name {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;private&lt;/b&gt; final Stringfullname;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Name(Stringfullname) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!fullname.matches("[a-zA-Z\\ ]+"))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw new IllegalArgumentException();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.fullname = fullname;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String[] names() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return fullname.split(" ");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String fullname() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return fullname;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;And of course theclient code has been changed accordingly.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Test&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public voidshouldHaveFullNameAsAttribute() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assert.assertEquals(danbjson, new Name(danbjson).&lt;b&gt;fullname()&lt;/b&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, I could havechosen "getFullname" as the method name for the new method. However,I have always found that naming convention a little bit awkward, the propertyis “full name” and adding a boilerplate “get” does not add any value in myopinion. By the way, JavaBeans is just one naming convention in Java, thenaming convention for CORBA predates JavaBeans. In the CORBA convention if youhave a property “fullname” of type String, then the way to access it was tocall a method “String fullname()” and the way to change the property was tocall a method&amp;nbsp; “void fullname(String)”.So the convention I use is not new to Java at all.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In some languages thereis no distinction in syntax between accessing a field and calling a no-argmethod. Had the code been written in Eiffel or Scala, the syntax would havebeen the same and there would be no change to the client code at all.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now that we haveencapsulated the usage via “fullname()” we can change the internalrepresentation to a char array.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;public class Name {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final &lt;b&gt;char[] chars&lt;/b&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Name(String name) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(!name.matches("[a-zA-Z\\ ]+"))&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw newIllegalArgumentException();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.&lt;b&gt;chars&lt;/b&gt; = &lt;b&gt;name.toCharArray()&lt;/b&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String[] names() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new String(&lt;b&gt;chars&lt;/b&gt;).split(" ");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String fullname() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new String(&lt;b&gt;chars&lt;/b&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Just for reference, inScala the corresponding change would start with this "final public"representation – here represented by the keyword “val”. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Name(&lt;b&gt;val&lt;/b&gt;&lt;b&gt;fullname&lt;/b&gt;: String)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span lang="EN-GB"&gt;&amp;nbsp; if(!fullname.matches("[a-zA-Z\\]+"))&lt;/span&gt;&amp;nbsp;throw new IllegalArgumentException();&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def &lt;b&gt;names&lt;/b&gt; = fullname.split(' ')&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The change would takeus to the slightly more verbose char array representation. Here we have no“val” in external class declaration, but a private val-field hidden inside the class-blockinstead.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Name(name:String)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; if(!name.matches("[a-zA-Z\\]+")) throw new IllegalArgumentException();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; &lt;b&gt;private val chars&lt;/b&gt; = name.toCharArray&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def fullname = chars.toString&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; def names = fullname.split(' ')&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In conclusion: As thepublic final field is accessible by the clients, it is also a part of the APIfor Name: This breaks data encapsulation. If you want to change datarepresentation, you will need to create an accessor method to which you directthe client.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In Scala or Eiffel thisis a no-issue, as the new accessor could transparently have the same name asthe old datafield ("fullname") and be accessed with exactly the samesyntax ("name.fullname"). However, in Java you have to include anempty pair of parenthesis to call the accessor method - thus the client codemust be changed.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, I consider this asmall issue, as there is excellent refactoring support in modern IDEs that eliminatethe change to a fully automated four-click, one-minute exercise. Thus, there isno point in designing for that change up front.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, even if we *do*break data encapsulation, I would say that it is not much of a problem. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, there are otherkinds of encapsulations that are more interesting than data encapsulation, butthat analysis will have to wait for some other letter.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-layout-grid-align: none; mso-pagination: none; tab-stops: 28.3pt 56.65pt 85.0pt 113.35pt 141.7pt 170.05pt 198.4pt 226.75pt 255.1pt 283.45pt 311.8pt 340.15pt; text-align: justify; text-autospace: none;"&gt;&lt;span lang="EN-GB"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-GB" style="font-family: Georgia;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-5945173230277201315?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/5945173230277201315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-and-data-encapsulation.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5945173230277201315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5945173230277201315'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-and-data-encapsulation.html' title='Public final and data encapsulation'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-6221528587844191035</id><published>2011-09-12T16:26:00.000+02:00</published><updated>2011-09-12T16:31:11.369+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Public final is also Immutable, Again</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;I must apologise as in my last letter I mixed two separate discussions into one: one about immutability, and one about encapsulations. What I was after was immutability, even though encapsulation is also interesting.&lt;br /&gt;&lt;br /&gt;To make thinks clear, let us return to the Name class for representing value objects for a name e g "Dan Bergh Johnsson". To focus on immutability, let us simplify it.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class Name {&lt;br /&gt;    public final String fullname;&lt;br /&gt;&lt;br /&gt;    public Name(String fullname) {&lt;br /&gt;        this.fullname = fullname;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, if I create an object of this class, then no client can mutate the state of that object. This is because&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The datafield is final so the client cannot make the reference point to some other String&amp;nbsp;&lt;/li&gt;&lt;li&gt;Strings are immutable, so the referred object cannot be changed&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Just for reference. I mentioned that Scala has a very elegant way of defining "public immutable datafield properties". The corresponding Scala class would be a one-liner.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Name(val fullname: String)&lt;/pre&gt;&lt;br /&gt;Elegant, isn't it? "Name is a class with the attribute value 'fullname' of type String". Scala promotes the use of immutable constructs by making it simple to declare them.&lt;br /&gt;&lt;br /&gt;Now, as my friend Tommy Malmström pointed out to me, I should also make my class final. This is a very valid and interesting point, so let me dig into.&lt;br /&gt;&lt;br /&gt;The problem in this case is not the objects we construct ourselves, but objects that are sent to us. We should rightfully assume that such objects are also immutable.However, someone could wittingly and deviously create a mutable subclass of Name.&lt;br /&gt;&lt;br /&gt;Back in Java land such a subclass could for example overrride toString&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;package names;&lt;br /&gt;&lt;br /&gt;class EvilName extends Name {&lt;br /&gt;    public EvilName(String fullname) {&lt;br /&gt;        super(fullname);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String toString() {&lt;br /&gt;        return "Voldemort";&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        Name name = new EvilName("Harry Potter");&lt;br /&gt;        System.out.println(name);&lt;br /&gt;        System.out.println(name.fullname);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;danbj$ java names.EvilName&lt;br /&gt;Voldemort&lt;br /&gt;Harry Potter&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You see how confusing it could be when toString is used to render the name object "Harry Potter".&lt;br /&gt;&lt;br /&gt;So, forbidding such overrides by declaring the Name class as final is really a good idea.&lt;br /&gt;&lt;br /&gt;On a side note, this is the reason why String is declared final. The String class is for example used to represent class and package information when loading code dynamically over the network - so imagine the consequences had it been possible to make a mutable phoney String.&lt;br /&gt;&lt;br /&gt;Well, that was about immutability.&lt;br /&gt;&lt;br /&gt;On the issue of encapsulation it can be argued whether&amp;nbsp;"public final String fullname" breaks encapsulation or not - and that discussion also depends on what encapsulation we mean. Any way, that is a separate discussion.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-6221528587844191035?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/6221528587844191035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-is-also-immutable-again.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6221528587844191035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6221528587844191035'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-is-also-immutable-again.html' title='Public final is also Immutable, Again'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-3600156317616095911</id><published>2011-09-09T16:35:00.000+02:00</published><updated>2011-09-16T08:19:44.266+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>"public final" is also Immutable</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;Immutable value objects are one of my favourite programming idioms. I really like how they aid and ease the burden of the rest of the code by taking care of small pieces of complexity. When they are based on the concepts of the domain they become yet another magnitude more valuable.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Implementation-wise they are most often a primitive type wrapped up in a protecting box. So it is pretty natural that a "name" is stored with a String containing the full name. Wrapped together in the box is probably as well some complexity, like the validation of the name and some interpretations of the data - in this case the logic to split a full name into its parts. At the end of the day, it is not so interesting to encapsulate the data as such - it is encapsulating the interpretation of the data that is crucial.In Java such a name class would look like this.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public class Name {&lt;br /&gt;    public final String fullname;&lt;br /&gt;&lt;br /&gt;    public Name(String fullname) {&lt;br /&gt;        if(!fullname.matches("[a-zA-Z\\ ]+"))&lt;br /&gt;            throw new IllegalArgumentException();&lt;br /&gt;        this.fullname = fullname;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String[] names() {&lt;br /&gt;        return fullname.split(" ");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, one thing worth noting is the datafield "fullname". It plays double roles both as data storage and as an attribute. Should we not have a private field and an accessor method instead?&lt;br /&gt;&lt;br /&gt;Well, the integrity of the object is still guaranteed as&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the datafield is final so the referred object cannot be exchanged&amp;nbsp;&lt;/li&gt;&lt;li&gt;the referred object (String) is immutable so the referred object cannot be changed&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So, yes, people can get to the field from the outside, but they cannot break anything.Of course there is the question that &lt;i&gt;if&lt;/i&gt; you change the data representation, &lt;i&gt;then&lt;/i&gt; you will break the clients.&lt;br /&gt;&lt;br /&gt;However, that is no big deal. If the situation should arise, we can apply the refactoring "encapsulate field" to introduce a new method "String fullname()" and replace every access to the field with a call to that method instead. Checking the entire codebase for accesses to "fullname" might be a large task. But, guess what, using a modern IDE there will be a menu item in the "Refactoring" menu that will do exactly that - fully automated.&lt;br /&gt;&lt;br /&gt;The alternative would be to have that code in from the start. However, I cannot see that there is a point in paying the overhead of more lines of code in the meantime.&lt;br /&gt;&lt;br /&gt;Making a field public does not break encapsulation. The important encapsulation is the interpretation and constraints of the data that is found in the constructor validation and the logic of the method "names()".&lt;br /&gt;&lt;br /&gt;By the way: in Scala you would not be able to see the difference between a public field and a method with the same name. Nice.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&amp;nbsp; &amp;nbsp;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-3600156317616095911?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/3600156317616095911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-is-also-immutable.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3600156317616095911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3600156317616095911'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/09/public-final-is-also-immutable.html' title='&quot;public final&quot; is also Immutable'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-8973900091449781305</id><published>2011-08-07T00:34:00.000+02:00</published><updated>2011-08-07T00:34:10.435+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala Actors are Just Code - No Magic</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;First time I tried out actors in Scala I though: "OK, there is a fair amount of magic going on here". I have later realised that there is actually no magic at all involved, but I would like to share with you my misconception and how it cleared out. &lt;br /&gt;&lt;br /&gt;I am talking about syntax like&lt;br /&gt;&lt;pre&gt;vlad ! Godot&lt;br /&gt;&lt;/pre&gt;and like&lt;br /&gt;&lt;pre&gt;receive {&lt;br /&gt;    case Godot =&amp;gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The good part is that once I had my misconceptions cleared out, it was much easier to understand some weird parts of the Scala standard actors, and the path to understanding the design of &lt;a href="http://akka.io/"&gt;Akka&lt;/a&gt; became much clearer.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;What I Mean with Magic&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let me for a brief moment clarify what I mean with "magic" in this context. A program consists of two parts - those I can build myself, and those where magic occurs. And when there is magic, there are often some magic words involved.&lt;br /&gt;&lt;br /&gt;Take for example the thread model of Java (and the JVM) where objects can be "locked". Down in the runtime, each object has a lock associated with it and this lock can be "obtained" using the magic formula&lt;br /&gt;&lt;pre&gt;synchronized (objectToLock) { … }&lt;br /&gt;&lt;/pre&gt;Here “synchronized” is a special construct to handle those locks. There is no way for me to create a lock with the same functionality through "ordinary programming". I have to wave my wand and utter that precise magic phrase - then I conjure the object-locks down in the runtime to do my bidding.&lt;br /&gt;&lt;br /&gt;In language design these constructions are sometimes referred to as "special forms" because they often have special syntax. &lt;br /&gt;&lt;br /&gt;Another example of special forms is the for construct in Scala&lt;br /&gt;&lt;pre&gt;for(vlad &amp;lt;- vladimirs) { vlad.start() }&lt;br /&gt;&lt;/pre&gt;There is no way for me as a programmer to build a construct that behaves the same way. The special syntax is built into the language, and reserved for some special behaviour decided by the language designers. For me as a programmer – some magic occurs. I can understand its effect, but not reproduce how it works.&lt;br /&gt;&lt;br /&gt;The actor syntax in Scala definitely looked like this kind of magic to me.&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;The Stage&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Let me start with what confused me. To simplify the discussion slightly, there are two places where there seem to be "magic" involved about actors: on the outside, and on the inside.&lt;br /&gt;&lt;br /&gt;Allow me to reuse &lt;a href="http://dearjunior.blogspot.com/2011/05/scala-actor-waiting-for-godot-vladimir.html"&gt;my example of the actor "Vladimir"&lt;/a&gt; with inspiration from Waiting for Godot.&lt;br /&gt;&lt;br /&gt;On the "outside" of the actors we have the way one actor sends a message to another actor. A really simplified example is a script that creates an actor and then sends a message to it. &lt;br /&gt;&lt;pre&gt;object vladimirwaitandrun extends Application {&lt;br /&gt;    val vlad = new Vladimir(42)&lt;br /&gt;    vlad.start()&lt;br /&gt;    vlad ! Godot&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In this example we assume that the class "Vladimir" is defined as an actors, and that "Godot" is a simple message type (defined as a case class).  Now what looks very "magic" to me is the line where the message is sent.  &lt;br /&gt;&lt;pre&gt;vlad ! Godot&lt;br /&gt;&lt;/pre&gt;This does not look like ordinary Scala syntax to me. It looks like one of those special forms with its associated magic going on.&lt;br /&gt;&lt;br /&gt;We will later see that I was mistaken here.&lt;br /&gt;&lt;br /&gt;On the "inside" we have how the actor reacts on messages that are passed to it. In Scala standard actors this happens inside the "act" method of a class that extends "actors.Actor"  &lt;br /&gt;&lt;pre&gt;class Vladimir (id : Int) extends actors.Actor {&lt;br /&gt;&lt;br /&gt;    def name: String = {&lt;br /&gt;        "Vladimir" + id&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def act() = {&lt;br /&gt;        println(name + " is waiting ")&lt;br /&gt;        receive {&lt;br /&gt;            case Godot =&amp;gt;&lt;br /&gt;            println(name + " saw Godot arrive! ")&lt;br /&gt;        }&lt;br /&gt;    println(name + "'s wait is over ")&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In this code the "receive-block" matches out arrived messages and run the appropriate code for the message.  &lt;br /&gt;&lt;pre&gt;receive {&lt;br /&gt;    case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! ")&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Well, this is the thread-based model, there is also the event-based model where "receive" is replaced with "react" and does something very similar. The difference is beside the point for this discussion, but this discussion is crucial to understand the difference and its subtleties.&lt;br /&gt;&lt;br /&gt;To me, this receive-block looks like a "special form" that invokes some magic. If anything, it reminds me of the synchronized-block mentioned earlier.&lt;br /&gt;&lt;br /&gt;We will later see that I was mistaken here as well.&lt;br /&gt;&lt;br /&gt;To make the setting of the stage complete, let us run the script that creates an actor and sends a message to it, a message upon which the actor reacts.  &lt;br /&gt;&lt;pre&gt;danbj$ scala godot.vladimirwaitandrun&lt;br /&gt;Vladimir42 is waiting&lt;br /&gt;Vladimir42 saw Godot arrive! &lt;br /&gt;Vladimir42's wait is over&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;My Erlang Heritage&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;One way to explain my misconception is of course my preconceived notion based on my previous experience. When I first learned actor programming some fifteen years ago, I did so using Erlang.&lt;br /&gt;&lt;br /&gt;In Erlang actors are called "processes" and they interact by dropping messages to each other. The receiving process reacts on the message and does something, very often to send other messages to other processes. The syntax for this message passing and handling is very tightly woven into the heart of the language.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.erlang.org/doc/reference_manual/expressions.html#send"&gt;syntax for dropping a message&lt;/a&gt; to another process looks like  &lt;br /&gt;&lt;pre&gt;NetlistenProcess ! terminateSignal&lt;br /&gt;&lt;/pre&gt;and the &lt;a href="http://www.erlang.org/doc/reference_manual/expressions.html#receive"&gt;syntax for receiving and reacting&lt;/a&gt; upon an incoming message looks like  &lt;br /&gt;&lt;pre&gt;receive&lt;br /&gt;    onhook -&amp;gt;&lt;br /&gt;        disconnect(),&lt;br /&gt;        idle();&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Looks familiar, does it not?&lt;br /&gt;&lt;br /&gt;Now, in Erlang both the exclamation mark (!) and "receive" are special forms in the language - syntax with a special meaning that unleashes some magic going on deep down in the runtime.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Seems not to far-fetched to assume same thing was going on in Scala.&lt;br /&gt;&lt;br /&gt;However, I was mistaken. In Scala actors are just plain old objects with perfectly normal method calls. It is not even special syntax involved.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;No Magic on the Outside&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now let us pick apart the "special syntax" for passing messages to see that there is actually no magic at all involved. We take a fresh look at the message-passing script.  &lt;br /&gt;&lt;pre&gt;object vladimirwaitandrun extends Application {&lt;br /&gt;    val vlad = new Vladimir(42)&lt;br /&gt;    vlad.start()&lt;br /&gt;    vlad ! Godot&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;We start with noting that Vladimir is in fact an object. It is an object that is instantiated from the class Vladimir and that object is referred to with the reference "vlad".  &lt;br /&gt;&lt;pre&gt;val vlad = new Vladimir(42)&lt;br /&gt;&lt;/pre&gt;Nothing magic here really.&lt;br /&gt;&lt;br /&gt;What makes "vlad" an actor is that the class Vladimir is a subclass of Scala actors.Actor.  &lt;br /&gt;&lt;pre&gt;class Vladimir(id : Int) extends actors.Actor {&lt;br /&gt;&lt;/pre&gt;This means that all the methods that are defined in actors.Actor are inherited to Vladimir, and thus are available to call using the reference "vlad". And one of those methods are named "!" (pronounced “bang”).&lt;br /&gt;&lt;br /&gt;As you are as curious as I am, we can even have a look at the definition of that method. We find it in ReplyReactor which is a trait that Actor makes use of.  &lt;br /&gt;&lt;pre&gt;override def !(msg: Any) {&lt;br /&gt;    send(msg, …)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So, “bang” is just a method, which we call on the actor to receive the message. We now realise that the strange syntax is just one way to write an ordinary method call.  &lt;br /&gt;&lt;pre&gt;vlad ! Godot&lt;br /&gt;&lt;/pre&gt;To make it totally obvious that this is just a method call, we can use the alternative syntax – the one that looks a little bit more familiar to people used to the syntax of C++/Java/C#.  &lt;br /&gt;&lt;pre&gt;vlad.!(Godot)&lt;br /&gt;&lt;/pre&gt;Oh, yes, that means exactly the same thing. It compiles and runs the same way.  &lt;br /&gt;&lt;pre&gt;danbj$ scala godot.vladimirwaitandrun&lt;br /&gt;Vladimir42 is waiting&lt;br /&gt;Vladimir42 saw Godot arrive! &lt;br /&gt;Vladimir42's wait is over &lt;br /&gt;&lt;/pre&gt;Now, I do agree that the exclamation mark feels like a weird method name. Now, remember that in ReplyReactor everything method “bang” did was to delegate to method “send”.  &lt;br /&gt;&lt;pre&gt;override def !(msg: Any) {&lt;br /&gt;    send(msg, …)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;To make things more “object-readable” we can inline the body of “bang” and use “send” instead. Only difference is that “send” takes another argument, but for the purpose of this discussion that does not make any difference – we can send in null there in this case.&lt;br /&gt;&lt;br /&gt;The “send” method in its turn is just an ordinary method. It takes the argument (the message) and stuffs it into the mailbox – which is just some kind of list. There the message will sit waiting for processing, but that is not anything that concerns the “send” method. In other words – it is a very ordinary method.&lt;br /&gt;&lt;br /&gt;There is no need to dig into details, but there is no magic going on.  Now we can change the script to use the alternative syntax and "send" as method.  &lt;br /&gt;&lt;pre&gt;object vladimirwaitandrun extends Application {&lt;br /&gt;    val vlad = new Vladimir(42)&lt;br /&gt;    vlad.start()&lt;br /&gt;    vlad.send(Godot, null);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now, this looks like plain use of an object, does it not? No magic, just a method call.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;No Magic on the Inside Either&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Now, on the inside of the actor we have the magic "act" method, which contains&lt;br /&gt;&lt;pre&gt;receive {&lt;br /&gt;    case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! " + threadid)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now, surely this must be some "special form" syntax with associated magic?&lt;br /&gt;&lt;br /&gt;To start with, there is nothing magic with the method "act". It is just a choice of name for the code where the actor has its code for "this is what you do". In a way, it is just like the "run" method in the Java interface "Runnable" - just a way to point out what code to run in a separate thread when the actor is started.&lt;br /&gt;&lt;br /&gt;When it comes to the recieve-block it turns out to be no magic there either.  In fact, "receive" is just a utility-method in the framework class "actors.Actor". Remember that we created the actor by letting the class Vladimir subclass "actors.Actor".  &lt;br /&gt;&lt;pre&gt;class Vladimir(id : Int) extends actors.Actor {&lt;br /&gt;&lt;/pre&gt;Thus our class Vladimir contains all the methods that are in Actor. And one of those methods is "receive". In the code-block it looks like "receive" is a keyword, but it is just a call to the method "receive" defined in the super-class. We can make this a little bit clearer by writing that explicitly.  &lt;br /&gt;&lt;pre&gt;this.receive {&lt;br /&gt;    case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! ")&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now the code-block with the case clause seems to be hanging into thin air. But it does not. According to the syntax of Scala it is the argument for the method. We can make that clearer by putting the argument inside parentheses.  &lt;br /&gt;&lt;pre&gt;this.receive ({&lt;br /&gt;    case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! ")&lt;br /&gt;})&lt;br /&gt;&lt;/pre&gt;Still looks a little bit weird?&lt;br /&gt;&lt;br /&gt;Well, remember that in Scala a function (like "sqr") is also a value. And, as such, it can be passed as an argument to a method (like the list-method "map" for example). Now, the code-block we see is just a function defined "in-line". We can make things a little bit less convoluted by giving that function a name through a "val"-declaration.  &lt;br /&gt;&lt;pre&gt;val messagehandler: PartialFunction[Any, Unit] = {&lt;br /&gt;    case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! ")&lt;br /&gt;}&lt;br /&gt;this.receive (messagehandler)&lt;br /&gt;&lt;/pre&gt;I agree that the type of “messagehandler” becomes pretty weird – those partial functions are not always trivial to wrap your head around. But the important point is that the “messagehandler” is just a Scala value.&lt;br /&gt;&lt;br /&gt;Let us revise the last line to have a look at what has happened to the “receive-block” that looked like a special form.  &lt;br /&gt;&lt;pre&gt;this.receive (messagehandler)&lt;br /&gt;&lt;/pre&gt;Viewed this way we see that "recieve" is just a method of the actor class. That method scans the mailbox for messages and does something when it finds a match. Now, to do this, the receive method must be told what to match and what to do about matches - an that is exactly what the (partial) method "messagehandler" does.&lt;br /&gt;&lt;br /&gt;So the “special form” suspect seems to be just an ordinary method call. Just to ensure there is no magic, let us&amp;nbsp;sketch&amp;nbsp;if we could implement it ourselves.&lt;br /&gt;&lt;br /&gt;Looping through the mailbox (a list) and searching for matches does not sound to complicated. Basically we just try to apply the message-handler and let it do its job. Of course there might be tricky corners, but there does not need to be any magic involved.&lt;br /&gt;&lt;br /&gt;The only remaining magic is what "receive" does when there is no match. In that case it waits until there arrives a message, and then it tries to match the message-handler onto the newly arrived message.&lt;br /&gt;&lt;br /&gt;Well, we can build even that part ourselves. If the mailbox is empty (or there are no matches) we can suspend the thread in a wait-state where we poll the mailbox at regular intervals. Even better, we can use the "notify" mechanism in the JVM where "receive" can call "mailbox.wait()" using the Java API. To wake up the thread we can let "send" (i e method "!") contain a "mailbox.notify()" so that the actor will resume its thread and rescan the mailbox.&lt;br /&gt;&lt;br /&gt;And, basically, this is what the "thread-based actors" do. It is just someone else that has written the code for us.&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;No Magic at All&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The syntax for sending messages ("!") and for receiving and reacting upon them "recieve {…}" looked like a lot of magic. However, it turned out that they where just ordinary methods defined on an ordinary class - the class "actors.Actor".&lt;br /&gt;&lt;br /&gt;This is what is meant when people say that "Scala actors is not a language feature, it is a library". In other words: Scala actors are just ordinary code. The only thing that is special with that code is that it is pre-packaged together with the Scala download. However, it has no special status over any code written by you and me.&lt;br /&gt;&lt;br /&gt;This design is actually very lucky for Scala. It has opened up for alternative actor frameworks to be written. The most prominent is Akka (champed by Jonas Bonér), and it has become so successful that the plan is to replace the standard actor library with Akka instead.&lt;br /&gt;&lt;br /&gt;Of course, Akka is not magical either. It is just code which is very well designed and written. But in principle it is not different from code that could have been written by you and me. No magic involved.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-8973900091449781305?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/8973900091449781305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/08/scala-actors-are-just-code-no-magic.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8973900091449781305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8973900091449781305'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/08/scala-actors-are-just-code-no-magic.html' title='Scala Actors are Just Code - No Magic'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-6015924342106667870</id><published>2011-05-27T13:20:00.000+02:00</published><updated>2011-05-27T13:20:18.459+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>How Heavy is Estragon - Event-Based Scala Actor</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;As we have seen thread-based actors are quite an intuitive model, but is not very efficient in conserving resources. Its main drawback is that each actor needs a thread each, and each thread will take some memory - about 60-70kB.&lt;br /&gt;&lt;br /&gt;Also, this amount of threads seem unnecessary as the thread is only used a potion of the time - so the threads could be pooled instead.&lt;br /&gt;&lt;br /&gt;So, let us create the Estragon version - an actor that drowses off and takes a nap whenever he is not actively needed. Thus the thread can be used by some other actor that wants to be active at the moment.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Estragon(id : Int) extends Actor {&lt;br /&gt;  def threadid = {&lt;br /&gt;    "T" + Thread.currentThread.getId&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def name: String = {&lt;br /&gt;    "Estragon" + id&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def act() = {&lt;br /&gt;    println(name + " is waiting " + threadid)&lt;br /&gt;    react {&lt;br /&gt;      case Godot =&gt;&lt;br /&gt;        println(name + " saw Godot arrive! " + threadid)&lt;br /&gt;    }&lt;br /&gt;    println(name + "'s wait is over " + threadid)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the code the difference from thread based Vladimir is really small - we use the method "react" instead of "receive". The rest of the API is the same: we subclass from Actor, we define an "act"-method. The only difference to get event-based actors (using a thread pool) instead of thread-based actors (having one thread each) is to switch from "receive" to "react".&lt;br /&gt;&lt;br /&gt;Simple? Yes, until we get into details and subtleties later.&lt;br /&gt;&lt;br /&gt;Now let's run the script for the play putting Estragon and Vladimir on stage and starting them.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object waitingforgodot extends Application {&lt;br /&gt;  println("Setting the stage " +&lt;br /&gt;    Thread.currentThread.getId)&lt;br /&gt;  val estragon = new Estragon(1)&lt;br /&gt;  val vladimir = new Vladimir(2)&lt;br /&gt;  println("Starting the play")&lt;br /&gt;  estragon.start&lt;br /&gt;  vladimir.start&lt;br /&gt;  println("Main script is over")&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage 1&lt;br /&gt;Starting the play&lt;br /&gt;Main script is over&lt;br /&gt;Estragon1 is waiting T10&lt;br /&gt;Vladimir2 is waiting T11&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well not very exiting. Both Vladimir and Estragon start and enters into waiting-state, waiting for Godot. Only difference is their respective ways of waiting. &lt;br /&gt;&lt;br /&gt;Vladimir keeps his thread, just putting it into a waiting state. Deep down under this is implemented through some "object.wait()". So whenever he gets out of his waiting state (when the message Godot finally arrive), the same thread can process the message-handler i e the receive-block.&lt;br /&gt;&lt;br /&gt;Estragon on the other hand discards his thread when going into "react". As he has no immediate use of the thread, it is given back to the pool to serve some other actor that need to run. So whenever Godot arrives to Estragon the message-handler will be activated and run by some thread, not necessarily the same as earlier. &lt;br /&gt;&lt;br /&gt;Nevertheless, the point is that when Estragon enters "react", the thread is no longer occupied but be used by other actors. So even if we have a lot of actors we still can manage with just a few threads.&lt;br /&gt;&lt;br /&gt;This becomes more obvious if we create lots of Estragons&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object estragongalore extends Application {&lt;br /&gt;  override def main(args: Array[String]) {&lt;br /&gt;    val actors = Integer.parseInt(args(0));&lt;br /&gt;    val ids = 0 until (actors)&lt;br /&gt;    val estragons = ids map (id =&gt; new Estragon(id))&lt;br /&gt;    println((actors) + " actors on stage")&lt;br /&gt;    for(estr &lt;- estragons) { estr.start() }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;scala godot.estragongalore 10&lt;br /&gt;10 actors on stage&lt;br /&gt;Estragon0 is waiting T10&lt;br /&gt;Estragon1 is waiting T11&lt;br /&gt;Estragon3 is waiting T12&lt;br /&gt;Estragon2 is waiting T13&lt;br /&gt;Estragon5 is waiting T10&lt;br /&gt;Estragon7 is waiting T10&lt;br /&gt;Estragon8 is waiting T10&lt;br /&gt;Estragon9 is waiting T10&lt;br /&gt;Estragon6 is waiting T11&lt;br /&gt;Estragon4 is waiting T12&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;Estragon 0, 1, 2, and 3 where started in separate threads. But, the next actor to start (Estragon5) could use thread T10 that had been used by Estragon0 and returned to the pool. So to create 10 actors we only needed four actor threads.That should conserve a lot of resources.Remembering that my poor laptop cringed when we put 2500 Vladimirs on stage? Let us see how many Estragon we can put on stage. It ought to be more as this model reuses the threads. What about 10 000 actors?&lt;pre&gt;danbj$ scala godot.estragongalore 10000 &lt;br /&gt;10000 actors on stage&lt;br /&gt;Estragon3 is waiting T12&lt;br /&gt;Estragon2 is waiting T13&lt;br /&gt;Estragon0 is waiting T10&lt;br /&gt;Estragon1 is waiting T11&lt;br /&gt;Estragon4 is waiting T11&lt;br /&gt;…&lt;br /&gt;Estragon9998 is waiting T12&lt;br /&gt;Estragon9935 is waiting T11&lt;br /&gt;Estragon9989 is waiting T13&lt;br /&gt;Estragon9956 is waiting T10&lt;br /&gt;Estragon9999 is waiting T12&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;10 000? No problem. Let us tenfold that.&lt;pre&gt;danbj$ scala godot.estragongalore 100000 &lt;br /&gt;100000 actors on stage&lt;br /&gt;Estragon0 is waiting T10&lt;br /&gt;Estragon3 is waiting T13&lt;br /&gt;Estragon2 is waiting T12&lt;br /&gt;…&lt;br /&gt;Estragon99991 is waiting T10&lt;br /&gt;Estragon99999 is waiting T11&lt;br /&gt;Estragon99998 is waiting T12&lt;br /&gt;Estragon99996 is waiting T13&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;100 000 worked fine. What about a million actors on stage?&lt;pre&gt;danbj$ scala godot.estragongalore 1000000 &lt;br /&gt;1000000 actors on stage&lt;br /&gt;Estragon1 is waiting T13&lt;br /&gt;Estragon0 is waiting T10&lt;br /&gt;Estragon3 is waiting T12&lt;br /&gt;…&lt;br /&gt;Estragon163350 is waiting T10&lt;br /&gt;Estragon163351 is waiting T10&lt;br /&gt;Estragon163352 is waiting T10&lt;br /&gt;java.lang.OutOfMemoryError: Java heap space&lt;br /&gt; at scala.concurrent.forkjoin.LinkedTransferQueue.xfer(LinkedTransferQueue.java:187)&lt;br /&gt; at ...&lt;br /&gt; at scala.actors.Scheduler$.execute(Scheduler.scala:21)&lt;br /&gt; at scala.actors.Reactor$class.dostart(Reactor.scala:222)&lt;br /&gt; at ...&lt;br /&gt; at godot.Estragon.start(waitingforgodot.scala:42)&lt;br /&gt; at ...&lt;br /&gt;&lt;/pre&gt;At last we got an OutOfMemoryError. This time we did not get it when trying to start a new thread, but somewhere in the scheduler instead.It turns out that 900 000 actors is just short of what a 256M heap can handle.&lt;pre&gt;danbj$ scala godot.estragongalore 900000&lt;br /&gt;900000 actors on stage&lt;br /&gt;Estragon0 is waiting T11&lt;br /&gt;Estragon2 is waiting T10&lt;br /&gt;…&lt;br /&gt;&lt;br /&gt;danbj$ ps -m -O rss&lt;br /&gt;  PID    RSS   TT  STAT      TIME COMMAND&lt;br /&gt;18186 345524 s001  S+     0:37.07 /usr/bin/java -Xmx256M …&lt;br /&gt;&lt;/pre&gt;RSS is "real memory" in kB and we note again that the scala startup script restricts heap to 256M per default. Let us plot memory use for some different number of actors.&lt;pre&gt;actors    RSS&lt;br /&gt;     1    61516&lt;br /&gt;  1000    62044&lt;br /&gt;  2500    61460&lt;br /&gt; 10000   71452&lt;br /&gt;100000  101588&lt;br /&gt;900000  345524&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So memory consumption is roughly 60MB in startup and 3kB per actor. That is a lot better than 60kB per actor for thread-based. &lt;br /&gt;&lt;br /&gt;That is pretty good. Now we can structure our systems using a lot of actors because the "overhead payload" of using an actor is not overwhelming. This is by the way an area where the framework Akka excels.&lt;br /&gt;&lt;br /&gt;In short: switching from thread-based actors to event-based actors is not more complicated than changing from "receive" to "react". Not at a syntactic code level at least. &lt;br /&gt;&lt;br /&gt;However, we also change execution model. We are no longer guaranteed that our actor is run by the same thread. In fact, the thread that registers the  message-handler by running "react" might not be the same thread that later runs the message-handler itself. And that might give us a clue to Estragon's bad memory. But that will have to wait for another letter.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;   Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-6015924342106667870?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/6015924342106667870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/05/how-heavy-is-estragon-event-based-scala.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6015924342106667870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6015924342106667870'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/05/how-heavy-is-estragon-event-based-scala.html' title='How Heavy is Estragon - Event-Based Scala Actor'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-4611175349425898520</id><published>2011-05-18T10:14:00.054+02:00</published><updated>2011-05-19T08:24:22.404+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NFR'/><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Vladimir Galore - Lots of Threaded Scala Actors Waiting for Godot</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;When we discussed the model for programming actors in Scala we saw that the &lt;a href="http://dearjunior.blogspot.com/2011/05/scala-actor-waiting-for-godot-vladimir.html"&gt;thread-based model&lt;/a&gt; could be compared to the very actively waiting character  &lt;a href="http://en.wikipedia.org/wiki/Vladimir_(Waiting_for_Godot)"&gt;Vladimir&lt;/a&gt; of &lt;a href="http://en.wikipedia.org/wiki/Waiting_for_Godot"&gt;Waiting for Godot&lt;/a&gt;. I also mentioned that the more drowsy, laid-back Estragon of the same play could be a good picture of the other model, the event-based.&lt;br /&gt;&lt;br /&gt;However, before proceeding to the event-based actors, I think it enlightening to dive a bit more into the thread-based and see what the problem is.&lt;br /&gt;&lt;br /&gt;The point of actor-based programming is that you want to mimic a "society of collaboration" where each actor performs a focused task. And you do not just want one actor per function (or type of task), you actually want one actor per task. So you want a lot of them.&lt;br /&gt;&lt;br /&gt;This is similar to object orientation - you do not want one object per class (e g representing phone numbers), you want one object per instance of the class (one for each phone number). Actually, it can be claimed that the restricted actor-message model is closer to the original ideas of object orientation than the object-method model we have become accustomed to.&lt;br /&gt;&lt;br /&gt;So we really want loads of actors. Let us see how many Vladimirs we can create before my poor laptop cringes.&lt;br /&gt;&lt;br /&gt;Let us revise the code for Vladimir in his waiting for Godot. As we will create a lot of Vladimirs I have given each an id.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Vladimir(id : Int) extends Actor {&lt;br /&gt;  def threadid = {&lt;br /&gt;    Thread.currentThread.getId&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def name: String = {&lt;br /&gt;    "Vladimir" + id&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def act() = {&lt;br /&gt;    println(name + " is waiting " + threadid)&lt;br /&gt;    receive {&lt;br /&gt;      case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! " + threadid)&lt;br /&gt;    }&lt;br /&gt;    println(name + "'s wait is over " + threadid)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case class Godot&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we also need to create loads of them. Let us make a list of integers and turn each of them into an instance of Vladimir.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object vladimirgalore extends Application {&lt;br /&gt;  override def main(args: Array[String]) {&lt;br /&gt;    val actors = Integer.parseInt(args(0));&lt;br /&gt;    val ids = 0 until actors // [0,1,2 ...]&lt;/pre&gt;&lt;pre&gt;// turn each int to an actor using the int as id&lt;br /&gt;    val vladimirs = ids map (id =&amp;gt; new Vladimir(id))&lt;br /&gt;    println(actors + " actors on stage")&lt;br /&gt;    for(vlad &amp;lt;- vladimirs) { vlad.start }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;scala godot.vladimirgalore 6&lt;br /&gt;6 actors on stage&lt;br /&gt;Vladimir2 is waiting 12&lt;br /&gt;Vladimir0 is waiting 10&lt;br /&gt;Vladimir1 is waiting 11&lt;br /&gt;Vladimir3 is waiting 13&lt;br /&gt;Vladimir4 is waiting 17&lt;br /&gt;Vladimir5 is waiting 18&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Never mind the order of the output - actors are threads and are thus entitled to run scheduled in any order. What we see is six actors, each an instance of Vladimir, and each given a thread of its own. And every one of them are in a wait-state waiting for the message "Godot".  Let us relieve one of them from its wait, just to see one completion. Let us send Vladimir4 the happy message of Godot's arrival.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object vladimirgalore extends Application {&lt;br /&gt;  override def main(args: Array[String]) {&lt;br /&gt;    val actors = Integer.parseInt(args(0));&lt;br /&gt;    val ids = 0 until (actors)&lt;br /&gt;    val vladimirs = ids map (id =&amp;gt; new Vladimir(id))&lt;br /&gt;    println(actors + " actors on stage")&lt;br /&gt;    for(vlad &amp;lt;- vladimirs) { vlad.start }&lt;br /&gt;    vladimirs(4) ! Godot&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;danbj$ scala godot.vladimirgalore 6&lt;br /&gt;6 actors on stage&lt;br /&gt;Vladimir1 is waiting 11&lt;br /&gt;Vladimir2 is waiting 12&lt;br /&gt;Vladimir3 is waiting 13&lt;br /&gt;Vladimir0 is waiting 10&lt;br /&gt;Vladimir4 is waiting 17&lt;br /&gt;Vladimir4 saw Godot arrive! 17&lt;br /&gt;Vladimir4's wait is over 17&lt;br /&gt;Vladimir5 is waiting 17&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ahaa. Vladimir 4 was started with thread 17 - which used "receive" to register the message handler (the code block containing the "case"). It was also thread 17 that later executed the message handler, doing the pattern matching of the case and running the corresponding code for "case Godot". Finally it was thread 17 that continued the code after the handler-block. Same thread all the way - that is why they are called thread-based. They do not only behave as if they where a thread, they are actually implemented using the same thread all the time.&lt;br /&gt;&lt;br /&gt;Accidentially, thread 17 managed to complete the act-method of Vladimir4 so that specific thread could be reused for Vladimir5. However, in all other cases, a new fresh thread was required.&lt;br /&gt;&lt;br /&gt;Now let us put loads of actors on stage. For clarity we remove the release of Vladimir 4 so that every actor will be waiting and all threads be locked up.&lt;br /&gt;&lt;br /&gt;Let us see if we can put 1000 Vladimirs on stage and set them acting.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;object vladimirgalore extends Application {&lt;br /&gt;  override def main(args: Array[String]) {&lt;br /&gt;    val actors = Integer.parseInt(args(0));&lt;br /&gt;    val ids = 0 until (actors)&lt;br /&gt;    val vladimirs = ids map (id =&amp;gt; new Vladimir(id))&lt;br /&gt;    println(actors + " actors on stage")&lt;br /&gt;    for(vlad &amp;lt;- vladimirs) { vlad.start }&lt;br /&gt;    // vladimirs(4) ! Godot&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;danbj$ scala godot.vladimirgalore 1000&lt;br /&gt;1000 actors on stage&lt;br /&gt;Vladimir0 is waiting 10&lt;br /&gt;Vladimir3 is waiting 13&lt;br /&gt;Vladimir2 is waiting 12&lt;br /&gt;Vladimir1 is waiting 11&lt;br /&gt;Vladimir4 is waiting 16&lt;br /&gt;Vladimir5 is waiting 17&lt;br /&gt;…&lt;br /&gt;Vladimir115 is waiting 128&lt;br /&gt;Vladimir116 is waiting 129&lt;br /&gt;Vladimir117 is waiting 130&lt;br /&gt;Vladimir118 is waiting 131&lt;br /&gt;Vladimir119 is waiting 132&lt;br /&gt;…&lt;br /&gt;Vladimir251 is waiting 264&lt;br /&gt;Vladimir252 is waiting 265&lt;br /&gt;Vladimir253 is waiting 266&lt;br /&gt;Vladimir254 is waiting 267&lt;br /&gt;Vladimir255 is waiting 268&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, the system hangs on Vladimir255 even though it has not yet started all the 1000 actors I asked for.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Hmm … "Vladimir0" to Vladimir255" - that is 256 actors that have been started before the system hangs. Such a number is hardly a coincidence …  Here my colleague George Spalding came to the rescue by pointing out the relevant JVM properties, in this case "actors.maxPoolSize  (default 256)". So, as I understand it Scala will not allow the JVM to allocate more than 256 threads for actor stuff. This means that when 256 Vladimirs had been started, then all 256 threads where sitting waiting for receiving Godot.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;receive {&lt;br /&gt;      case Godot =&amp;gt;&lt;br /&gt;        println(name + " saw Godot arrive! " + threadid)&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And if the runtime-system refuse to allocate more threads, then no more actors will be started.&lt;br /&gt;&lt;br /&gt;Let us run it again, with modified properties, increasing the maximum number of actor threads.&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;scala -Dactors.maxPoolSize=10000 godot.vladimirgalore 1000&lt;br /&gt;1000 actors on stage&lt;br /&gt;Vladimir0 is waiting 10&lt;br /&gt;Vladimir3 is waiting 13&lt;br /&gt;Vladimir2 is waiting 12&lt;br /&gt;Vladimir1 is waiting 11&lt;br /&gt;Vladimir4 is waiting 16&lt;br /&gt;Vladimir5 is waiting 18&lt;br /&gt;…&lt;br /&gt;Vladimir997 is waiting 1010&lt;br /&gt;Vladimir998 is waiting 1011&lt;br /&gt;Vladimir999 is waiting 1012&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ok now it worked… what about 2500?  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;danbj$ scala -Dactors.maxPoolSize=10000 godot.vladimirgalore 2500&lt;br /&gt;2500 actors on stage&lt;br /&gt;Vladimir0 is waiting 10&lt;br /&gt;Vladimir3 is waiting 13&lt;br /&gt;…&lt;br /&gt;Vladimir2498 is waiting 2511&lt;br /&gt;Vladimir2499 is waiting 2512&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Seems to work … and 5000?  &lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;danbj$ scala -Dactors.maxPoolSize=10000 godot.vladimirgalor 5000&lt;br /&gt;...&lt;br /&gt;Vladimir2538 is waiting 2552&lt;br /&gt;Vladimir2539 is waiting 2553&lt;br /&gt;godot.Vladimir@35a631cc: caught java.lang.OutOfMemoryError: unable to create new native thread&lt;br /&gt;java.lang.OutOfMemoryError: unable to create new native thread&lt;br /&gt; at java.lang.Thread.start0(Native Method)&lt;br /&gt; at java.lang.Thread.start(Thread.java:658)&lt;br /&gt; at scala.concurrent.forkjoin.ForkJoinPool.createAndStartSpare(ForkJoinPool.java:1609)&lt;br /&gt; at ...&lt;br /&gt; at scala.actors.Scheduler$.managedBlock(Scheduler.scala:21)&lt;br /&gt; at scala.actors.Actor$class.receive(Actor.scala:512)&lt;br /&gt; at godot.Vladimir.receive(waitingforgodot.scala:38)&lt;br /&gt; at godot.Vladimir.act(waitingforgodot.scala:49)&lt;br /&gt; at ...&lt;br /&gt; at scala.actors.ReactorTask.run(ReactorTask.scala:36)&lt;br /&gt; at ...&lt;br /&gt; at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)&lt;br /&gt; at ...&lt;br /&gt;Vladimir2540 is waiting 2553&lt;br /&gt;^C&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nope it crashed.&lt;br /&gt;&lt;br /&gt;But … systems always reveals interesting information when breaking down.&lt;br /&gt;&lt;br /&gt;In this case it was the scala.actors.Scheduler that tried to start a new Thread in order to serve the Vladimir "receive" inside its act-method. And creating this "new native thread" was too much load for the JVM that crashed with OutOfMemoryError.&lt;br /&gt;&lt;br /&gt;Let us run this once again, just below the limit where it crashes.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;danbj$ scala -Dactors.maxPoolSize=10000 godot.vladimirgalor 2539&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and have a look at process status  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;danbj$ ps -m -O rss&lt;br /&gt;  PID    RSS   TT  STAT      TIME COMMAND&lt;br /&gt; 8164 264280 s001  R+     0:06.80 /usr/bin/java -Xmx256M …&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;OK, "RSS" stands for "resident set state" and is basically "real memory". So, memory use is 264280 kB. Also note that the scala runtime has set the JVM "maximum heap size" (Xmx) to 256M. These two numbers are strikingly close to each other. My conclusion is that it seems to be the allocated heap that has filled up.&lt;br /&gt;&lt;br /&gt;This does makes sense, a few thousand threads will need one allocated stack each, and that will eat the available space pretty quickly.   Trying out with different number of actors give us some data on how much stack is needed per actor.   &lt;br /&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;actors    RSS (in kB)&lt;br /&gt;    1    62752&lt;br /&gt;  500    95676&lt;br /&gt; 1000   134132&lt;br /&gt; 2500   239248&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, apart from that the system needs 62M just to start, every Vladimir (thread-based actor) seems to need just below 70k each. That is not very slim, not if we want to create truckloads of actors.&lt;br /&gt;&lt;br /&gt;Obviously, the thread based actors have their advantage in being pretty easy to understand. But they definitely have their drawback in eating system resources by asking for one thread and a stack allocation each.&lt;br /&gt;&lt;br /&gt;But, hey … in our benchmark all the threads where in wait-state. Could they not have been pooled in some way? We could have gotten away with just a few threads, and we would have been able to create many more actors!&lt;br /&gt;&lt;br /&gt;Sure we could, and that is exactly what event-based actors do. Instead of being on their feet like Vladimir, we want them to drowse off and take a nap like Estragon. And in the mean-while the thread could be used by some other actor that has something in its inbox it wants to process. Unfortunately, they will also loose a little bit of their sense of time like him. But that will have to wait to another letter.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-4611175349425898520?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/4611175349425898520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/05/vladimir-galore-lots-of-threaded-scala.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4611175349425898520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4611175349425898520'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/05/vladimir-galore-lots-of-threaded-scala.html' title='Vladimir Galore - Lots of Threaded Scala Actors Waiting for Godot'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-5695274142871859095</id><published>2011-05-16T10:20:00.005+02:00</published><updated>2011-05-18T16:01:38.371+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='actors'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala Actor Waiting for Godot - Vladimir Thread Version</title><content type='html'>Dear Junior&lt;br /&gt;&lt;br /&gt;My collegue Roozbeh Maadani and I where curious about the different actor models of Scala so we decided to &lt;a href="http://opkoko11.blogspot.com/2011/04/live-scala-bortom-basics.html"&gt;try them out&lt;/a&gt;. I have also had a distant interest in Akka for a while, an interest re-vigored by &lt;a href="http://www.jfokus.se/jfokus11/preso/jf11_AkkaSimplerScalabilityFaultToleranceConcurrency.pdf"&gt;Jonas Bonér's presentation at Jfokus&lt;/a&gt;, and deepened by attending his mini-course on Akka at &lt;a href="http://bit.ly/opkoko11-schema"&gt;OP-KoKo&lt;/a&gt;. So, I have been toying around with &lt;a href="http://akka.io/"&gt;Akka&lt;/a&gt; a little as well. I will get back to that.&lt;br /&gt;&lt;br /&gt;Let us get started and create an application with some actors - in this case an reenactment of Waiting for Godot. The basic plot of Waiting for Godot is roughly two characters, Vladimir and Estragon, waiting for a person named Godot to show up - which he does not. So let us start with the setup.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object waitingforgodot extends Application {&lt;br /&gt;  println("Setting the stage")&lt;br /&gt;  val vladimir = new Vladimir&lt;br /&gt;  val estragon = new Estragon&lt;br /&gt;}&lt;br /&gt;class Estragon extends Actor {&lt;br /&gt;  // here we will later read Estragon's script&lt;br /&gt;  def act() = null&lt;br /&gt;}&lt;br /&gt;class Vladimir extends Actor {&lt;br /&gt;  def act() = null&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In the application script we create two actor objects, one "Vladimir" and one "Estragon", defined by one class each. When started (which they are not yet), they will run their respective scripts which is defined in their act()-method. Agreeably neither of them have much of a script to follow yet.&lt;br /&gt;&lt;br /&gt;Nevertheless, we can run the application, even though the result is not very thrilling:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage&lt;/pre&gt;&lt;br /&gt;Time to give one of the actors some script to follow. Let us start with Vladimir.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Vladimir extends Actor {&lt;br /&gt;   def act() = {&lt;br /&gt;      println("Vladimir is waiting")&lt;br /&gt;      // ... stuff happen&lt;br /&gt;      println("Vladimir's wait is over")&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Running the app still gives&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage&lt;/pre&gt;&lt;br /&gt;Obviously, the script for Vladimir is not executed. This is because in the Scala "actors.Actor" API the basic metaphor is that an actor is a thread (conceptually). It is not necessarily implemented that way, but the API keeps the mental model as close to thread as possible. Thus, we need to start it.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object waitingforgodot extends Application {&lt;br /&gt;   println("Setting the stage")&lt;br /&gt;   val vladimir = new Vladimir&lt;br /&gt;   val estragon = new Estragon&lt;br /&gt;   println("Starting the play")&lt;br /&gt;   vladimir.start&lt;br /&gt;   estragon.start&lt;br /&gt;   println("Main script is over")&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now we see the actor Vladimir acting his part as well&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage&lt;br /&gt;Starting the play&lt;br /&gt;Main script is over&lt;br /&gt;Vladimir is waiting&lt;br /&gt;Vladimir's wait is over&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the Vladimir script is actually running even after  the main script is over. This is explain by "vladimir.start" is actually starting a new thread which keeps running even after the original main-thread has finished. &lt;br /&gt;&lt;br /&gt;This becomes even more obvious if we add some thread information to our printlns.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object waitingforgodot extends Application {&lt;br /&gt;   println("Setting the stage " + Thread.currentThread.getId)&lt;br /&gt;   val vladimir = new Vladimir&lt;br /&gt;   val estragon = new Estragon&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Vladimir extends Actor {&lt;br /&gt;   def act() = {&lt;br /&gt;      println("Vladimir is waiting " + &lt;br /&gt;         Thread.currentThread.getId)&lt;br /&gt;      println("Vladimir's wait is over " + &lt;br /&gt;         Thread.currentThread.getId)&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Which yields &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage 1&lt;br /&gt;Starting the play&lt;br /&gt;Main script is over&lt;br /&gt;Vladimir is waiting 10&lt;br /&gt;Vladimir's wait is over 10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Main script is run by thread 1 and character Vladimir is run by thread 10. Curiously this actually apply to the play itself. In the play Vladimir is the only one who have a clear sense of time: he remembers the past (which the other characters does not, at least not very well), and he has an idea of the future to come.&lt;br /&gt;&lt;br /&gt;Now let's get over to the point of the play, which is waiting for a specific person named Godot. Vladimir's script is extended by a "wait for Godot to arrive". The actor representation of this is to send a message to the actor Vladimir, a message consisting of "Godot". &lt;br /&gt;&lt;br /&gt;Vladimir on his part must wait for this message to arrive in his "inbox". He does so by using "receive" and a message handler. Using "recieve" makes the actor to check its mailbox and act upon the messages it finds. The "message handler" is simply a codeblock that tells what to do with messages.&lt;br /&gt;&lt;br /&gt;If there is no message in the inbox when the actor gets to "recieve", then the actor blocks and waits for a message to arrive.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Vladimir extends Actor {&lt;br /&gt;   def threadid = {&lt;br /&gt;      Thread.currentThread.getId&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   def act() = {&lt;br /&gt;      println("Vladimir is waiting " + threadid)&lt;br /&gt;      receive {&lt;br /&gt;         case Godot =&amp;gt;&lt;br /&gt;            println("Vladimir saw Godot arrive! " + threadid)&lt;br /&gt;      }&lt;br /&gt;      println("Vladimir's wait is over " + threadid)&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In this code "receive" causes the thread to be put in a waiting-state and watch the actor's "inbox". The "inbox" is the way to communicate with an actor. You should neither access its data, nor should you call methods on the object directly. Instead you send "messages" to it, which it will receive and react upon. I think of it like corresponding with mail.&lt;br /&gt;&lt;br /&gt;So, whenever a message arrive, the actor will run its message handler to see what it should do about it. The message handler in this case is the code-block following "receive"&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;receive {&lt;br /&gt;   case Godot =&amp;gt;&lt;br /&gt;      println("Vladimir saw Godot arrive! " + threadid)&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;So, if there is a message that matches the value "Godot", then it will be handled by running the code &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;println("Vladimir saw Godot arrive! " + threadid)&lt;/pre&gt;&lt;br /&gt;Let us ponder this for a while. The actor support in Scala is a library, not a part of the system. So "receive" is not a reserved word in the language, it is the name of a method of the Actor class (which we subclass). So, what actually is happening is that we execute the receive-method and pass in a code-block as the argument, the message handler. &lt;br /&gt;&lt;br /&gt;So another way to phrase it is that we use "receive" to register a message-handler with the actor runtime (i e the thread). As the message-handler is passed as a parameter it will sit on the top of the stack. And there the processing stops (the thread goes to sleep). &lt;br /&gt;&lt;br /&gt;At a later point of time (when there is message in the inbox), the processing will be resumed (by the same thread). Now, the message-handler is still there on the top of the stack so we can run it, do the case-pattern-matching, select the "println(...)" and execute it. Thereafter, the thread pops out of the "recieve {...}" and continue with the rest of the program. &lt;br /&gt;&lt;br /&gt;So, the entire "receive, wait for message, pattern-match, run message handler" was just a slow subroutine call.&lt;br /&gt;&lt;br /&gt;Now over to the message.&lt;br /&gt;&lt;br /&gt;We have one piece missing: who (or what) is Godot?&lt;br /&gt;&lt;br /&gt;In this example Godot is a simple value. There is no need to make it an actor, because it does not play any active part in the program. Actually, in the play there is no character Godot on stage at any time - he simply never shows up. So casting the Godot part is easy - there is no actor needed. &lt;br /&gt;&lt;br /&gt;Thus we can represent Godot with a value object defined by a case class&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;case class Godot&lt;/pre&gt;&lt;br /&gt;Yepp, that is all that is needed to define a message.&lt;br /&gt;&lt;br /&gt;This defines a class Godot which contains exactly one object: Godot (a little bit like an enum would). As there is no mutable state, this object can safely be shared by anyone interested in Godot, in the same way as there only need to be one integer 4711 or one string "fubar".&lt;br /&gt;&lt;br /&gt;The main advantage of case classes is that they can be used for pattern matching, which is necessary if we want to receive them as messages the way we did.&lt;br /&gt;&lt;br /&gt;Now let us run this.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage 1&lt;br /&gt;Starting the play&lt;br /&gt;Main script is over&lt;br /&gt;Vladimir is waiting 10&lt;br /&gt;^C&lt;/pre&gt;&lt;br /&gt;This time I had to kill the process as there was one thread that had not finished. Thread 10 was still active running the Vladimir actor and fully occupied waiting for Godot. I e it was hanging in "receive" but as it never got "Godot" it kept hanging there.&lt;br /&gt;&lt;br /&gt;This is by the way also a parallel to the play. In the play Vladimir is very energetic, at least compared to Estragon who also waits for Godot. Vladimir is on his feet all the time during the play, whereas Estragon often sits down and even takes a nap. Obviously, Estragon's strategy conserves resources better, but let us not hold that against Vladimir right now.&lt;br /&gt;&lt;br /&gt;In the play, Godot never show up, but let us be nice to poor Vladimir just for a moment and send him a Godot to his inbox.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;object waitingforgodot extends Application {&lt;br /&gt;   println("Setting the stage " + Thread.currentThread.getId)&lt;br /&gt;   val vladimir = new Vladimir&lt;br /&gt;   val estragon = new Estragon&lt;br /&gt;   println("Starting the play")&lt;br /&gt;   vladimir.start&lt;br /&gt;   estragon.start&lt;br /&gt;   println("Let Godot arrive")&lt;br /&gt;   vladimir ! Godot&lt;br /&gt;   println("Main script is over")&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Here we use the "!" (pronounced "bang") syntax for putting a message into the inbox of the actor referred by "vladimir". &lt;br /&gt;&lt;br /&gt;This will wake vladimir from its recieve-wait-state.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;receive {&lt;br /&gt;   case Godot =&amp;gt;&lt;br /&gt;      println("Vladimir saw Godot arrive! " + threadid)&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now that actor is reactivated, it will pattern-match the "case" clauses (only one in this example) in the handler and run the corresponding code.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;danbj$ scala godot.waitingforgodot&lt;br /&gt;Setting the stage 1&lt;br /&gt;Starting the play&lt;br /&gt;Let Godot arrive&lt;br /&gt;Vladimir is waiting 11&lt;br /&gt;Main script is over&lt;br /&gt;Vladimir saw Godot arrive! 11&lt;br /&gt;Vladimir's wait is over 11 &lt;/pre&gt;&lt;br /&gt;This time I did not need to kill the process as the Vladimir thread had a chance to finish its execution.&lt;br /&gt;&lt;br /&gt;Note also that messages are sent asynchronously so there is no guarantee that message handling is done immediately after message is sent. On the contrary, things can happen in apparently random order. In this case, the Godot-message is sent before Vladimir had stated running, and the main script interleaves with the Vladimir script. Of course your code should not rely on any specific order of execution.&lt;br /&gt;&lt;br /&gt;In this run some significant things happen from a message passing perspective&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"Let Godot arrive" (by thread 1)- here a message is sent to (and put in) Vladimir's inbox&lt;/li&gt;&lt;li&gt;"Vladimir is waiting" (by thread 11) - Vladimir enters the "receive", pushes the message-handler on the stack, and goes into thread wait&lt;/li&gt;&lt;li&gt;"Vladimir saw Godot arrive!" (by thread 11) - the actor runtime (the same thread) realises that there is a message in the inbox; it wakes up and run through the pattern-matching; it finds that the value Godot matches the case Godot and run the corresponding code.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A drawback with this Vladimir design is that each actor needs to have its own thread. The thread will be in wait-state when there is no message processing going on, so no CPU will be wasted. However, the number of threads a system can handle is quite limited so dedicating threads to waiting actors is pretty wasteful. However, that is &lt;a href="http://dearjunior.blogspot.com/2011/05/vladimir-galore-lots-of-threaded-scala.html"&gt;a letter in its own right&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In contrast to Vladimir who is on his feet the entire play we have the other character, Estragon. As I mentioned, Estragon is more laid back; he sits down and occasionally takes a nap. We will see that he is a pretty good picture of the other actor execution model, the event-based. But that will also need to be the subject of another letter. And, then we want to cover Akka as well ....&lt;br /&gt;&lt;br /&gt;Nevertheless, the thread-based actor model that Vladimir represents is a pretty good starting point for understanding actors, message passing, and message-handling execution.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-5695274142871859095?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/5695274142871859095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/05/scala-actor-waiting-for-godot-vladimir.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5695274142871859095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5695274142871859095'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/05/scala-actor-waiting-for-godot-vladimir.html' title='Scala Actor Waiting for Godot - Vladimir Thread Version'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-559078727577834549</id><published>2011-03-03T16:24:00.009+01:00</published><updated>2011-05-16T22:56:20.381+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='value object'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='unit test'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Getting Started with JUnit and TDD in Scala</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;As I like the flow of test driven development, it was natural to me to try TDD when starting using Scala. As Scala runs on the JVM and interoperates well with Java it should be easy to just use JUnit. However, it was not totally obvious how to do it, and looking around the net I found no "start from scratch, this is how to do it"-tutorial. Anyway, this is how I did it, starting from scratch.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;A First Test - without JUnit&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let's start with writing a test for the now-classical Money-example. Using my IDE at hand (IntelliJ), I created a file 'MoneyTest.scala' and wrote the test checking that one swedish krona is one swedish krona.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class MoneyTest {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;def should_equal_same_amount_same_currency = {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;new Money("SEK", 1) == new Money("SEK", 1)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us pick this apart. This is a class (MoneyTest) that can be used to create instances of that class. Such an instance ("a MoneyTest") is in other words "an object that can test properties of Money". One of the properties it can test is that Money "should equal same amount same currency". Testing the property is done by running the method.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;We have not yet got JUnit in the loop, but this is the anatomy of a unit test in place.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Get it to Compile&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To get the test through the compiler we need a Money class as well, which will reside in Money.scala.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Money(currency : String, amount : Int) {}&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yepp, that's it - class declaration and constructor rolled together.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now we are in shape having our first unit test and enough implementation to satisfy the compiler. Time to run the test. If we want to we can run it on the interactive read-eval-print-loop (REPL).&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;scala&amp;amp;gt; new MoneyTest().should_equal_same_amount_same_currency&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;res0: Boolean = &lt;b&gt;false&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Well, this is actually a failing unit test, giving us the permission to hack away.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Taking the Red Test to JUnit&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;However, I have come to be used to&amp;nbsp;JUnit - I like the assert methods, I like how it integrates with my IDE, I like how it integrates with build servers.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, I would like to pimp up this pretty naked unit test to make use of JUnit.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;First step was to add JUnit to the Scala project. In IntelliJ I created a new "External Library" named "junit" to which I added&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;junit-4.4.jar - I happened to find it in ~/.m2/repository/junit/junit/4.4/junit-4.4.jar. Then I added the new external library to the project.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Next step is the code. As JUnit is now on the classpath, &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I can do the imports, annotations, and use the methods I am used to (albeit the import will be Scala-scented).&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;b&gt;import org.junit.Test&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;b&gt;import org.junit.Assert._&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class MoneyTest {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;@Test&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;def should_equal_same_amount_same_currency = {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;assertTrue&lt;/b&gt;(new Money("SEK", 1) == new Money("SEK", 1))&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;Looks familiar, doesn't it? Now I can run it from within IntelliJ like any JUnit-test. Running it gives another familiar message:&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;java.lang.AssertionError:&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at org.junit.Assert.fail(Assert.java:74)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at org.junit.Assert.assertTrue(Assert.java:37)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at org.junit.Assert.assertTrue(Assert.java:46)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at MoneyTest.should_equal_same_amount_same_currency(MoneyTest.scala:10)&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;...&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Well, using assertTrue never gave helpful error messages. Let's do better.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Using JUnit&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us change the assert and use assertEquals instead. This works fine as the mother-class in Scala (named AnyRef) is nothing but "java.lang.Object" so there will be an equals method around.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To be precise, there is actually a class above "AnyRef" named "Any" which include the immutable value-types in Scala that parallel the Java primitives. But that distinction does not matter here.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Changing the code to use assertEquals we get:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;@Test&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;def should_equal_same_amount_same_currency = {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;assertEquals&lt;/b&gt;(new Money("SEK", 1), new Money("SEK", 1))&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This lands me with the error message:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;java.lang.AssertionError: expected:&amp;lt;&lt;b&gt;Money@348bdcd2&lt;/b&gt;&amp;gt; but was:&amp;lt;&lt;b&gt;Money@4a4e79f1&lt;/b&gt;&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at ...&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at MoneyTest.should_equal_same_amount_same_currency(MoneyTest.scala:10)&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;OK, two Money instances with different hashcodes are obviously not considered equal, even though their data are the same. This might be what we want for entities or domain events, but not for value objects such as Money.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;However &amp;nbsp;the error message looks kind of obscure due to the default toString.&amp;nbsp;Let us add a custom toString to get readable messages in the future.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;class Money(currency : String, amount : Int) {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;override def toString() : String = currency + " " + amount&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Running the tests again gives:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;java.lang.AssertionError: expected: &lt;b&gt;Money&amp;lt;SEK 1&amp;gt;&lt;/b&gt; but was: &lt;b&gt;Money&amp;lt;SEK 1&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;at ...&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is definitely more readable. Arguably it would be more confusing had we not remembered the last error message: they are different instances. So, the equality test that Scala gives us from the Scala top class AnyRef (which is the same as java.lang.Object on the JVM) does not cut it for value objects - exactly as in Java.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Fixing Equality&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;What to do? Of course we could get into Money and add an override def equals returning true. Then we could add a testcase to provoke a failing equals, forcing us to elaborate our equals method etc. However, in Scala there is a simpler solution at hand - declare Money as a "case class".&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;b&gt;case&lt;/b&gt; class Money(currency : String, amount : Int) {&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;override def toString() : String = currency + " " + amount&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us not get into the details, but apart from giving us well-behaving equals and hashcode, it actually makes sense for value objects to be case classes.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Green Test, Refactoring, and Ready to Start over again&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The good part is that this change take us home to a green bar. There is not much refactoring to do, so now we have gone a full TDD cycle using Scala and JUnit. Time for next round.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now we have gotten started&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ps Once getting started, you might want to &lt;a href="http://dearjunior.blogspot.com/2011/05/scala-actor-waiting-for-godot-vladimir.html"&gt;try out some actors in scala&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-559078727577834549?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/559078727577834549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/03/getting-started-with-junit-and-tdd-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/559078727577834549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/559078727577834549'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/03/getting-started-with-junit-and-tdd-in.html' title='Getting Started with JUnit and TDD in Scala'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-9213130109078056444</id><published>2011-02-02T21:22:00.000+01:00</published><updated>2011-02-02T21:22:09.229+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Conceptual Abstraction, and Technical</title><content type='html'>&lt;div class="gmail_quote"&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I think there is an important distinction between solving a technical problem and solving the conceptual problem. And this distinction has a profound effect on what the code will look like.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let me take an example. Imagine that you have some class that keeps track of the score during a football game. It might look something like this.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;class FootballGame() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;int home = 0;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;int guest &amp;nbsp;= 0;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;void homeGoal() { home++; }&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;// void guestGoal()&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;// String score () , e g "4-3"&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;// etc&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now you want to add goal logging, that logs each goal to stdout. This might change homeGoal to&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;void homeGoal() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;home ++;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;System.out.println("home goal");&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Next reasonable change can be that you want the logging to be configurable so that you can log to a file instead of standard out.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This can be done from a technical perspective or a conceptual perspective. Let's have a look at each to see why I prefer doing it the conceptual route.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;&lt;i&gt;Technical abstraction&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The ambition of technical abstraction is to make yourself independent of the particular implementation you have at the moment. The "how" is here "to log goals to standard out", the "what" is "to log goals somewhere". We want the solution less dependent on the "how".&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;We refactor homeGoal to use a configurable output stream instead of hard-coding. The code inside FootballGame might turn out something along&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;FootballGame(PrintStream out) {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;this.out = out;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;void homeGoal() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;home++;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp;out.println("home goal");&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is a perfectly acceptable solution from a technical perspective. It uses dependency injection, so we can easily configure it with stdout, a stream to a log file or sending the data remote through a socket. For testing we can use a PrintStream backed with a ByteArrayOutputStream or we can mock the PrintString when doing TDD. The unit test for driving that step might look like&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Test&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void shouldLogHomeGoal() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ByteArrayOutputStream out = new ByteArrayOutputStream();&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FootballGame game = new FootballGame(new PrintStream(out));&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;game.homeGoal();&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Assert.assertEquals("home goal", out.toString());&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;(Arguably we also test some of the functionality of ByteArrayOutputStream - but as that is a standard API class I am pretty comfortable with that.)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Typically technical abstraction can be done by using the standard APIs given by the platform (OutputStream, String, List, File etc).&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The weakness of this approach is that the code/solution/architecture gets riddled with technical constructs, and after a while it is hard to remember exactly what purpose that particular OutputStream was for in that particular place.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;&lt;i&gt;Conceptual abstraction&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The ambition of the conceptual abstraction is also to make yourself independent of the particular implementation. However, we look at the situation a little bit different and thus set of in a slightly different directions. The "how" is here "to log goals to standard out", but the "what" becomes "to log goals".&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;We refactor homeGoal to use a GoalLogger.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;FootballGame(GoalLogger goallogger) {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.goallogger = goallogger;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;void homeGoal() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;home ++;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;goallogger.log("home goal");&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;interface GoalLogger {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void log(String msg);&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This solution does also use dependency injection, it can also be configured to log to standard out, to a log file, or cross network. For TDD we will probably using mocking in the driving testcase - which is really easy as we have an explicit interface.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Test&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void shouldLogHomeGoal() {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GameLogger gameLogger = Mockito.mock(GameLogger.class);&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FootballGame game = new FootballGame(gameLogger);&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;game.homeGoal();&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;verify(gameLogger).log("home goal");&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The difference is that we will need explicit classes. E g for stdout-logging we will use StdoutGoalLogger.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;class StdoutGoalLogger implements GoalLogger {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void log(String s) { System.out.println(s); }&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For other purposes we will use a FileGoalLogger or a NetworkGoalLogger.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;b&gt;Obviousness is the Difference&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The main difference to me is that it is totally obvious what the intent of the GoalLogger is, as apart from the generic PrintStream in the example of technical abstraction.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Granted, there are more code in the conceptual abstraction than in the technical abstraction - but I would still prefer the former if it came to maintenance or further development.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;But the real difference comes in the next step. We will probably notice that there are two calls that are repeated:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;goallogger.log("home goal");&amp;nbsp;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;goallogger.log("guest goal");&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now that we have the GoalLogger abstraction we can let it evolve.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;interface GoalLogger {&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void homeGoal();&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;void guestGoal();&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;}&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Note that we have also removed the now obsolete "void log(String msg)", and this is what makes this GoalLogger distinct from some or any general-purpose logger.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Had we done the technical abstraction of working with an PrintStream, it would not be as obvious what could be done next. What I have seen most of the times is some kind of util class emerging containing static "helper methods" like GoalUtil.logHomeGoal(PrintStream), helper methods that are sometimes used, sometimes not. This in turn leads to similar (or duplicated) code in several location and an increase in code line count.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In my experience the small increase in line count for the conceptual abstraction is far better than the "ripple" increase in line count that the technical abstraction cause over time.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The bottom line. Focusing on the conceptual problem at hand gives a better codebase in the long run than focusing on solving the technical problem does. It might give more code but it need not to take much more effort.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span style="color: #888888;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #888888;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #888888;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #888888;"&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-9213130109078056444?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/9213130109078056444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2011/02/conceptual-abstraction-and-technical.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/9213130109078056444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/9213130109078056444'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2011/02/conceptual-abstraction-and-technical.html' title='Conceptual Abstraction, and Technical'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-2325601896984440688</id><published>2010-11-30T08:13:00.003+01:00</published><updated>2010-11-30T08:20:42.180+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='model'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophical'/><title type='text'>What is Snow?</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;On the morning after a night of snowfall, I took a morning walk to&amp;nbsp;kindergarten with my two sons. The older of them (four years old, but&amp;nbsp;soon five) asked:&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;"Why does snow glitter?"&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Good question and I described how snow consist of snow flakes that are&amp;nbsp;flat, and that it is the top-most layer of flakes that glitter - in&amp;nbsp;the same way as the glitter palettes that you can glue onto paper. We&amp;nbsp;discussed it a while, and he seemed to think that it made sense.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;After some moments of silence came the next question:&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;"Why is snow soft and fluffy?"&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Good question, and I described how the flakes fall on top of each&amp;nbsp;other in loose layers. We discussed it a while, and he seemed to think&amp;nbsp;that it made sense.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To no big surprise there came yet another question:&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;"Why are snow balls hard?"&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Good question again, and I described how the loosely layered flakes&amp;nbsp;are squeezed together and get stuck in each other - that is why the&amp;nbsp;snowball does not fall apart. We discussed it a while, and he seemed&amp;nbsp;to think that it made sense.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, is snow *really* snowflakes? Nahhh, snow is water that sticks&amp;nbsp;together through covalent bindings that behaves in a certain way when&amp;nbsp;the temperature drops so much that the kinetic energy of the molecules&amp;nbsp;is so low that it make them bind to each other in certain geometric&amp;nbsp;patterns.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;But, you do not expect me to explain that to a four year old kid, I guess …&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The snow flake metaphor is a model. It abstracts away a lot of really&amp;nbsp;complex stuff to give us a way of explaining a limited set of&amp;nbsp;phenomenons. Put another way, it answers some interesting questions.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;As all models it has its limits. For example, had my son asked "How&amp;nbsp;come that when snow melts, it become water, but when it freezes again&amp;nbsp;it does not become snow, but ice?". Well, then the snow-flake model&amp;nbsp;would not have helped much. It is just a model. It answers some&amp;nbsp;questions in a way that makes sense, but not all questions.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;However, the same goes for the "covalent binding" explanation. It is&amp;nbsp;also just a model. It is not more or less "true" that the snowflake&amp;nbsp;model. It is just capable of explaining another range of phenomena in&amp;nbsp;a way that makes sense.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;They are both useful models, and that is where they get their value.&amp;nbsp;The interesting question is not whether the model is "true" or not,&amp;nbsp;but whether the model is useful.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The "snow flake" model enables a father to give sensible answers to&amp;nbsp;some questions a four year old boy might ask on the way to&amp;nbsp;kindergarten on the morning after a night of soft snowfall.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;From my point of view, that is a good model.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-2325601896984440688?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/2325601896984440688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/11/what-is-snow.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/2325601896984440688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/2325601896984440688'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/11/what-is-snow.html' title='What is Snow?'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-8017806386994042101</id><published>2010-11-23T07:56:00.001+01:00</published><updated>2010-11-23T08:16:48.706+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Fix the Problem, not the Bug</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It is not always "fixing the bug" is the right thing to do. Well, it&amp;nbsp;depends on what you mean with the word "bug" I guess. But, to often&amp;nbsp;"fix the bug" means "make a local change to make the bad behaviour go&amp;nbsp;away". Instead we should search for the cause of the trouble, the&amp;nbsp;problem itself - and fix that.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Say you have an application where you handle train departures. And&amp;nbsp;somewhere you are to show a result of some search - a result that&amp;nbsp;comes packed as a ResultInfo object containing timestamp and matching&amp;nbsp;departures.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Simple, Clear, Readable Code&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So there might be a class for listing results looking something like:&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;/** Lists train departures from searches. */&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;public class DepartureLister {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;private PrintWriter resultwriter;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;/** Render search result */&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;void showlist(ResultInfo resultinfo) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;resultwriter.println("resulttime: " + resultinfo.timestamp);&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (Departure departure : resultinfo.matching) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;resultwriter.println(departure.trainNr);&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;resultwriter.println("matches: " + resultinfo.matching.size());&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For simplicity, let us say that the classes ResultInfo and Departure&amp;nbsp;are the most simple possible.&lt;/span&gt;&lt;/div&gt;&lt;blockquote style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;/** Search result with matching departures */&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;class ResultInfo {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;String timestamp;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;Collection&lt;departure&gt; matching;&lt;/departure&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;/** Train departure identified by its train number */&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;class Departure {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;String trainNr;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;OK, pretty obvious what the code does as well as its purpose.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Finding a Bug&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now imagine that this code at some occasion barfs with&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;java.lang.NullPointerException&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;at client.DepartureLister.showlist(DepartureLister.java)&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;on the line&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;for (Departure departure : resultinfo.matching)&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;What is going on? From a technical standpoint it is pretty obvious&amp;nbsp;that this code is wrong as it did not take into account that the list&amp;nbsp;"resultinfo.matching" could be null.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Fixing the Bug&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So fixing the bug we change the code by wrapping the for-loop with a&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;null-guarding if.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;b&gt;if (resultinfo.matching != null) {&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;for (Departure departure : resultinfo.matching) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;resultwriter.println(departure.trainNr);&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;And we also need to do something about the result-size printout.&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;resultwriter.println("matches: " +&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;b&gt;(resultinfo.matching != null ?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;resultinfo.matching.size() &lt;b&gt;: 0)&lt;/b&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Well, it works, but I would not say that the code is "pretty obvious"&amp;nbsp;any longer. Even if we refactor it to make it neater, there will still&amp;nbsp;be the null handling hanging around messing up things.  Code should&amp;nbsp;not look like this. If it is easy to express "list the matching&amp;nbsp;departures", then that message should be easy to read from the code. It &lt;i&gt;was&lt;/i&gt; easy to read it, it is no longer.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Furthermore, any use of ResultInfo throughout the code will need these kinds of guards and switches. Apart from messing up the code in all those places, it is also a blatant violation of the DRY principle, stating that each "idea about the code" should only be expressed "once within the code".&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Obviously "fix the bug" was not the right thing to&amp;nbsp;do.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Find the Problem&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us see what would happen if we try to "fix the problem" instead.&amp;nbsp;To start with, let us formulate the trouble, but from a conceptual&amp;nbsp;standpoint - what the code tries to achieve, not a technical - what&amp;nbsp;the code does. The technical standpoint was "resultinfo.matching can&amp;nbsp;be null". Rephrased from a purpose-perspective that would be&amp;nbsp;"situations with no matching departures".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now it becomes blatantly obvious that the natural counter-question is&amp;nbsp;"Why on earth is that not represented as an empty list?". So we dig&amp;nbsp;into the departure-matching code and find the search where you call a&amp;nbsp;legacy backend system.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;/** Searches for departure according to matching some criteria */&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;public class DepartureMatcher {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;private Legacy legacy = new Legacy();&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;public ResultInfo searchMatching(String[] matchcriteria) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;ResultInfo resultInfo = new ResultInfo();&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;resultInfo.timestamp = new Date();&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;int[] trainnrs = legacy.find(matchcriteria);&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;b&gt;if (trainnrs[0] == 0) {// special signal no match&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;resultInfo.matching = null;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;return resultInfo;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;resultInfo.matching = new ArrayList&amp;lt;Departure&amp;gt;();&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;for (int trainnr : trainnrs) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; resultInfo.matching.add(new Departure(trainnr));&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;return resultInfo;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Okey, here we can see the root of the problem - why "empty list" is&amp;nbsp;handled as a special case and signaled with null. One can almost see&amp;nbsp;how the if-clause in the middle have been "cranked in" into the middle&amp;nbsp;of the searchMatching when some programmer found out about the&amp;nbsp;non-intuitive behaviour of the backend system to represent "no match"&amp;nbsp;with "[0]".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Fix the Problem&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, fixing the underlying problem is pretty easy. We change the "no&amp;nbsp;match" clause&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;if (trainnrs[0] == 0) {// special signal no match&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;resultInfo.matching = &lt;b&gt;null&lt;/b&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;return resultInfo;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;and replace it with&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;if (trainnrs[0] == 0) {// special signal no match&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;resultInfo.matching = &lt;b&gt;Collections.emptyList()&lt;/b&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;return resultInfo;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now the two cases "empty list of matches" and "non-empty list of&amp;nbsp;matches" behave analogous. This leaves room for some refactoring,&amp;nbsp;replacing the messy method with:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;public ResultInfo searchMatching(String[] matchcriteria) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;int[] legacyreturnlist = legacy.find(matchcriteria);&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;int[] &lt;b&gt;trainnrs = legacyreturnlist[0] == 0 // no match&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ? new int[0]&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : legacyreturnlist&lt;/b&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;List&lt;departure&gt; matching = new ArrayList&lt;departure&gt;();&lt;/departure&gt;&lt;/departure&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;for (int trainnr : trainnrs) {&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;matching.add(new Departure(trainnr));&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;return new ResultInfo(new Date(), matching);&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here it is more clear what each part of the method is doing. Of course,&amp;nbsp;to make this into clean code, some more refactorings are justified -&amp;nbsp;especially extracting each functional part (of a few lines) to methods&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;with names of their own. But, we can be proud over what we have done&amp;nbsp;this far.&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here is time to take a small break and ponder what we have done. We&amp;nbsp;have made a piece of the code behave a little bit clearer, yes. We&amp;nbsp;have removed a weird special case (null list), yes. But we have also&amp;nbsp;changed the API of a public method - and that should not be taken&amp;nbsp;lightly.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Can we be sure that we have not broken anything else? Do we not risk&amp;nbsp;introducing an unknown heap of new bugs? And if so, how can that be&amp;nbsp;better than changing the code in one place (the client where we&amp;nbsp;originally had the bug reported)?&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I would argue, that even if we introduce new bugs, we have still fixed&amp;nbsp;a problem. The key difference is that those bugs will be code locales&amp;nbsp;that rely on a non-intuitive API - so those bugs will be easy to fix.&amp;nbsp;In other words: when moving to a clearer way to formulate the code,&amp;nbsp;you should not be too afraid for "causing bugs". As long as the change&amp;nbsp;you make solves a problem and leaves the code in better shape - then&amp;nbsp;subsequent bugs are easier to fix.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Fast Fail&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course we should do what we can to aid in finding those bugs. In&amp;nbsp;this case this can be done by changing the contract for the&amp;nbsp;ResultInfo. Up until now it have been legal to have a null-list of&amp;nbsp;matches. Now we want empty match to be represented by empty&amp;nbsp;matching-list. So let us enforce this:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;ResultInfo(Date timestamp, Collection&lt;departure&gt; matching) {&lt;/departure&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;if (&lt;b&gt;matching == null&lt;/b&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;throw new NullPointerException(&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;"Matching list not allowed&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;to be null " + timestamp);&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;this.timestamp = timestamp;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;this.matching = matching;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now there will probably be a pile of test-cases that will fail with&amp;nbsp;NullPointerException and hopefully pointing out places in the code to&amp;nbsp;change to adhere to the new and clearer API.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Sum it up&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Trying to fix the bug where it surfaced just led to messy code in a lot of places. That was because the problem was not really there. Not a strange thing: effect is not cause, symptom is not illness - we all know it. The real problem was "empty list" represented by null.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Instead, finding the root of the trouble - the problem itself - we could solve the reason for the unclear code. Let "empty list" be represented by an empty list, from the source. Now, the client code could stay in its original lucent form, and we could also make some refactorings of the search code to make it easier to grasp.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;On top we added some enforcement of this new policy - the ResultInfo simply refuses to accept the mission to carry "null-lists". Now all clients can rest assured they will always get a proper list of Departures.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Al in all, the code becomes clearer.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Exceptions might Apply&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course there are points of time you do not want to do this, like a&amp;nbsp;few days before a release. However, as a general rule I prefer to fix&amp;nbsp;the underlying problem in the code, than to fix the bug where the&amp;nbsp;problem manifest itself.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-8017806386994042101?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/8017806386994042101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/11/fix-problem-not-bug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8017806386994042101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8017806386994042101'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/11/fix-problem-not-bug.html' title='Fix the Problem, not the Bug'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-7641935589042862822</id><published>2010-11-18T07:39:00.001+01:00</published><updated>2010-11-18T07:49:27.345+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubiquitous language'/><category scheme='http://www.blogger.com/atom/ns#' term='domain driven design'/><title type='text'>Presenting on Ubiquitous Language at Jfokus 2011</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I have gotten the delighting message from the Jfokus committee that&amp;nbsp;they want me to speak at the Jfokus 2011 conference in Stockholm in&amp;nbsp;February. I had proposed a presentation on the Domain Driven Design&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;concept of Ubiquitous Language which they have accepted.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It seems to me that the ubiquitous language is one of the hardest&amp;nbsp;things to get right. When I look at my own experience it is a part&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;where there are a lot of small distinction, distinctions that are&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;subtle but make a huge difference.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Just take an example of how you can express the same thing in&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;different ways that seem synonymous, but actually make a huge&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;difference.&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Compare&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;"An account has a phone number. The account can change phone numbers."&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;with&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;"An account has a phone number. The phone number can be changed."&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The difference might be subtle, but in a &lt;i&gt;precise&lt;/i&gt; language the&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;distinction is important. In the first case, the account have still&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;the same (conceptual) phone number, which has been edited. The account&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;and the phone number are both entities. In the second case, the&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;account have changed its phone number to another phone number.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In code the two cases would be&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;1. account.number.changeto(numbersequence)&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;blockquote&gt;2. account.number = new PhoneNumber(numbersequence)&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, what difference does it makes?&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Well, somewhere else we might require that a new account might have&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;the same number as an old account. Fair enough. But what happens if&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;the old account gets a new number? Does the &lt;i&gt;new&lt;/i&gt; account change its&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;number as well?&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Have we taken the pain to actually create a strict language that is&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;understood in common, then we have the answer in the language. If we do&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;not have that strict language, chances are high that we arbitrarily&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;select one of them that "feels right at the moment". However, next&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;time a similar situation arises there is no guarantee that what we&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;pick arbitrarily that time is logically consistent with the first&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;pick. Over time we risk getting a system that behaves subtly, or&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;obviously, inconsistent with itself.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course, this is just one example. In the presentation, what I want&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;to cover are practical aspects of to make a shared language to become&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;useful - and what it takes to become useful. E g it has to be both&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;rich enough to express the complexity of the problem, but it must&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;still be precise enough so we can use it as a base to build a system.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Other aspects I want to cover is how such a language can grow over&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;time (not a Big Upfront Design), problems and traps when introducing a&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;new term, and the challenges of "mixed language environment" such as&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;when there are both Swedish and English around.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course you recognize several of these subjects as we have discussed&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;these earlier. However, I hope to put them together in a concise and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;structured format - and want to roll in some new ideas. I am sure&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;there will be plenty of reasons to return to these areas in subsequent&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;letter.&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-7641935589042862822?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/7641935589042862822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/11/presenting-on-ubiquitous-language-at.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7641935589042862822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7641935589042862822'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/11/presenting-on-ubiquitous-language-at.html' title='Presenting on Ubiquitous Language at Jfokus 2011'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-6443775428232948528</id><published>2010-11-10T16:29:00.003+01:00</published><updated>2011-08-25T15:16:26.143+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistical analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='release'/><category scheme='http://www.blogger.com/atom/ns#' term='planning'/><category scheme='http://www.blogger.com/atom/ns#' term='story'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophical'/><category scheme='http://www.blogger.com/atom/ns#' term='backlog'/><title type='text'>4 Points of Story Points</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For quite some time there have been a debate on "what story points really are". To some extent there have been insightful discussions about important things to consider when sizing stories. However, the "really are" part of the debate just leaves me tired.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To discuss the true nature of story points is pretty pointless: they are a construct, created by us, and can be given any arbitrary meaning. It does not matter. What matters is whether that construct is useful for a purpose. This is the core of pragmatism.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In other words, the relevant question is not "what story points are", but "what story points are useful for". Please excuse the pun, but rephrased "What is the point of story points?"&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If I try to pry things apart I can distinguish four different situations where I have found story points useful. Basically they cover the questions "Is it small enough?", "What does it cost?", "Which should we do first?", and "When can I have it?".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Small Enough&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One of the cardinal faults a team can do is to start working on a story that is way to big. If they do, they will surely fail to finish it within the sprint, and having a demo with nothing to show is pretty depressing. Having a lot of half-finished work also tie their hands of what they can do next sprint. No good.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;A mature team might have developed a gut feeling of how big a bite they can take and still eat it. The stories considered too big are simply sent back to product owner for delimitation or splitting.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;A less mature team might see that bites have different sizes, but have not yet the insight of how big a bite they can take without choking.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here story points can come in useful. The team can size the stories as 13, 20, 3, 8 etc. But they need not to know their limits. Instead we can observe the velocity over a few sprints and see what "small enough" means. For example, if the team have a velocity of 18, I would advice to set the limit to 9 (half velocity). So, the stories sized 3 and 8 are small enough, and those of 13 and 20 will need some more pre-sprint work to make them manageable.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It can be handy to reserve the top of backlog for stories that are small enough, a "backlog shortlist" of ready-to-develop stories. Or, if you prefer the kanban style to have one stage "delimit and split" followed by a "ready-to-develop" queue before pulling them into active development.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Cost&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Whether we like it or not, the question about money always come up. It can be hard to just look at a requested feature and say how much it would cost to develop it. In a lot of development efforts the dominating cost is the cost of labour. Either the work will tax the amount of available work by the employees, or there will be contractor bills to be paid.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here story points can come in useful. Someone probably knows what the team costs per week, or can calculate it. If you have some historical velocity data you can make a rough estimate of what each point costs. So, if you know roughly the size of the story, you can calculate the cost.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Say that your team costs EUR 27 000 a week, you run two weeks sprint, and your sprint-velocity hoover around 18. Then each point costs around EUR 3 000. So, a story of size 40 will cost roughly EUR 120 000.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Well, not all of the time will be "pure development work". There will be meetings, phone calls, administration (filling out time reports) etc. But, that does not matter. Pulling through a story of size 40 will take roughly two sprints and during that time the team will cost that amount of money.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course, in practice you will rather want to give an interval than a precise number. The velocity might be within 17-19 (with 90% confidence) and a "40" story can be anything from 21 to 40. So the cost will rather be in the range EUR 60 000 - 130 000. Still, it will be a figure good enough for business to decide if it is remotely interesting to proceed or not.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Priorities&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;A misconception among business side "customers" is that they should set priorities on business value. Well, but "economics" is really about alternatives - the cost of a bar of chocolate is that you cannot get two lollipops. In the same way, for the product owner to make a wise balance between what different stakeholders want, she must be able to compare their cost.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Interesting enough, to make priorities, we do not need to know the absolute cost of each story. It is enough to know their relative cost.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here story points can come in useful. If feature A is size 20, feature B is 8, and feature C is 13, then we know that we can swap out feature A from a release and switch in feature B and C instead. And in doing so we do not need to care about the details of how much money it is about - all we need is aid in choosing.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Planning&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Business need to look ahead to synchronize different parts of their work. E g there are some benefits in having a marketing campaign at the same time as you release some new feature of your software. But, waiting for the software to be complete before ordering the marketing will obviously make you loose market-time.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Here story points come in useful. If you observe the velocity of the team over some time you can apply some not-too-advanced statistics to predict how much work will be completed at some future point of time. Of course, each such prediction will have a probability to fail, and the surer you want to be, the lower you must set the prediction.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For example, if you have observed the velocities 36, 28, 36, 38, 24, 35, 32, 35 and you have five sprints to go, you can calculate the average and predict the team will finish 165 points. However, that prediction is just a prediction - the real result will be as likely to be higher as it is to be lower. In other words, your prediction has a confidentiality of 50 % - or a 50 % risk of failing.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If you want to make a safer prediction, say taking just a 5% risk of failing, you can calculate an interval with 95% confidentiality. In this case it will be the interval 144-186. Now you can mark the backlog, colouring all stories up to 144 as green (very likely to be delivered), those from 144-186 as yellow (totally "depends-on") and those from 186 and up as red (very unlikely to be delivered).&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;In Summary&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It is very hard to talk about the "true nature" of story points. They are abstractions that say &lt;i&gt;something&lt;/i&gt; about development work. And, the question of "what they really are" is not a very interesting one. Working with story points is a model, and a model should not be evaluated on "how true" it is - but on how useful it is.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Story points might be useful for a team to decide whether a story is small enough to fit in a sprint, of if it should be pushed back to the product owner - if they cannot do it by gut feeling.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Story points might be useful in assessing the cost of developing a story - if it is questionable whether its value justify the cost.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Story points might be useful for setting priorities - if it is difficult balancing the stakeholder interests.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Story points might be useful for planning at release level - if the organisation need to synch the work of different departments or groups&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Apart from these four points, story points might be useful in doing other useful things - if it helps the organisation to act more wisely.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It might well be that in your particular setting, none of the "ifs" apply - and in that case story points are not useful to you. And if they are not useful, they steal time and attention from other things that would serve you better - i e they are waste that should be discarded.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In the end "what story points really are" is not as interesting as "what is the point of story points".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ps Story points being helpful for planning is of course key to &lt;a href="http://dearjunior.blogspot.com/2009/05/why-release-planning-works.html"&gt;why release planning works&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;pps If story points help in planning it is interesting to see what factors drive high story points. For planning, it is the &lt;a href="http://blog.mountaingoatsoftware.com/its-effort-not-complexity"&gt;amount of effort that differs&lt;/a&gt;, but that is to a large extent &lt;a href="http://dearjunior.blogspot.com/2010/07/complexity-drives-effort.html"&gt;driven by the complexity&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ppps Unless you are really good at making statistical computation, it helps to have a&lt;a href="http://dearjunior.blogspot.com/2009/10/release-planning-spreadsheet.html"&gt; spreadsheet to aid in the planning&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;pppps One way to ensure team does not embark upon developing something "too big" is to make a &lt;a href="http://dearjunior.blogspot.com/2008/04/keeping-backlog-in-shape-using-backlog.html"&gt;backlog shortlist&lt;/a&gt; of the top part of the product backlog.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-6443775428232948528?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/6443775428232948528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/11/4-points-of-story-points.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6443775428232948528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6443775428232948528'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/11/4-points-of-story-points.html' title='4 Points of Story Points'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-1736079285856683275</id><published>2010-11-02T07:58:00.001+01:00</published><updated>2010-11-04T16:09:56.885+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Good Product Owner Wrapup</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I would like to wrap up our discussion about the good product owner and the characteristics thereof. Of course there are many important attributes, and there are even more ways to select words for them. However, I think a lot of them are caught by the two-by-two containing "engaged, involved, decisive, and empowered".&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;personal &amp;nbsp; organisational&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;social: &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;engaged&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;involved&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;formal: &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisive&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;empowered&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It does not tell everything about a good product owner. It is just a model, meant to capture some important points in a concise way.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, let's just have a walk around this picture.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Starting with &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;engaged&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; we have a product owner that cares, who thinks the product and the system is important. This product owner has an inner drive to do things for the benefit of the product. So, it is a &lt;i&gt;personal&lt;/i&gt; attribute. Also it is not so much about mandate and formalities, it is more about interacting with people, so "engaged" is set in a &lt;i&gt;social&lt;/i&gt; setting.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Moving over to right we stay in the &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;social&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; setting, but transfer to the &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;organisational&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; attribute of being &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;involved&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; (from Latin "in the turning"; today we would probably say:"in the loop"). We are still talking about "interacting with people", but now it is not the person's inner drive. Instead it is the organisation "letting" the PO being involved. Rephrased, the organisation thinks that being product owner is the most important thing on this persons job description - there is nowhere else this person rather should be.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Moving down we stay on &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;organisational&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; attributes, but switch to talk about &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;formalities&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;. Being &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;empowered&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; is all about having the organisational mandate to take decisions that will stand. Of course the product owner can change her mind, and re-decide something else later. However, that is the decision of the product owner herself - not something the rest of the organisation can force upon her. The PO is a little bit like the "local CEO" of the product.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Moving to the left we stay on &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;formalities&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;, but move back to &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;personal&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; attributes. Being &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisive&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; is to have the personal drive to actually make decisions when they are needed. Of cause even a decisive person can change her mind, but the good product owner will take decisions with respect to the team, not throwing them "of balance" by completely changing direction. Still it is being decisive in the moment needed that keeps progress going.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Moving up we stay on &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;personal&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; attributes, but cross the border of formalities back to &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;social&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; settings and we end up at &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;engaged&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; where we started.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, this model is nothing but a model, and thus it is limited in its power and limited in its reach. In other words: it misses a lot of important points.&amp;nbsp;It is also a product of annotating specific words specific meanings, that are by no mean ubiquitous.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Other words&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://forward-going-rich.blogspot.com/"&gt;Steven Hale&lt;/a&gt; pointed out that the distinction between "engaged" and "involved" is unclear (to say the least). He has suggested "interested" and "active" as a more distinct pair for the social attributes. This also makes the acronym IDEA possible &amp;nbsp;- which is neat. However, in defense of "engaged/involved" he also notes that there was a girl with whom he got involved, later engaged, and now they are married.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Important things missed&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;There are also important things this model leaves out. One of the things &lt;a href="http://jockeholm.wordpress.com/"&gt;Joakim Holm&lt;/a&gt; pointed out is that fails to mention the "burning vision" the product owner should uphold. I could not agree more - that is one of the most of important things a product owner should establish, nurture, and communicate (I am keen to say "radiate"). And that dimension is not caught in this discussion on "characteristics".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In the end - this two-by-two is just a model. Being a such some important things fall outside, for the simplicity of expressing many important things concisely. To me, this model capture a lot of important attributes.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The way to judge a model is not whether it is "true, or not". It is whether it is useful in important circumstances. Personally &amp;nbsp;have used this model a lot of times when trying to figure out what is wrong in situations that does not work well. It has also deepened my understanding of agile and how it relies on humans, as individuals and their interactions, rather than setting and trusting formal structures.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I hope it will come useful to you.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ps So, who will become a good product owner? Well, for example, I have met some &lt;a href="http://dearjunior.blogspot.com/2009/06/agile-product-owner-new-project-manager.html"&gt;really good project managers that I think would become excellent product owners&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-1736079285856683275?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/1736079285856683275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/11/good-product-owner-wrapup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1736079285856683275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1736079285856683275'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/11/good-product-owner-wrapup.html' title='Good Product Owner Wrapup'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-5241081612364255854</id><published>2010-10-21T08:28:00.003+02:00</published><updated>2010-10-21T08:28:00.282+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Empowered Product Owner</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us say that you have a product owner personally engaged, organisationally involved, and who is decisive enough to take decisions. For having a &lt;a href="http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html"&gt;good product owner&lt;/a&gt; you only lack the fourth characteristics; you want the product owner to be empowered.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; &lt;b&gt;Empowered&lt;/b&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course it does not help much having a product owner taking decisions if she does not have the authority to do so. The problem is that any decision the team has started working from can suddenly be revoked.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;Sorry folks, I just talked to the Guy-Who-Decides-Stuff and you remember that delimitation we settled for yesterday …. well, to make a long story short, he thinks it is an over-simplification, so we cannot do that. I am really sorry if it messes up things for you …&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Agile methods in general are built do handle change. But you want that change to come controlled — not on things in-sprint after you have spent considerable time and effort working on it. If the team gets contra-orders repeatedly during a sprint they start mistrusting the decisions and guess if they lose tempo!&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is really what I do not like about "Proxy Product Owner". Such a one can be engaged, involved, and decisive. However, they are not empowered - the "Real PO" is somewhere else and any decision might be overruled. The unfortunately result is often that the Proxy PO gets indecisive.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;Proxy PO: Sound good, just let me check with Guy-Who-Decides-Stuff. I will know for sure by tomorrow.&lt;/blockquote&gt;&lt;blockquote&gt;Team: So, what do we do until tomorrow?&amp;nbsp;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Point here is that the team lo&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ses focus and tempo.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To make things worse, the etymology of the word "proxy" unveils that "proxy without authority" is a misuse. The word is closely related to "&lt;a href="http://www.merriam-webster.com/dictionary/procurator"&gt;procurator&lt;/a&gt;" which was the province manager in the Roman empire and &lt;i&gt;who held administrative powers as agent of the emperor&lt;/i&gt;. No talking here about "have to check with the Emperor in Rome first".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, what to do about it?&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I told you about the example of the non-involved Head of Marketing. In that case, someone else did the day-to-day job. Taking care of the backlog etc was done by an assisting controller from economy department. And he had to constantly run around the building to chase down stakeholders to validate any decision he made. The poor bastard did not even have the title "Proxy PO".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The solution I advice is to empower the Proxy to become the Real Product Owner, and the Head of Marketing in this example will become one important stakeholder.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In some organisations this sounds strange: "Can you give authority to someone who is not the boss?" I would argue you can.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I think of the relationship between the product owner and the stakeholders a little bit like the relation between the CEO and the Board. The Board is not the "boss" of the CEO. All decisions the CEO makes, she makes based on her mandate. If the CEO makes consistently bad decisions, she will be replaced - but until that point of time she has her mandate. Of course the good CEO will carefully listen to what the Board thinks is important. But, the decisions will be her own.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In the same way, the stakeholders are not the boss of the product owner. All decisions the PO makes, she makes based on her mandate. If the PO makes consistently bad decisions, she will be replaced. Of course the good PO listens carefully to what the stakeholders think is important, and try to balance those interests. But, the decision will be her own.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In traditional organisations there is a glory around the word "owner" that tend to push the title "up the ladder". If it is a really important system, then it might make sense to have the Head of Marketing to be product owner. But then the system must also be important enough for that person to spend considerable time on its development. Otherwise, delegate both the task and the authority to someone who has the time.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is actually nothing but an instance of the good advice on organisational structure: &lt;i&gt;Strive for aligning task, competence, and mandate&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Sounds pretty obvious, but it is interesting to see how often these are not well-aligned in many organisations.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being empowered is a characteristics in an organisational context, in the same way &amp;nbsp;as "involved" is "allowed by the organisation to spend time with the team". However, it is not so much about the informal situations that "involved" is mostly about, it is more about when there are time to make decisions. In that respect it is more related to being decisive.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; Empowered&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If you are in an organisation that manage to hand you an empowered product owner, you have a good chance to keep things rolling.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp;Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-5241081612364255854?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/5241081612364255854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5241081612364255854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/5241081612364255854'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html' title='Empowered Product Owner'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-3940466263678767852</id><published>2010-09-29T16:28:00.001+02:00</published><updated>2010-10-21T21:35:48.130+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Decisive Product Owner</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In the list of c&lt;a href="http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html"&gt;haracteristics of a good product owner&lt;/a&gt;, we have this far discussing those in informal situations - being engaged and involved. However, product ownership is also a lot about making decisions, and then I like the product owner to be decisive.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;b&gt;Decisive&lt;/b&gt; &lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;System development is a lot about making decisions. Even when we write code (and perhaps especially then) we make hundreds and thousands of micro-decisions. Some of them have mainly technical implications (make this design one class or two), but some of them form enterprise logic (what fields should I use when computing this if-conditional).&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Sometimes these decisions grow a little bit larger, and we want to ask someone about what we should do. For example we might be writing a batch-file reader and wonder how we should handle if someone sends in the same file twice. Perhaps we consider saving some kind of file ID and a content hash to detect that situation. This might take a day or so to implement so most probably we will bring that up during the daily standup.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;That standup is when the product owner can step in and make a huge difference. Of course the PO needs to be there (involved) and needs to care (engaged), but if she is she might make a huge difference by saying:&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;"Hold that thought. To me that seems like a separate story (Avoid duplicate file read). It is good enough if you implement this without that feature. if same file is sent twice, and we read it twice - then so be it. I make it new story and bring it up with the stakeholders."&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Viola, within one minute the product owner have saved the team one day of coding, just by being decisive.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Product owner need also be able to take decisions at point blanc, even when there might not be enough information.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;Team member: "I wonder, what shall we do about social security numbers for people with protected identity"&lt;/blockquote&gt;&lt;blockquote&gt;Product owner: "I do not know whether we have a case for supporting protected SSNs - need to check that up. Ignore that feature for now, if necessary I will add that as a new feature later."&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is just a few minute conversation, yet it saves the team hours of work by not loosing tempo.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being decisive rules out product owners that "just want to investigate a little bit further before saying anything definitive" - such behaviour leaves the team floundering on what to do, whether they can proceed on the assumption or if they should wait.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being decisive is a characteristic in a personal context, as is engaged. However it is more about making decisions rather than informal situations - so in that respect it is more related to being empowered.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt;&lt;/i&gt; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;b&gt;Decisive&lt;/b&gt; &lt;i&gt;&lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Nevertheless, having a decisive product owner makes things so much easier to keep things rolling.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-3940466263678767852?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/3940466263678767852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3940466263678767852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3940466263678767852'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html' title='Decisive Product Owner'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-7191074889429890168</id><published>2010-09-17T09:07:00.003+02:00</published><updated>2010-10-21T21:35:13.873+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Involved Product Owner</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Let us continue the discussion about &lt;a href="http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html"&gt;four characteristics of a good product owner&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Having an engaged product owner is very well, but it does not really help much if she is not &lt;i&gt;involved&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt; &amp;nbsp; &lt;b&gt;Involved&lt;/b&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; &amp;nbsp; &lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being involved is basically &lt;i&gt;spending time with the team&lt;/i&gt;. I want the product owner to show up at daily stand-ups, and to be available for questions and discussions. Without being involved, the engagement does not lead anywhere - like "that is a really interesting and important point; we really need to discuss this, but unfortunately I am extremely short of time &amp;nbsp;- can we set up a meeting next week?". Few things stops up development more that not being able to put forward those important questions and have those discussions.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being an involved product owner is much about discussions and other informal situations - much like being engaged also is. However, where "engaged" is an attribute of the person, I would say that "involved" is an attribute of the organisation: does the (rest of the) organisation &lt;i&gt;let&lt;/i&gt; the product owner to &lt;i&gt;be involved&lt;/i&gt; or does it expect her to be &lt;i&gt;elsewhere&lt;/i&gt;?&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Having the product owner being involved rules out product owners that have lots of other important stuff to do, and being product owner will have to take whatever time that "is left" (obviously seldom more that extremely little). Product ownership is nothing that can be handled "on the side, with left hand".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One striking example is the Head of Marketing, who was the product owner of a web sales system. However, that person had so much to do with campaigns and strategy planning he did not even have time to come to the bi-weekly demos.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It is not uncommon to hear this kind of situation "solved" by a Proxy Product Owner. &amp;nbsp;The proxy will fulfill the "involved" part while the Real Product Owner is elsewhere doing more important stuff. I do not think this is a good solution.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The Proxy Product Owner does give the team someone to talk to and discuss with on a daily basis, the problem is that that person seldom hold authority to take decisions - and if they do those decisions often need to be ratified by the Real Product Owner. In the two-times-two-matrix, it is rather a problem about being empowered - so let me return to the Proxy Product Owner in a later letter.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt;&lt;/i&gt; &amp;nbsp; &lt;b&gt;Involved&lt;/b&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; &amp;nbsp; &lt;i&gt;&lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/i&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being involved is an attribute that applies to informal situations, like being engaged. In contrast to "engaged" it is however not so much about the person per se, but rather about the surrounding organisation. In that respect "invloved" is more akin to "empowered", with the distinction that the latter is more about formal decisions.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Still, having the product owner involved in the daily work is crucial for success.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-7191074889429890168?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/7191074889429890168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/09/involved-product-owner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7191074889429890168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7191074889429890168'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/09/involved-product-owner.html' title='Involved Product Owner'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-3721372557441359169</id><published>2010-09-15T21:31:00.004+02:00</published><updated>2010-10-21T21:34:19.003+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Engaged Product Owner</title><content type='html'>&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One of the things I appreciate with people I work with are that they are &lt;i&gt;engaged&lt;/i&gt;, and a good product owner is no exception to this. Thus, in the list of &lt;a href="http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html"&gt;four characteristics of a good product owner&lt;/a&gt;, I would like to start with that one.&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;b&gt;Engaged&lt;/b&gt; &amp;nbsp; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; &amp;nbsp; &lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;With "engaged" I basically mean that the product owner should &lt;i&gt;care&lt;/i&gt; about the product that we are working on together. This manifests itself as the product owner &lt;i&gt;wanting to participate&lt;/i&gt;.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For example, there might be a problem with some story that is under development - border cases might be unclear or we have unveiled an alternative flows that we did not foresee. In that case, the product owner should consider it important to discuss those to help the development move forward without stopping. Or, if there is a business concept a developer do not understand, the product owner should want to explain it.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Further than that, the product owner is not just reactive. The engagement is also proactive. As an example, there might be a story on the backlog that the development team has deemed too big or unclear to start developing. The product owner should then consider that important enough to work with stakeholders and developers to re-phrase that story in a way that makes it more feasible for development, e g by delimiting it or splitting it.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Being engaged rules out product owners that became product owner "because someone had to be" or - even worse - where ordered to take that position, perhaps against their wish. Such a person will have no particular interest in the system, how it is used, or how it should evolve.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So being engaged is mostly about informal situations - like being involved - not about formal decisions. And it is also an attribute in a personal context - like being decisive - not about what the surrounding organisation lets you.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Having an engaged product owner is crucial for sustained success in development. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-3721372557441359169?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/3721372557441359169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3721372557441359169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3721372557441359169'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html' title='Engaged Product Owner'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-1303241943575794515</id><published>2010-09-13T12:41:00.014+02:00</published><updated>2010-10-21T21:36:18.950+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Four Characteristics of a Good Product Owner</title><content type='html'>&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;A good product owner is hard to find — but it is well worth the effort. Once a development team start becoming agile it does not take long before the quality of the product-ownership becomes one of the most significant factors for the &amp;nbsp;productivity of the team. A good product owner works with the rest of the team to gain and uphold a high velocity. A bad product owner can slow the team down to close to a grinding halt.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I have seen several organisations that have attempted to establish a product owner role, where some attempts have succeeded and others have failed miserably. I have tried to find some way to characterise the product owners of these organisations where I have seen success. Finally I have boiled it down to four characteristics that are to some degree linked to each other.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The product owner I have come to appreciate can be summed up by being &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;engaged&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;, &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;involved&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;, &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;decisive&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;, and &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;empowered&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/engaged-product-owner.html"&gt;Engaged&lt;/a&gt; &amp;nbsp; &lt;a href="http://dearjunior.blogspot.com/2010/09/involved-product-owner.html"&gt;Involved&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;a href="http://dearjunior.blogspot.com/2010/09/decisive-product-owner.html"&gt;Decisive&lt;/a&gt; &amp;nbsp; &amp;nbsp;&lt;a href="http://dearjunior.blogspot.com/2010/10/empowered-product-owner.html"&gt;Empowered&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course, each word here have a multitude of interpretations so some explanation is needed to clarify what &amp;nbsp;I mean. I will elaborate each of them in subsequent letters, but right now I just want to try to convey the larger picture to you.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Context - Person and Organisation&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One thing I find interesting with this list of four characteristics is that it contains attributes of the person being product owner as well as the organisation surrounding that person. On one hand side, being &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;engaged&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; and &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisive&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; are &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;personal attributes&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; — they come from the "inside".&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;Engaged&lt;/b&gt; &amp;nbsp; Involved&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;Decisive&lt;/b&gt; &amp;nbsp; &amp;nbsp;Empowered&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;On the other hand being &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;involved&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; and &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;empowered&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; are attributes given by the surrounding &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;organisation&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;, it can let you be involved or being empowered, or it can stop you from doing so — they come from the organisation environment.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Engaged &amp;nbsp; &lt;b&gt;Involved&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Decisive &amp;nbsp; &amp;nbsp;&lt;b&gt;Empowered&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, the verticals in the matrix is about the context&amp;nbsp;—&amp;nbsp;personal or organisational.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Situation - Informal or Formal&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In a similar manner the attributes describe how the product owner acts in different kinds of situations. &amp;nbsp;Being &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;engaged&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; and &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;involved&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; are about &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;informal situations&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; — day to day discussions, coming to daily stand-ups , etc.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;Engaged&lt;/b&gt; &amp;nbsp; &lt;b&gt;Involved&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Decisive &amp;nbsp; &amp;nbsp;Empowered&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;On the other hand we have &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisive&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; and &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;empowered&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;. These are attributes that talk about &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;formal situations&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; — when there is a decision to make. The decisions are small as well as large. A small decision can be to scope a story during sprint, a large decision to say: "let's release". Disregarding small or large, those decisions are important.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Engaged &amp;nbsp; Involved&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="font-family: Times; text-align: justify;"&gt;&lt;blockquote style="text-align: left;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;b&gt;Decisive&lt;/b&gt; &amp;nbsp; &amp;nbsp;&lt;b&gt;Empowered&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, the horizontals in the matrix is about situation&amp;nbsp;—&amp;nbsp;informal or formal.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I definitely want to dive into each of these characteristics, but that will wait for another day.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To sum up this observation: I think this cross-section of personal-vs-organisational context and informal-vs-formal situations neatly catches most of the really important parts of what a good product owner is like, and what behaviour it leads to.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp;Dan&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-1303241943575794515?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/1303241943575794515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1303241943575794515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1303241943575794515'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/09/four-chars-of-good-product-owner.html' title='Four Characteristics of a Good Product Owner'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-7457138581240347090</id><published>2010-09-02T22:09:00.000+02:00</published><updated>2010-09-02T22:09:14.943+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NFR'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Multicore, Power, and Performance</title><content type='html'>&lt;div style="font: 12.0px Helvetica; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 14.0px;"&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Dear Junior&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Next time your data centre upgrade, you will of course get better performance out of your deployed systems. However, as there are several kinds of performance it can be interesting to think about what will happen to &lt;/span&gt;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/search/label/NFR"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;response time and capacity&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;. Chances are capacity will improve, but response time might decline. The reason is spelled multicore.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In ancient days of yore, long gone, processors improved by running on higher clock frequency. Higher frequency made them able to process more stuff per unit of time. New processor meant higher frequency and thus better response time. If high capacity was needed, it was achieved by the processor thread-switching between several requests serving them all within reasonable response time.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Those days are gone. Nowadays high-speed processors are no longer in demand. The reason for this is power consumption. The power-consumption of a processor is roughly proportional to the frequency, squared. So for thrice the speed, you pay nine times the power.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Slower Saves Power&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;There are of course several problems with high power consumption such as electricity bills and environmental issues. However, the driving force is cooling. Every single Joule that is fed into a processor in a data hall is transformed to heat. That heat needs to be transported out of the hall by the cooling system - and that is the limiting factor.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In other words — if you populate your data centre with high-speed processors you will hit cooling capacity at one point. However, if you use low-speed processors (frequency third of the high-speed), you can stuff in nine times more in the same data centre. So, nine times more, each giving a third of the MIPS compared to high-speed processor. Still you get three times more MIPS out of the same hall - good economy.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Of course, the modern way of doing it is not to build several processors, but to stuff multiple cores onto the same chip — i e multicore. Still, the driver is the same - you get more MIPS out of you data centre by lots of low-frequency cores that out of substantially fewer high-frequency cores.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This is not just theory. Several of the large web-sites of the world use new keys like MIPS/W or MIPS/m3 when benchmarking their data centres.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Actually, the same goes for laptops where heat must be limited to prevent user burns. There two slower cores on the same chip can give higher computational power and still radiate a lot less heat.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Better Capacity and Worse Response Time&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Getting back to response time and capacity — how are these affected? Well, the data centre upgrade might consists of pulling out old single-core processors and replace them with quad-core processors with 20% lower frequency. Power consumption goes down, making it possible to stuff more processor into the same space.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Looking at the data centre from the perspective of all clients we serve, or all transactions we process — we get a dramatic increase in capacity. However, from the perspective of a single request or transaction we experience a slower processor — so response time or latency will get worse.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Where processors and data centres earlier where sports cars getting faster and faster, they now rather resembles &lt;/span&gt;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/08/two-types-of-performance.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;school busses&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; that do not run nearly as fast but can carry a lot of people at the same time.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Of course this will affect the &lt;/span&gt;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/search/label/NFR"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;non-functional attributes&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; of our systems running on these data centres. Unfortunately, the effect is not that straight-forward, but I am pretty sure we are slowly running into trouble and need to do something about it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Yours&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;ps This is one of the reasons it is important to keep apart &lt;/span&gt;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2010/08/two-types-of-performance.html"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;response time and capacity&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;, instead of stuffing them both under "performance".&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande';"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande';"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-7457138581240347090?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/7457138581240347090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/09/multicore-power-and-performance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7457138581240347090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7457138581240347090'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/09/multicore-power-and-performance.html' title='Multicore, Power, and Performance'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-3676019087421937927</id><published>2010-08-27T09:00:00.041+02:00</published><updated>2010-09-02T22:16:52.416+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NFR'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='requirement'/><title type='text'>Two Types of Performance</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Dear Junior&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In architecture one of the most important tasks is to keep an eye on the non-functional (or quality) attributes of the system. Often this importance is enhanced by stakeholders holding up some non-functional requirement (NFR) saying "the system must really fulfill &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;this&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;". Unfortunately, these NFRs are often quite sloppily formulated and a key example is "performance". I have stopped counted the times I have heard "we must have high performance".&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;I think a baseline requirement for any NFR is that it should be specific. There should be no doubt about &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;what&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;quality we talk about. In my experience "performance" can mean at least two very different things. Instead of accepting requirements on performance I rather try to reformulate the NFR to use some other wording instead. I have found that the "performance" asked for often can be split into two different qualities: &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;latency&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;and &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;throughput&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Latency or Response Time&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;With latency or &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;response time&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;I mean the time it takes for some job to pass through the system. A really simple case is the loading of a web page, where the job is to take a request and deliver a response. So we can get out our stop-watch and measure the time it takes from the moment we click "search" until the result-page shows up. This latency is probably in the range of 100 ms - 10 s. Of course, this response-time is crucial to keep the user happy.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;But latency can also be an important property even without human interaction. In the context of cron-started batch jobs it might be the time from the input-file is read until the processing has committed to the database. The latency for this processing might have to be short enough so the result does not miss next batch downstream. E g it might be crucial that the salary-calculation is finished before the payment-batch is sent to the bank on salary day.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In a less batch-oriented scenario the system might process data asynchronously, pulling it from one queue, processing it, and pushing it onto another queue. Then the latency will be the time it takes from data being pulled in until the corresponding data is pushed out at the other end.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;All in all, the latency is seen from the perspective of one single request or transaction. Latency talks about how &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;fast&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;the system is from one traveller's point of view. Latency is about "fast" in the same way as an F1-car is fast, but will not carry a lot of load.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Throughput or Capacity&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;On the other hand, &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;throughput&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;or &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;capacity&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;talks about how much work the system can process. For example, a news information portal might have to handle a thousand simultaneous requests — because at nine o'clock coffee break a few thousand people might simultaneous surf to that site to check out the news.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Throughput is also important in the non-interactive scenario. Each salary-calculation might only take a few seconds, but how many will the system be able to process during those 10000 s between midnight (when it starts) and 02:45 when the bank-batch leaves. If we cannot process all 50 000 employees, some will complain. To meet the goal we need a throughput of five transactions per second.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In other words, where &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;latency&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;was the performance from the perspective of &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;one&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;client or transaction, then &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;throughput&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;is the performance seen from the perspective of the collective of all clients or transactions, how much load the system can carry. Here "load" in the same way as a bus will take a lot of load transporting lots of people at once, even if it is not fast.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Fastness vs Load Capacity&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Both F1 cars and heavy-duty trucks are no doubt "high-performing" cars. But they are so in completely different ways. To have a F1 car showing up at the coal mine would be a misunderstanding that only could be matched by the truck at the race track.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;So, I avoid talking about "performance" and risk misunderstanding. Instead I try to use "latency" and "response time" to talk about how fast things happen — while thinking about an F1 car. &amp;nbsp;And I use "throughput" and "capacity" to talk how much load the system can handle — while thinking about a bus full of people.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;What is the latency for transporting yourself between Stockholm and Gothenburg using a F1 car or public-transport bus? What is the throughput of transporting a few thousand people from Stockholm to Gothenburg using an F1 car or public-transport bus?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Yours&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Dan&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;P s Now when we are &lt;a href="http://dearjunior.blogspot.com/2010/09/multicore-power-and-performance.html"&gt;moving to multicore&lt;/a&gt;, we will see increasing capacity but latency leveling out or getting worse. This in itself will be a reason to move to non-traditional architectures, where I think the event driven architectures (EDA) is a good candidate for saving the day. &lt;/span&gt;&lt;a href="http://javazone.no/incogito10/events/JavaZone%202010/sessions/Multicore%20and%20Event%20Driven%20Architectures"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;My presentation&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; at the upcoming &lt;/span&gt;&lt;a href="http://jz10.java.no/"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;JavaZone&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; will mainly revolve around this issue.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-3676019087421937927?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/3676019087421937927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/two-types-of-performance.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3676019087421937927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/3676019087421937927'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/two-types-of-performance.html' title='Two Types of Performance'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-8749630760901409931</id><published>2010-08-23T11:30:00.001+02:00</published><updated>2010-08-23T11:30:00.061+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophical'/><title type='text'>Agile is Different</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;From time to time I hear, see, or read how Agile is explained as "it&amp;nbsp;is no news" or "it is the same old good project management, with some&amp;nbsp;twists". My impression is that this is done as an attempt to make&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Agile less scary to make it easier to "sell" to management. I think&amp;nbsp;this is a serious mistake. I think that in subtle but fundamental and&amp;nbsp;important ways - at its heart and roots - &lt;i&gt;Agile is different&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The difference is subtle because you cannot observe it directly. Any&amp;nbsp;and all of the things you can see in an Agile-honouring organisation&amp;nbsp;can easily be copied. There are software delivered in short and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;regular intervals, there are team retrospectives, and daily&amp;nbsp;team-meeting. And all of these practises can be used in a&amp;nbsp;traditionally managed organisation as well, but it &lt;i&gt;does not&lt;/i&gt; make that&amp;nbsp;organisation Agile.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To me the fundamental difference is in &lt;i&gt;how you look at humans&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Traditional management use humans as building parts to build a&amp;nbsp;software-producing machine, or a factory. In this machine people are&amp;nbsp;the moving parts and they are strung together by a processes that&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;dictated their interactions. At the end of the process, software&amp;nbsp;emerges. It is very mechanical. For example, in this world it would be&amp;nbsp;very strange if people would arbitrarily start changing the process -&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;then the designed process might just break and who knows what would&amp;nbsp;happen. So that cannot be allowed.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I might be guilty of over-exaggerating, but the practice of constantly&amp;nbsp;referring to people as "resources" to me unveils an outlook on people&amp;nbsp;that I find scary.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The view of humans in Agile is different. In Agile we acknowledge that&amp;nbsp;it is the engagement and skills of people that make things happen. We&amp;nbsp;make it a first-order concern that people should feel motivated and&amp;nbsp;proud. And instead of a mechanical world view, we rely on a more&amp;nbsp;organic view of organisations. If people want to &lt;a href="http://dearjunior.blogspot.com/2010/07/in-agile-practitioners-own-process.html"&gt;change the process&lt;/a&gt;&amp;nbsp;they are not only allowed, they are encouraged to do that — even if we&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;do not know the precise effect it will have on the overall system.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To explain this, I think it is easiest to look at the Agile Manifesto.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The first of its values is:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;Individuals and interactions over processes and tools&lt;/i&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is not a small thing. Here lays a fundamental difference in how&amp;nbsp;we look at people and organisations. A traditional process is defined&amp;nbsp;by a single person at a single point of time. However, the wisdom and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;insight of that person at that time is nothing - absolutely nothing -&amp;nbsp;compared to what can be achieved by having each involved person&amp;nbsp;thinking and discussing with their peers - and doing so&amp;nbsp;continuously. And if given the choice between an ever-so-well defined&amp;nbsp;process on one side and trusting the &lt;i&gt;wisdom of the crowd&lt;/i&gt; on the other&amp;nbsp;hand, we chose the crowd any day of the week.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It is a little bit like democracy. We &lt;i&gt;could&lt;/i&gt; trust a wise and benign emperor. However, we think we get a better result if all citizens engage in an open discussion. We create and change our laws according to that discussion - even if we do not know the result in advance.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In this perspective Agile is a celebration of the wonderful and&amp;nbsp;mysterious system that emerge from initiatives that rise out of&amp;nbsp;interaction between people that care.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;This is also what can be seen in the fifth principle of the Agile Manifesto:&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;Build projects around motivated individuals.&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;Give them the environment and support they need,&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;and trust them to get the job done.&lt;/i&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;We actually trust that people &lt;i&gt;want&lt;/i&gt; to work. We acknowledge that we&amp;nbsp;need to give them the proper environment and tools, but that will be&amp;nbsp;enough. There is no need to command and control. Things will just&amp;nbsp;happen. It is a leap-of-faith to let control go. Organisations with&amp;nbsp;traditional management dare not take that leap. Agile does.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, when looking at a traditional organisation or project and&amp;nbsp;comparing that one with one honouring Agile, you might not see much of&amp;nbsp;a difference. But if you are inside of it, you&lt;i&gt; feel the difference&lt;/i&gt;. It&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;is there - at the heart. You feel trusted and empowered. And if you&amp;nbsp;look closely you might see it as well - the small smile on peoples&amp;nbsp;faces.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The difference is subtle. But it is fundamental. And it is important.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I am convinced that at its roots and heart - Agile is different.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-8749630760901409931?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/8749630760901409931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/agile-is-different.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8749630760901409931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/8749630760901409931'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/agile-is-different.html' title='Agile is Different'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-4571422253395925117</id><published>2010-08-20T08:15:00.006+02:00</published><updated>2010-08-25T07:45:34.059+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><category scheme='http://www.blogger.com/atom/ns#' term='requirement'/><title type='text'>Two Observations on Overtime in Traditional Projects</title><content type='html'>Dear Junior&lt;br /&gt;I have seen quite a few classically managed projects, and through friends and collegues I have been in contact with even more of them. I would just like to make two observation on the practice of working&lt;br /&gt;overtime in different phases of such projects.&lt;br /&gt;&lt;br /&gt;* It is very uncommon, actually I have neither experienced nor heard of, that project management orders overtime for requirements analysists so that they will deliver the full and finished requirement documentation on a specified date.&lt;br /&gt;&lt;br /&gt;* It is very common, actually I have experienced it several times myself and heard of it numerous times, that project management orders overtime for programmers so that they will deliver the full and finished implementation on a specified date.&lt;br /&gt;&lt;br /&gt;From these two observations it is probably possible to deduct lots of interesting conclusions. I will refrain from doing so here and leave it up to you as an interesting mind-game.&lt;br /&gt;&lt;br /&gt;Yours&lt;br /&gt;&lt;br /&gt;Dan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-4571422253395925117?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/4571422253395925117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/two-observations-on-overtime-in.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4571422253395925117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4571422253395925117'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/two-observations-on-overtime-in.html' title='Two Observations on Overtime in Traditional Projects'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-7673143986811143776</id><published>2010-08-18T08:01:00.002+02:00</published><updated>2010-11-23T07:48:47.762+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='application security'/><category scheme='http://www.blogger.com/atom/ns#' term='sql injection'/><category scheme='http://www.blogger.com/atom/ns#' term='xss'/><category scheme='http://www.blogger.com/atom/ns#' term='domain driven design'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>DDS Value Object Presentation Video</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;At the OWASP AppSec conference I had a presentation on value objects&amp;nbsp;and Domain Driven Security. It turned out into a 35 minute code kata&amp;nbsp;with refactorings, where I used value objects "DDD style" in two ways.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Firstly, I used them to create a design that makes indata validation&amp;nbsp;come natural in the context of Injection Flaws. I used the classical&amp;nbsp;SQL Injection login-attack as an example and applied "hard type" value&amp;nbsp;objects in the same way as &lt;a href="http://dearjunior.blogspot.com/search/label/sql%20injection"&gt;we have discussed before&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Secondly, I addressed a Cross-Site Scripting (XSS) scenario. Here I&amp;nbsp;noted that even if XSS is often perceived as a problem with "bad&amp;nbsp;indata", there are cases when those data are perfectly valid. So,&amp;nbsp;instead I choose to look at it from an output-encoding perspective -&amp;nbsp;not "bad indata validation", but "bad outdata encoding".&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To be able to do something about the outdata encoding, you can think&amp;nbsp;about the client side browser as a subsystem of your system. Seen that&amp;nbsp;way, the presentation tier plays the role of the API to that&amp;nbsp;subsystem. Then it becomes obvious that we should enforce proper&amp;nbsp;encoding at the border of that subsystem - i e in the API we use for&amp;nbsp;calling it.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Modifying the presentation tier API from "soft type" strings to "hard&amp;nbsp;type" value objects made it obvious where proper encoding should go -&amp;nbsp;thus solving the XSS problem.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The full video coverage from the conference has been released, and &lt;/span&gt;&lt;a href="http://owasp.blip.tv/file/3918040/"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;my  presentation&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; can be found at the &lt;/span&gt;&lt;a href="http://www.owasp.org/index.php/OWASP_AppSec_Research_2010_-_Stockholm,_Sweden#Value_Objects_a_la_Domain-Driven_Security:_A_Design_Mindset_to_Avoid_SQL_Injection_and_Cross-Site_Scripting"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;OWASP website&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dan&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-7673143986811143776?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/7673143986811143776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/dds-value-object-presentation-video.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7673143986811143776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/7673143986811143776'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/dds-value-object-presentation-video.html' title='DDS Value Object Presentation Video'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-6156044685809176397</id><published>2010-08-12T09:02:00.001+02:00</published><updated>2010-08-12T16:46:13.735+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum master'/><category scheme='http://www.blogger.com/atom/ns#' term='coach'/><title type='text'>Blitz Retrospective</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One of my favourite method tools is a retrospective format I call the&amp;nbsp;"Blitz Retrospective". I have used it in a lot of situation where it&amp;nbsp;has been impossible to do "large" retrospectives. For example, in some&amp;nbsp;situations, the teams have been very "retrospective sceptic". In&amp;nbsp;other, there has been a formally appointed "scrum master" who was not&amp;nbsp;very open to suggestions, so suggesting changes to his retrospectives&amp;nbsp;would not achieve much. In yet other, the sprints have been so long I&amp;nbsp;have not had the patience to wait a few weeks. In all these situations&amp;nbsp;it has been possible to suggest, and do, a "really quick&amp;nbsp;retrospective".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The "Blitz Retrospective" only takes 25 minutes, and its focus is to&amp;nbsp;find *some* change the team think would improve things.&amp;nbsp;The format consists of three parts: the startup, collection of ideas, and vote.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Startup&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If it is the first time, the startup is spent explaining the format so&amp;nbsp;everybody feels comfortable with what will happen. I clarify that the&amp;nbsp;purpose is to find &lt;i&gt;one single&lt;/i&gt;&amp;nbsp;idea of improvement that we will &lt;i&gt;try&amp;nbsp;out&lt;/i&gt; next week.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;A question that always come up on purpose is why we are limited to one&amp;nbsp;idea, and what happens with the rest. Well, if the timespan is only a&amp;nbsp;week, it would be foolish to focus on more that one thing - it would&amp;nbsp;just result in none of them being changed.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;As for the rest of the&amp;nbsp;ideas that come up - they will be there in the back of peoples minds&amp;nbsp;and might change things implicitly - but they will not be actively in&amp;nbsp;focus.&amp;nbsp;If it is not the first time, I usually quickly rehearse the procedure,&amp;nbsp;but I spend the time on evaluating the last retrospective's "winning&amp;nbsp;idea" - more on that later.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The startup in full should not take more than five minutes.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Collection of Ideas&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Second section is the collection of ideas. To help the team members I&amp;nbsp;split a whiteboard in three sections labeled "Continue/Increase",&amp;nbsp;"Start/Try", and "Quit".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;First section "Continue/Increase" is for things we already do and that&amp;nbsp;support our work. Second section "Start/Try" is for ideas that we&amp;nbsp;think we should benefit from, but we do not do it already, at least&amp;nbsp;not in any significant amount. Last section "Quit" is for things team&amp;nbsp;members think we do, but should stop doing as it does not serve us&amp;nbsp;well, or even harm us.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Then team members are free to write down suggestions in any of these&amp;nbsp;sections. Usually, I let them write on stickies, so that they can&amp;nbsp;write a short statement on the sticky and explain it briefly when they&amp;nbsp;post it on the board. If a short discussion emerges, then fine.&amp;nbsp;However, if it seems to turn into a debate, or risk running long, I&amp;nbsp;cut it short pointing to the purpose (find one idea) and the procedure&amp;nbsp;(there will be a vote later).&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I also try to convince the team to keep the suggestions very concrete&amp;nbsp;and limit them to thinks they directly can effect. For example,&amp;nbsp;replacing the ventilation system of the building might really improve,&amp;nbsp;but selecting such improvements is just asking for failure. In other&amp;nbsp;retrospective formats such ideas are really valuable, but the purpose&amp;nbsp;of Blitz Retrospective is basically to get acceptance for&amp;nbsp;retrospectives - and then they must make a difference. We want things we actually can do, and that we can do within a week.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;The collection of ideas could take ten to fifteen minutes. On&amp;nbsp;occasions when time has not been an issue, I have let it run on longer&amp;nbsp;- but usually most ideas are on the board after ten minutes.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Grooming the List of Suggestions&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;When getting closer to the end of collection of ideas, I take a more&amp;nbsp;active role, starting talking about the stickies in the "Quit"&amp;nbsp;section.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;It is extremely valuable to get the "Quit" feedback, and I really encourage people to post such suggestions. However, I am a firm believer of that you should focus on "telling the good stories", because the stories you tell (and repeat) will become part of the "team lore" and shape the atmosphere of the team work. This is the basic idea behind the organisational philosophy "&lt;a href="http://appreciativeinquiry.case.edu/"&gt;Appreciative Inquiry&lt;/a&gt;".&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, telling "bad stories" will basically make people feel bad - but not do much good in the long run. Telling "good stories" will culture a nice team atmosphere as well as enforcing the good habits.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Therefore I take on the role as the "positivist&amp;nbsp;fanatic" and try to rephrase each sticky under "Quit" into "positive" ones. For example, if a quit-note says "stop coming late to meetings", I might suggest a start-note "meetings begin exactly on time - even if people are missing".&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Before throwing away the "Quit" not I ask the original poster whether the new notes have captured the original purpose. Surprisingly often there is an additional aspect I had not understood. In the "begin on time" example, the poster might say: "It is not only about starting on time, it is also that every time someone arrive (late) there is a start of chit-chat and small talk that disrupts the meeting". To capture this there will be a second note start-note "keep meeting focus when people arrive mid-meeting".&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I also ask if there are some suggestion that the poster think is a duplicate&amp;nbsp;of some other - if so they can have it removed. Merging two similar suggestions to one of course gives them a better chance to "win".&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Still when "grooming", the board is still open for new ideas, it is just for the team members to step up, post a sticky, and present the idea.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;At the end of collection of ideas there often are a load of ideas and&amp;nbsp;we only have a few minutes until we shall leave the room with one&amp;nbsp;selected idea: time to vote.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Voting&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;For the voting, I simply rearrange the stickies and let each team&amp;nbsp;member give three suggestions one vote each. The sticky with the most&amp;nbsp;votes is the winner and is what the team should try for improvement&amp;nbsp;the coming week.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;As for the rest - things might improve just by having vented them, but they are not in active focus.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Evaluation&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Next week I use the startup section for a quick evaluation. Here I want to separate two parts.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;One question is whether we did as we intended at all. Not trying isn't necessarily failure. Things change quickly from time to time and we might have had valid reasons not to do it. Even "did not have time" is a valid reason - and suggests that we should put aside time.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If the team did try the suggestion, the second question is whether it helped us or not. If it was helpful, we try keep doing it. If it was not helpful, then it is important to keep in mind that it was an experiment - and such &lt;i&gt;should&lt;/i&gt; have positive and negative outcomes from time to time.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If the suggestion was tried and found helpful, we should find a way to formalize it. Technical stuff might go into a new check on the build server, working habits might go into the team's "Team Rules" or "Working Agreements" - whatever the name. The important part is that we do something that makes it plausible we will continue doing this good thing we have just found.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;Getting Retrospectives Going, at All&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I have found that running a few Blitz Retrospectives often results in&amp;nbsp;an acceptance of having retrospectives at all. In combination with the&amp;nbsp;not-very-scary format "ok, we can spare 25 min after Friday lunch", it&amp;nbsp;is a good way to get retrospective started at all.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course, such a brief format misses many points - things a longer&amp;nbsp;and deeper retrospective will catch. But the purpose of Blitz&amp;nbsp;Retrospective is not to catch those - it is to win acceptance for&amp;nbsp;having retrospectives at all an pave way for deeper retrospectives&amp;nbsp;down the road.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;I have found that the format works well for that purpose.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ps Ester Derby and Diana Larsen have written a great book named &lt;/span&gt;&lt;a href="http://pragprog.com/titles/dlret/agile-retrospectives"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Agile Retrospectives&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt; that is really helpful once you have gotten past that initial resistance, have established retrospectives, and want to elaborate them, specialise them, or just improve them in general.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;pps Tobias Fors has made the point (&lt;a href="http://scrumtipsblogg.blogspot.com/2010/08/aterblickens-grundregel.html"&gt;blog post in Swedish&lt;/a&gt;) that feeling safe and secure is fundamental to engaging in a retrospective. He suggests the fundamental rule being "Everyone did their best given the conditions", and I have seen it helpful to start each retrospective with writing some similar statement on the whiteboard.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-6156044685809176397?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/6156044685809176397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/blitz-retrospective.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6156044685809176397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/6156044685809176397'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/blitz-retrospective.html' title='Blitz Retrospective'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-4456556499430715398</id><published>2010-08-04T12:45:00.008+02:00</published><updated>2010-08-04T21:35:13.358+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Typewriting is not Storytelling</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If you would observe a famous author during a workday to get insights&amp;nbsp;in how such people work, you might come out with a report along these lines.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;"After breakfast, Famous Author sits down at the typewriter. She then&amp;nbsp;punches the keys, using the tip of her fingers, repeatedly. From time&amp;nbsp;to time she picks a new blank page and roll it into the typewriter.&amp;nbsp;She continues until early afternoon, except for a lunch break,&amp;nbsp;whereafter she walks around in town taking pictures of people."&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Even the Famous Author herself might describe her workday in a similar&amp;nbsp;way ("do always write at least ten pages a day" or "only write when&amp;nbsp;inspired"), describing the structure of the work, or the ceremonies&amp;nbsp;surrounding it.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Correct as these descriptions might be, they totally miss the point.&amp;nbsp;They tell you nothing about weaving a plot, about evolution of&amp;nbsp;characters, about where to start the story, about how to finish it,&amp;nbsp;or other things that makes the work worth reading.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Unfortunately, I have the feeling that many descriptions of agile&amp;nbsp;practices make the same mistake.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-4456556499430715398?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/4456556499430715398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/08/typewriting-is-not-storytelling.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4456556499430715398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/4456556499430715398'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/08/typewriting-is-not-storytelling.html' title='Typewriting is not Storytelling'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-2172854051300051496</id><published>2010-07-23T11:43:00.018+02:00</published><updated>2010-08-03T23:00:02.117+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='process'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><title type='text'>In Agile, the Practitioners Own the Process</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;T&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;he term "process management" might be one of the driest around in system development, but in the shift to agile, the term hides a secret both surprising and delightful.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande';"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times; font-size: medium; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Times; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 11px;"&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Demystifying "process", is nothing but our daily habits, what we do when creating systems. Examples of process include how we decide when we commit stuff, how we manage our requirements, whether we do pair programming, when to do code reviews, how we decide something is finished , etc. It is really about our every-day habits of life when working.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Put that way "process management" becomes how we decide what habits we should have, or how we change them, like if we should introduce code review, or take them away, if we should be more rigorous on "no failing tests" when committing, etc.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Put that way "process management" is simply how we get better at development over time.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Process Management Traditional Style&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In traditional process management each organisation has some kind of authority that decides what process we should follow. It might come in the form of a "Chief Process Officer" or as a "Project Office", but the point is that somewhere we&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;decide&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;the process. The groups that do the daily work of creating and maintaining systems are then to follow this process. These groups can be projects, maintenance groups or have some other organisational structure. For simplicity let us call them "practitioners" for short. So, project office&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;decide&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;the process, practitioners&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;follow&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;the process.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In many cases "project office decide, practitioners follow" is an illusion. There actually exist (take my word for it) project offices that write a process behind locked doors and then hand out a binder to the rest of the org, while believing the process will be followed. Truth is that those documents will never be read outside the project office, and will obviously not be followed. &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;As an example, the project office might have decided that all code should be reviewed, and then fully believe that so is done — because it is in the process. The truth might be that no code is ever reviewed at all and the practitioners might not even know code review is part of the formal process. This "alienated project office" is of course a process management anti-pattern.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;A good process office traditional style will of course behave differently. It will stay in touch with the practitioners and check whether the process is followed. If it is not, they will question why it is not followed, and explain the rationale of why they process look the way it does. It will also gather feedback and change the process to better fit &amp;nbsp;changed of discovered needs.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;However, even if the project offices adapt the process upon request, it is still in charge. If a practitioner what to change the process (e g "continuous, automated deployment to test environment"), she will suggest that change to the project office that will evaluate it. If the project office thinks it is a good idea, they will change the process, and the practitioner can start following the improved process. However, the practitioner cannot single-handed change the process just because she thought it was a "nice idea, worthy to give a try".&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Process Management Agile Style&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Agile development on the other hand relies heavily on the idea of continuous improvement. The basic idea is that that the process you have today is just the best you have come up with this far. Further more, the challenge of today is to find out what you should do different tomorrow. Agile development also honours doing experiments — if you get an interesting idea, then try it out for some time. At next retrospective, you evaluate the change and keep the it if it proved beneficial — or throw it away and try something else.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Experimentation is not only a right in agile, it can also be claimed to be a responsibility. Taking it to an extreme, it can even be claimed that if you have not changed your process in some significant way the last year, you are probably no longer agile. It is probably a sign you no longer do experimentation coming up with no ideas to try. That you have found "the perfect process" is just to improbable to be likely.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Here comes the mind-shift: for the practitioners to do this experimentation, they should have a mandate to do these continuous changes to the process. In other words, they should be empowered to change the process (ever so slightly)&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;at their own will&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;.They should&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;not&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;need to ask project office for permission. We want to keep the threshold for new ideas as low as possible.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Rephrased, the practitioners are actually unilaterally allowed to change the process. They now&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;own the process&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;they follow themselves, it is no longer owned by the project office.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Project Office Still Valuable&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;This does not mean that the project office becomes obsolete. Quite the opposite, it might even become more important. When all practitioners can form their process, it becomes even more interesting to have some group that pays attention to all these changes, gather the changes that where successful, and can&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;promote cross learning&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;between practitioners of different groups.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;A team might for example struggles with that some pieces of the code is only understood by one single developer. Independently another team has solved a similar situation by using pair programming whenever such code is touched. The project office might then recognise the situation and suggest that the struggling team try that method to see if it will help them.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;At this point of time the Project Office might change its name to enforce their new role. Some have re-branded themselves as the Agile Office, which I think is nice turn.&amp;nbsp;&lt;/span&gt;&lt;a href="http://blog.mountaingoatsoftware.com/"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Mike Cohn&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;has reported that at one of his clients they called this group the "Agile Enablement Team" to emphasise that their goal is to enable other to become more agile.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;What about Standard Process&amp;nbsp;&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In agile process management you can still have a standard process. The difference is that the standard process will not be pre-defined, but rather&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;emerge&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;. The project office will gather ideas that have worked at some team, e g "pair program on baldy understood code", &amp;nbsp;and suggested it to some other team. If it worked at the second team as well it will promote the idea a little more active, and if it fits the organisation as a whole, it will soon enough be a standard among most or all teams. At this point "pair program on badly understood code" has become part of a&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;de facto standard&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Over time, more a more practices will emerge and spread to all teams and a standard process will be formed. But, it will only do so if those practices actually work well throughout the organisation. And, it will not be cut in stone, but open to be challenged and evolved in the same dynamical manner.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;So, the standard process will not become a standard process because someone say so, instead it will become the de facto standard process because a majority of the teams have tried and found the same set of ideas valuable and fit within the organisation. Here the project office plays a key role in facilitating and guiding this evolution so that the good ideas are spread and that the practises have a chance to converge instead of diverging.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;The Shift&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In traditional process management, the process is owned by the process office and followed by the practitioners.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;In agile process management, the process is owned by the practitioners and facilitated by the process office.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Small mind shift in theory, huge difference in practice.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Yours&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&amp;nbsp;&amp;nbsp; Dan&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;P.s. The situation of the Project Office in an agile environment resembles very much the situation of the architect who is&amp;nbsp;&lt;/span&gt;&lt;a href="http://dearjunior.blogspot.com/2009/07/not-enforcing-architecture.html"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;unable to enforce architecture&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;, but instead must work with the practitioners to explain and evolve it.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-2172854051300051496?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/2172854051300051496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/07/in-agile-practitioners-own-process.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/2172854051300051496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/2172854051300051496'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/07/in-agile-practitioners-own-process.html' title='In Agile, the Practitioners Own the Process'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-1070622699079614235</id><published>2010-07-15T09:58:00.003+02:00</published><updated>2010-07-15T12:48:00.932+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Refactoring as Time Machine</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Dear Junior&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;If I had a time machine, I would not need to worry very much on how to&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;invest my retirement pension plan. I could just pick any random fund,&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;and if that one turns bad, I could just travel back in time and pick&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;one that will succeed instead.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Now, who said that time travel should be free? If nothing else, the&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;power to run it should send your electricity bill to unusual heights. &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So each time travel will certainly come with a fee. However, if it&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;enables me to "have made" a better choice of pension plan thirty years&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;ago, it would probably be worth it.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;The Existential Angst of Making Decisions&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;How wonderful would that be, to not have to spend effort and energy on&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;finding what hopefully is the best, and then have to worry about&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;having made the wrong decision.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Unfortunately, I have no time machine. And chances are I will not have&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;one either when time comes for me to retire, about thirty years from&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;now.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;So, boring and uninteresting it might be, I have to spend time and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;energy on investigating different choices to make a good one. And live with the angst.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;In System Development We also make Decisions&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;When developing software, I constantly have to make a lot of&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisions, small or big. It might be just what to name a method, or it&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;might be how to split the system in tiers; still decisions, decisions,&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decisions. And, all those choices affect how easy the system will be&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;to work with in the future - picking the wrong choice, and I will have&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;a hard time.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Sometimes I find that I have earlier made a design- or architecture&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decision that "seemed like a good idea at the moment", but now feels&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;like crap. Perhaps I should have spent a little more time and effort&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;thinking over all possible futures?&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;i&gt;In System Development We Have a Time Machine&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;To my delight, I have found that in system development I have the time&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;machine I lack in financial investments. Often some&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;not-too-complicated refactorings can "take me back in time" and change&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;that template method solution (that does not suite me well any longer)&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;to a shiny state and strategy pattern (that does suit my current&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;needs).&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Of course, the refactoring time travel is not for free - there is a&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;fee to be paid in the work I have to do and the testing to ensure it&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;went well. However, that fee is much lower than paying the price of&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;continue working with a code-base that is not well aligned with my&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;best-idea-at-the-moment.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Obviously, I still have to spend enough time and energy to find a&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;decent solution when making a choice. The difference is that I do not &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;have to spend the enormous effort to cover all options. The&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;possibility of making future refactorings simply shrews the economics&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;of making a decision. Refactorings make it possible to settle for a&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;good solution now, keep the speed up, and pay the small fee for&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;changing your mind in the future. And I can skip the "angst" part.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;In that way refactoring is a wonderful little time machine.&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Yours&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&amp;nbsp; Dan&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;Ps The ability to do refactorings in the future makes it possible to keep options open longer, thus deferring decision-commitment. This is what I see as the central message of the &lt;a href="http://www.infoq.com/articles/real-options-enhance-agility"&gt;Real Options&lt;/a&gt;-movement.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7928985878402740088-1070622699079614235?l=dearjunior.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dearjunior.blogspot.com/feeds/1070622699079614235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dearjunior.blogspot.com/2010/07/refactoring-as-time-machine.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1070622699079614235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7928985878402740088/posts/default/1070622699079614235'/><link rel='alternate' type='text/html' href='http://dearjunior.blogspot.com/2010/07/refactoring-as-time-machine.html' title='Refactoring as Time Machine'/><author><name>Dan Bergh Johnsson</name><uri>http://www.blogger.com/profile/07991087192133138300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_YBdrg97aiE0/TBcl0cBo07I/AAAAAAAAACk/1Bc4IswjTYA/S220/danbjcoffe.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7928985878402740088.post-6135951871392476385</id><published>2010-07-07T23:50:00.027+02:00</published><updated>2010-11-10T16:32:29.780+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='knowledge'/><category scheme='http://www.blogger.com/atom/ns#' term='domain driven design'/><category scheme='http://www.blogger.com/atom/ns#' term='user story'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Complexity Drives Effort</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', serif;"&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;Dear Junior&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;There has been a &lt;a href="http://www.infoq.com/news/2010/07/story-points-complexity-effort"&gt;recent discussion on story point estimation&lt;/a&gt; (or&amp;nbsp;sizing) that is so common in Scrum. Especially the discussion has been about how sizes should relate to complexity &amp;nbsp;and to effort needed to complete story. In a &lt;a href="http://blog.mountaingoatsoftware.com/its-effort-not-complexity"&gt;blog post&lt;/a&gt; Mike Cohn made a good example between effort and&amp;nbsp;complexity by comparing "licking a thousand stamps" on one side, and&amp;nbsp;"performing a simple brain surgery" on the other side. These where&amp;nbsp;assumed to take approximately the same effort, but had drastically&amp;nbsp;different complexity. Point was that they should have same amount of&amp;nbsp;story points.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;&lt;i&gt;It is Effort that Makes a Difference&lt;/i&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;I think there is a lot of merit to the point Mike makes that it is&amp;nbsp;amount of effort that is the usable parameter - we need it to make&amp;nbsp;rough cost estimates and to predict what&amp;nbsp; functionality can plausibly&amp;nbsp;be released when. Complexity is not usable in the same way.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;However, even if "effort" is what we primary care about, to me&amp;nbsp;complexity plays a very central role - more than I have seen mentioned&amp;nbsp;in the discussion. To clarify I would like to dive into the&amp;nbsp;thousand-stamps-example.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;&lt;i&gt;Story is Effect, not Task&lt;/i&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;To start with, the team should not get a story saying: "lick a&amp;nbsp;thousand stamps"; because that prescribes a specific solution. A good story should only point out the desirable effect, and leave to the team to pick a good solution. I guess the story could instead have read:&amp;nbsp;"ensure a thousand stamps get licked", or something&amp;nbsp;along that line. The difference is subtle but important. In the first&amp;nbsp;case, the team is given a task to perform. In the second case, the&amp;nbsp;team is given a problem to be solved.&amp;nbsp;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;&lt;i&gt;Bulk Driving Effort&lt;/i&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;If you are to lick ten or a hundred stamps, you will certainly just do it. If you are to lick a thousand you will get mighty bored and tired - with ten seconds per stamp that amounts to three hours of work. However, it is still manageble, so&amp;nbsp;you just get onto it. So here the effort will be driven by the bulk of the job - more stamps, more effort.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;However, if you are to lick ten thousand stamps, or a million, then you are facing another magnitude of effort. To lick a million stamps would take 10 000 000 seconds, which is 70 weeks of&amp;nbsp;full-time work - the better part of two years. Facing that task I would probably start building a stamp-licking machine.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;Interesting enough this changes the game. The effort of building such a machine is independent of the amount of stamps to be licked. It is roughly as hard to build such a machine whether it will lick thousand or ten million stamps. So, bulk does no longer drive the effort.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;&lt;i&gt;Complexity Driving Effort&lt;/i&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;So, how hard is it to build a stamp-licking machine. Well, the actions involved is pretty straight forward, there are only one set of maneuvers, and no decisions to make - so, not-too-hard is a fair guess.&amp;nbsp;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;And here comes the other half of the interesting change of the game. The effort is decided by how hard it is to build such a machine - i e the complexity of the task. So, bulk does not drive effort any longer, instead it is the complexity of the task that drives the effort.&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;&lt;i&gt;Software Development Teams do not do Bulk&lt;/i&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; min-height: 16.0px; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font: 14.0px Georgia; margin: 0.0px 0.0px 0.0px 0.0px; text-align: justify;"&gt;Going back to software domain, the equivalent of licking lots of&amp;nbsp;stamps (10 seconds each) is probably to send a pre-formatted mail to a&amp;nbsp;long list of email addresses found in an excel sheet ("new mail", CnP&amp;nbsp;mail content from template, CnP email from next line in she
