<?xml version="1.0" encoding="utf-8"?><rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Bjarte.Com</title><description>Software architecture,design, process and business</description><language>nb-NO</language><item><guid isPermaLink="false">0dc1a2f5-1b37-48de-b152-1a26f4062003</guid><link>http://bjarte.com/post/my-fresh-new-blog</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>My fresh new blog</title><description>&lt;p&gt;This weekend I have published my new blog. Before my blog was hosted by Tumblr, but as a true programmer I needed to write my own. I have focused on making the blog as feature-free as possible. I have no admin interface, I just use Windows Live Writer. For comments I use Disqus.&lt;/p&gt;  &lt;p&gt;The blog is running on my own virutal server hosted by ISPHuset ( in Norway).&amp;#160; Having my own web server with the flexibility it brings is great.&lt;/p&gt;  &lt;p&gt;The reason for writing a new blog framework is learning. At work you are confined to work with the tools that get the job done. When writing your own software you can experiment.&lt;/p&gt;  &lt;p&gt;I decided to try out Autofac for dependency injection, Db4o as a storage and Moq as mocking framework. Usually I would use Structuremap, NHibernate and RhinoMocks. &lt;/p&gt;  &lt;h3&gt;Autofac &lt;/h3&gt;  &lt;p&gt;Autofac is ok. It has all the features that I usually use in StrutureMap. The only problem with Autofac is the documentation. Going from version 1 to 2 Autofac has changed its entire API and its conventions. Googeling for help is not easy, as you never know if what your read is version 1 or 2. Documentation is a problem with most OS projects and there should be a better way. &lt;em&gt;I have been playing with the thought of creating a web site that can deal with this issue&lt;/em&gt;. All in all, I give Autofac a 4/6 ;)&lt;/p&gt;  &lt;h3&gt;Db40&lt;/h3&gt;  &lt;p&gt;I have not worked a lot with Document or Object databases before, so working with Db4o was interesting.&lt;/p&gt;  &lt;p&gt;Getting started is very easy:&lt;/p&gt;  &lt;pre&gt;_db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), fileName);
_db.Store(myObject);&lt;/pre&gt;

&lt;p&gt;That’s all you have to do as long as you have a reference to the Db4o dll. Easy schmeasy. I did run into some problems. Consider having a Post object with a list of Tags. So you insert all your posts into the Db and now you want a list of all tags without pulling out every single post in the database. Suddenly you realize you are not dealing with a relational database anymore.&lt;/p&gt;

&lt;p&gt;Luckily Db4o has Linq support, so you can query your object without pulling them out of the database. In my case I created a Tag object and asked the database for a unique list of Tags. I’m no master of Db4o so the solution I found might not be the best one.&lt;/p&gt;

&lt;p&gt;Using Db4o is very easy in the simple cases, but things easily gets tricky when dealing with relationships. For me to use Db4o effectivly in the future I need to learn more about it, and frankly, I don’t think I want to spend the time. I have more faith in document databases, so maybe I will try out Mongo next time.&lt;/p&gt;

&lt;h3&gt;Moq&lt;/h3&gt;

&lt;p&gt;I did’t get to use Moc a whole lot. My first impression is that Moq has a much cleaner interface compared to Rhino Mocks. I think I will be using Moq in the future.&lt;/p&gt;

&lt;h3&gt;Continous deployment is great&lt;/h3&gt;

&lt;p&gt;The smartest thing I have done is to set up a TeamCity server at home. Everytime I check my code&amp;#160; into GitHub, TeamCity get’s my changes and deploys them automatically to the Blog. Continous deployment should be mandatory for everybody developing software. Now, you don’t nessecarily need to deploy the changes directly to your customer, but at least you should do in-house deployment. Every single repetitive development task that can be automated should be. The reason ? It saves money and makes programming more fun !&lt;/p&gt;

&lt;h3&gt;Problems and bugs&lt;/h3&gt;

&lt;p&gt;Most of the challenges I faced when developing the blog was related to porting the data from the previous blog. I needed to support the Tumblr url schema /Post/[PostId]/[Slug], and also my new one /Post/[Slug]. Also I needed to move my images and make sure that the comment integration continued working. &lt;/p&gt;

&lt;p&gt;Making sure that all the RSS feeds continued working was also a challange. Some of you might have noticed that I suddenly released over 30 posts in Google reader. Not sure how I would prevent that behaviour. Hope it didn’t cause any problems. &lt;/p&gt;

&lt;h3&gt;Bjarte – the designer&lt;/h3&gt;

&lt;p&gt;I’m not really a web designer, but I have done some design work in the past. I focused on making the reading experience nice and I hope I have done&amp;#160; a good job. When It comes to the rest of the design I am pretty happy with it considering the fact that I’m a developer :) I know the design is different between IE and Chrome b.c. I have deliberately used some CSS 3 features that is not supported everywhere. Also the site doesn’t look good on 1024*800 monitors, and monitors with low contrast. Can’t please them all :)&lt;/p&gt;

&lt;p&gt;I have tried to make the HTML as clean as possible by relying on CSS to do most of the work, and letting the HTML be responsible for structure only. In the future I might spice up the site with some nifty JQuery action, but right now I’m content with maintaining a small feature set.&lt;/p&gt;

&lt;p&gt;That’s it for now. See you later :)&lt;/p&gt;</description><a10:updated>2010-03-14T10:41:33+01:00</a10:updated></item><item><guid isPermaLink="false">434270222</guid><link>http://bjarte.com/post/434270222</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Sometimes you are better off without comments</title><description>&lt;pre&gt;        /// &amp;lt;summary&amp;gt;
        /// Gets the constant value.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="exp"&amp;gt;The exp.&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        public static object GetConstantValue(this Expression exp){
           ...
        }
&lt;/pre&gt;
&lt;p&gt;I found this code in an open source project. It kinda looks like a joke, but it&amp;#8217;s not.&lt;/p&gt;</description><a10:updated>2010-03-08T08:48:00+01:00</a10:updated></item><item><guid isPermaLink="false">394350290</guid><link>http://bjarte.com/post/394350290</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Spot dirty code without reading it</title><description>&lt;p&gt;Sometimes you can identify bad code without reading it at all. If you have big arrows forming in your code  you should reconsider your solution. It  usually indicates a high &lt;a&gt;cyclomatic complexity&lt;/a&gt; (i.e unredable code). Can you see the arrow&amp;#160;?&lt;/p&gt;
&lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_kxz6tb5JV41qzl1ms.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img/&gt;&lt;/p&gt;</description><a10:updated>2010-02-17T08:43:00+01:00</a10:updated></item><item><guid isPermaLink="false">392690675</guid><link>http://bjarte.com/post/392690675</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>A little nasty one from the belly of the beast</title><description>&lt;p&gt;I was just skimming thru the ASP.NET MVC code and found this little nasty guy.&lt;/p&gt;
&lt;p&gt;You should never widen your interface to enable unit testing. Doing so is a code smell, and there is (almost) always a better way.&lt;/p&gt;
&lt;pre class="code"&gt; 
[SuppressMessage(
    "Microsoft.Usage", 
    "CA2227:CollectionPropertiesShouldBeReadOnly",
    Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
        protected internal ModelBinderDictionary Binders {
            get {
                if (_binders == null) {
                    _binders = ModelBinders.Binders;
                }
                return _binders;
            }
            set {
                _binders = value;
            }
        }
&lt;/pre&gt;</description><a10:updated>2010-02-16T13:47:00+01:00</a10:updated></item><item><guid isPermaLink="false">385212753</guid><link>http://bjarte.com/post/385212753</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Linq for javascript in one minute</title><description>&lt;p&gt;I do quite a lot of javascript and C# programming. Linq is one of the greatest things in C# and I was missing it in javascript, so I figured I could just implement what I needed. It took about one minute. Here is how I could improve  some of my code:&lt;/p&gt;
&lt;pre class="code"&gt;var a =[];
for (var i = 0; i &amp;lt; elements.length; i++) {
    a[a.length] = {
        name: elements[i].name,
        id: elements[i].id
    }
};
return a;

&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre class="code"&gt;return elements.select(function(item) {
    return {
        Name: item.Name,
        Id: item.Id
    };
});

&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre class="code"&gt;var res = [];
for (var i = 0; i &amp;lt; ids.length; i++) {
     for (var j = 0; j &amp;lt; this._currentList.length; j++) {
           if (ids[i] == this._currentList[j].Id)
               res[res.length] = this._currentList[j];
     }
}
return res;

&lt;/pre&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;pre class="code"&gt;return this._currentList.where(function(item) {
    return ids.contains(item.Id);
});


&lt;/pre&gt;
&lt;p&gt;The actual implementation I call Blinq (e.g.) Bjarte Linq :p&lt;/p&gt;
&lt;pre class="code"&gt;if (Array.prototype.where != undefined)
    throw new Error("Duplicatte method definition on Array");

Array.prototype.where = function(match) {
    var a = [];
    for (var i = 0; i &amp;lt; this.length; i++) {
        if (match(this[i])) {
            a[a.length] = this[i];
        }
    }
    return a;
}

if (Array.prototype.select != undefined)
    throw new Error("Duplicatte method definition on Array");

Array.prototype.select = function(selection) {
    var a = [];
    for (var i = 0; i &amp;lt; this.length; i++) {
        a[a.length] = selection(this[i]);
    }
    return a;
}

if (Array.prototype.contains != undefined)
    throw new Error("Duplicatte method definition on Array");

Array.prototype.contains = function(obj) {
    var len = this.length;
    for (var i = 0; i &amp;lt; len; i++) {
        if (this[i] === obj) { return true; }
    }
    return false;
};

&lt;/pre&gt;
&lt;p&gt;Not alot of code really.&lt;/p&gt;
&lt;p&gt;Nitpickers corner: LINQ-like implementations of Javascript already exists, but when it takes me a minute to implement I don&amp;#8217;t go about learning a new framework to get the job done :)&lt;/p&gt;</description><a10:updated>2010-02-12T09:10:00+01:00</a10:updated></item><item><guid isPermaLink="false">383916513</guid><link>http://bjarte.com/post/383916513</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Strongly typed Action Links, URLs and Redirect To Action in ASP.NET MVC 2 RC 2</title><description>&lt;p&gt;This one goes out to all you who are spending valuable time to figure out where the heck you can find these methods:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ActionLink and BuildUrlFromExpression you can find in the MVC Futures:&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;%@ Import Namespace="Microsoft.Web.Mvc"%&amp;gt;  
&amp;lt;% =Html.ActionLink&amp;lt;HomeController&amp;gt;(x =&amp;gt; x.Index(),"Go home") %&amp;gt; 
&amp;lt;% =Html.BuildUrlFromExpression&amp;lt;HomeController&amp;gt;(x=&amp;gt;x.Index())%&amp;gt; 
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Strongly typed RedirectToAction you can find in MvcContrib&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;using MvcContrib; 
return this.RedirectToAction(x=&amp;gt;x.Index());
&lt;/pre&gt;
&lt;p&gt;You can also read Phil Haacks uber lame exuse for not putting this inside MVC at the end of &lt;a href="http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx"&gt;this post&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2010-02-11T17:25:00+01:00</a10:updated></item><item><guid isPermaLink="false">370208632</guid><link>http://bjarte.com/post/370208632</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Apple and Usablility</title><description>&lt;p&gt;I am very impressed with the user interfaces Apple has on it&amp;#8217;s products like iPod and the iPhone. Apple really do set the standard. Apple does have some really crappy software as well. The one that constantly annoys me is iTunes. But that&amp;#8217;s not a problem Apple. I can forgive you for one mistake. However, what I got this morning when I tried to update my iTunes didn&amp;#8217;t please me at all. As we all know when we get an software update we just press next, next and then we&amp;#8217;re OK. Apple has realized this as well and is deliberately trying to push some software to you that you DO NOT WANT. This is not acceptable.&lt;/p&gt;
&lt;p&gt;The problem is easy to fix. They could just have left the check-boxes unchecked.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_kxb2721znG1qzl1ms.png"/&gt;&lt;/p&gt;
&lt;p&gt;Obviously I&amp;#8217;m not new to this behaviour. A lot of non-user friendly companies does exactly the same thing. But Apple? Come on. You are supposed to be the usability guys.&lt;/p&gt;
&lt;p&gt;The way to create great software is to think about the user experience from the users perspective. Nobody wants an extra browser or a mobile-something application installed when they are just updating their software.&lt;/p&gt;
&lt;p&gt;Hopefully you, my readers, don&amp;#8217;t do this kind of crap to your customers. Or do you&amp;#160;?&lt;/p&gt;
&lt;p&gt;Later.&lt;/p&gt;</description><a10:updated>2010-02-04T08:15:00+01:00</a10:updated></item><item><guid isPermaLink="false">366838415</guid><link>http://bjarte.com/post/366838415</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Code ownership and source control in action</title><description>&lt;p&gt;We (the team) just had a chat about some ideas we should follow when it comes to source control and code ownership. Here is a short summary.&lt;/p&gt;
&lt;h4&gt;Code ownership&lt;/h4&gt;
&lt;p&gt;&amp;#8221;Shared code ownership: &amp;#8221; To ensure that more than one person is familiar with a certain part of the code base we have shared code ownership. This will make the team more flexible, and making change easier. It is always allowed to refactor code to make it better. It is actually required to prevent  the code base from deteriorating over time.  That said, there might be people who knows more about the code base than you do. Also, somebody else might be working with the code right now. &amp;#8221;Consult before making radical change.&amp;#8221; Communication is always important.&lt;/p&gt;
&lt;h4&gt;Check in&lt;/h4&gt;
&lt;p&gt;&amp;#8221;Check in early, check in often: &amp;#8221; The &lt;i&gt;code &lt;/i&gt;is what is in source control, not what is on your computer. By keeping the code in isolation on your computer you are setting yourself (and the team) up for big trouble. By updating(first) and checking in (second) often, you prevent merging and communication problems.   Partition your current work into sub problems, and check in when each feature is created or updated. Work on one problem at a time.  If you find yourself working on 10 features, where each one is impossible to check in, you are doing it wrong. It&amp;#8217;s a code management anti-pattern.  The philosophy behind this is simple. Problems are easier to fix right after they occur. In a day, or a week, solving the problem becomes exponentially harder. Considering this philosophy, keeping the code on your machine to avoid problems MAKES NO SENSE&amp;#160;!&lt;/p&gt;
&lt;p&gt;&amp;#8221;If the code isn&amp;#8217;t checked into source control, it doesn&amp;#8217;t exist&amp;#8221;&lt;/p&gt;
&lt;h4&gt;Write tests&lt;/h4&gt;
&lt;p&gt;Write tests for the expected behaviour and your usage of the code. This will ensure that new features and refactoring is compatible with existing usage.&lt;/p&gt;
&lt;h4&gt;Standard&lt;/h4&gt;
&lt;p&gt;&amp;#8220;Standard&amp;#8221; is what we do right now (or should do). The standard can be changed as we find better ways to solve our problems. However, we should all follow the current standard.&lt;/p&gt;</description><a10:updated>2010-02-02T13:09:00+01:00</a10:updated></item><item><guid isPermaLink="false">342715696</guid><link>http://bjarte.com/post/342715696</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Feedback is king</title><description>&lt;p&gt;&lt;i&gt;&lt;img class="articleImage" src="http://bjarte.com/uploads/tumblr_kwi0byIriu1qzl1ms.jpg"/&gt;The other day when I was up in the mountains in my cabin, I suddenly started thinking about development processes and rapid feedback loops.  I sat down to write about it, and here is the result:&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;&lt;br/&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;There is a saying “culture eats strategy for breakfast”.  It’s true. I have seen it in action.&lt;/p&gt;
&lt;p&gt;Introducing a new process often requires changing the culture in the company. This is hard or impossible. Radical change creates too much friction. Working with the existing process and modifying it slowly is the most feasible route.  Identify your goals and see how you can slowly modify your existing process to achieve the goals.&lt;/p&gt;
&lt;p&gt;Let assume that building software faster and with better quality is a good idea in your context. It usually is.  Let’s say this is our goal, assuming that it in the end will lead to more profitability.&lt;/p&gt;
&lt;p&gt;I firmly believe that to create maintainable software there is one term that is more powerful than all others. That term is rapid feedback loops (RFL). Rapid feedback loops is the common denominator of all agile processes. The only process I know of where RFL is not a central concept, is the waterfall model.  It is not the details of the agile processes that make them succeed. It is the fact that they all embrace rapid feedback.&lt;/p&gt;
&lt;p&gt;Test driven development tells us every minute if our code works. Continuous integration tells if our code is working in the bigger picture. Integration tests checks whether we are fulfilling the product requirements. Periodical demonstrations and conversations with our customers tell us if we are building the right product. It’s all about getting feedback. If you are writing bad code, or creating the wrong features, feedback nudges you back on the right track. Design reviews can prevent architectural erosion. You need feedback as soon as possible so that you don’t waste time working on the wrong thing. Working on the wrong thing is expensive.&lt;/p&gt;
&lt;p&gt;Feedback is a good thing if the feedback you are getting is correct. If it’s not you have a problem. We can usually trust well written unit tests. Integration tests are harder, because they are only correct if they are actually testing a feature we need in the end product.  We need to constantly check with our customer that we are on the right track. The customer might be wrong, so we re-check on a continuous basis.&lt;/p&gt;
&lt;p&gt;If you want to improve your current process you should start looking at your feedback loops. Slowly introduce feedback on all levels. You don’t need to pick Scrum, XP, RUP, Lean, Kanban, Crystal Clear or ScrumBut. However, you should know roughly what they are about. This way you can pick from a toolbox of practices and make them fit into your existing culture.&lt;br/&gt;&lt;br/&gt; I don’t believe in picking an out of the box process if it will crash with your current company culture. However I really do believe in feedback loops and you should introduce them slowly into your current process. There is obliviously more to creating a smooth software machine, but feedback is a key concept.&lt;/p&gt;
&lt;p&gt;Peace.&lt;/p&gt;</description><a10:updated>2010-01-19T15:32:00+01:00</a10:updated></item><item><guid isPermaLink="false">332145494</guid><link>http://bjarte.com/post/332145494</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Software related podcasts</title><description>&lt;p&gt;Here is my ITunes export of podcasts I listen to. Most are software or &amp;#8220;software business&amp;#8221; related. I hope it&amp;#8217;s helpful. Have I missed some crucial ones&amp;#160;? Tell me on &lt;a href="http://twitter.com/bjartn"&gt;twitter&lt;/a&gt; or in the comments :)&lt;/p&gt;
&lt;p&gt;BTW, I just removed the StackOverflow podcast from the list. It was taking &amp;#8220;brain dead&amp;#8221; to another level :)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET Rocks!&lt;/li&gt;
&lt;li&gt;Agile Toolkit Podcast&lt;/li&gt;
&lt;li&gt;Elegant Code&amp;#160;» CodeCast&lt;/li&gt;
&lt;li&gt;Entrepreneurial Thought Leaders&lt;/li&gt;
&lt;li&gt;Hanselminutes&lt;/li&gt;
&lt;li&gt;Herding Code&lt;/li&gt;
&lt;li&gt;IEEE Software’s &amp;#8220;On Architecture&amp;#8221; with Grady Booch&lt;/li&gt;
&lt;li&gt;IEEE Talks Software Process&lt;/li&gt;
&lt;li&gt;Lean Agile Straight Talk podcast&lt;/li&gt;
&lt;li&gt;Mixergy - Online Business Tips from Successful Entrepreneurs&amp;#160;» Interview&lt;/li&gt;
&lt;li&gt;Pluralcast&lt;/li&gt;
&lt;li&gt;Polymorphic Podcast&lt;/li&gt;
&lt;li&gt;Software Engineering Radio - the podcast for professional software developers&lt;/li&gt;
&lt;li&gt;TEDTalks (audio)&lt;/li&gt;
&lt;li&gt;The Startup Success Podcast&lt;/li&gt;
&lt;li&gt;This Week In Google&lt;/li&gt;
&lt;li&gt;This Week in Startups - Audio Only&lt;/li&gt;
&lt;li&gt;this WEEK in TECH - MP3 Edition&lt;/li&gt;
&lt;li&gt;Venture Voice&lt;/li&gt;
&lt;/ul&gt;</description><a10:updated>2010-01-13T10:46:00+01:00</a10:updated></item><item><guid isPermaLink="false">328334991</guid><link>http://bjarte.com/post/328334991</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Crush it !</title><description>&lt;p&gt;I just finished the book &lt;i&gt;&lt;a href="http://crushitbook.com/"&gt;Crush It!&lt;/a&gt;&lt;/i&gt; by Gary Vaynerchuck. It&amp;#8217;s about how you can make a living using social media and doing what you love to do. In the book he summarizes my own philosphy in a couple sentences&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Love your family&lt;/li&gt;
&lt;li&gt;Live your passion&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Can&amp;#8217;t argue with that&amp;#8230;&lt;/p&gt;
&lt;p&gt;I give it a 4 out of 6. If I had finished it a year ago I might have given it a 5 or 6. It all depends on what kind of &lt;a href="http://www.sethgodin.com/purple/"&gt;books&lt;/a&gt;, blogs and &lt;a href="http://thisweekinstartups.com/"&gt;shows&lt;/a&gt; you have devoured before you read it. To me it wasn&amp;#8217;t a lot of mind blowing stuff in there. Still, it&amp;#8217;s worth reading due to the passion Gary brings to the subject. Get the audio book, and you will see what I mean :)&lt;/p&gt;</description><a10:updated>2010-01-11T08:03:00+01:00</a10:updated></item><item><guid isPermaLink="false">326660733</guid><link>http://bjarte.com/post/326660733</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Freaky coincidence</title><description>&lt;p&gt;Just sat down to draw some vectorized mountaintops in Illustrator to practice my design skills. I turned on Spotify and the first song started. It was Jeremy by Pearl Jam. It starts&lt;/p&gt;
&lt;p&gt;&amp;#8220;At home drawing pictures of mountaintops&amp;#8230;&amp;#8221;&lt;/p&gt;
&lt;p&gt;Freaky :p&lt;/p&gt;</description><a10:updated>2010-01-10T10:36:39+01:00</a10:updated></item><item><guid isPermaLink="false">323325696</guid><link>http://bjarte.com/post/323325696</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>An abstraction on top of NHibernate</title><description>&lt;p&gt;Prepare for a random thought &amp;gt; 140 chars:&lt;/p&gt;
&lt;p&gt;I just read Ayendes &lt;a href="http://ayende.com/Blog/archive/2010/01/08/responding-to-effectus-commentary.aspx"&gt;post&lt;/a&gt; where he debates why we should not put an abstraction on top of NHibernate.&lt;/p&gt;
&lt;p&gt;The reason to do such a thing would be to avoid coupling your code to the persistence layer. This in itself is not a bad idea until you take a deeper look at what is required to make a useful abstraction.&lt;/p&gt;
&lt;p&gt;A simple persistence interface on top of NHibernate would make it easy to change the persistence layer but&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What happens when you need other features from NHibernate. Will you add it to the abstraction layer&amp;#160;? Not a very solid abstraction really.&lt;/li&gt;
&lt;li&gt;NHibernate is already an abstraction on top a relational database. Do you want to add another one&amp;#160;?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The term &amp;#8220;Leaky abstraction&amp;#8221; comes to mind.&lt;/p&gt;</description><a10:updated>2010-01-08T14:36:04+01:00</a10:updated></item><item><guid isPermaLink="false">304293156</guid><link>http://bjarte.com/post/304293156</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Taking your game to the next level</title><description>&lt;p&gt;Experience is the best way to learn, especially if you fail. However, you should not be reinventing the wheel and making mistakes people have made before you.  Use the knowledge on the web for what it is worth, and stand on the shoulders of giants as you take the next step to become a better developer.&lt;/p&gt;
&lt;p&gt;I have been learning new things about the business of software, project management and software architecture.  I have read a lot of books, listened to hours and hours of pod casts, watched screen casts and been to conferences. Finding the best content among all available sources is hard. In this post I will share some highlights hoping that I can help you in your search for the best content.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The business of software&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="right" src="http://bjarte.com/uploads/tumblr_kvd1h1RbOQ1qzl1ms.png" class="person"/&gt;I was listening to the &lt;a href="http://blog.stackoverflow.com/category/podcasts/"&gt;StackOverflow podcast&lt;/a&gt; when they were interviewing &lt;a href="http://twitter.com/jason"&gt;Jason Calacanis&lt;/a&gt;. I had never heard about this guy but he was apparently an internet celebrity and serial entrepreneur in the web space. He had just started a show “&lt;a href="http://thisweekinstartups.com/"&gt;This week in startups&lt;/a&gt;” and I checked it out.&lt;/p&gt;
&lt;p&gt;In the show he is interviewing guests on how you start up and run a successful internet business. He has a very interesting personality which makes this show a must watch. I am listening to many shows, like “&lt;a href="http://twit.tv/"&gt;This week in tech&lt;/a&gt;”, “&lt;a href="http://twit.tv/"&gt;This week in Google&lt;/a&gt;”, “&lt;a href="http://herdingcode.com/"&gt;Herding Code&lt;/a&gt;”, “&lt;a href="http://elegantcode.com/elegantcode-cast/"&gt;Elegant code cast&lt;/a&gt;”, “&lt;a href="http://www.se-radio.net/"&gt;Software engineering radio&lt;/a&gt;”, “&lt;a href="http://www.hanselminutes.com/"&gt;HanselMinutes&lt;/a&gt;”, “&lt;a href="http://blog.stackoverflow.com/category/podcasts/"&gt;StackOverflow&lt;/a&gt;” and many others, but this show is always the highlight of the week.&lt;/p&gt;
&lt;p&gt;After I started watching this program I am really getting a taste for the business side of things. Turns out it is as complicated and fun as creating software.  You need to be passionate, hard working and even a little bit smart to be a good entrepreneur.&lt;/p&gt;
&lt;p&gt;&lt;img align="right" src="http://bjarte.com/uploads/tumblr_kvd1i47ijR1qzl1ms.jpg" class="person"/&gt;Lately I have &lt;a href="http://www.goodreads.com/review/list/2952492"&gt;been reading&lt;/a&gt; all sorts of books on the subject. One of the most intriguing books I have read lately is “&lt;a href="http://www.sethgodin.com/purple/"&gt;The purple cow&lt;/a&gt;” by Seth Godin. He talks about how you need to create remarkable products that people want to talk about. The traditional model of marketing is not working anymore because people is getting overloaded with information and It’s hard or even impossible to make your product stand out. Read the book or get it at &lt;a href="http://audible.com"&gt;audible.com&lt;/a&gt;.  It is worth it. Audible, by the way, is great.&lt;/p&gt;
&lt;p&gt;Right now I am reading a book called “&lt;a href="http://www.amazon.co.uk/Predictably-Irrational-Hidden-Forces-Decisions/dp/0007256531/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1261821731&amp;amp;sr=8-1"&gt;Predictably irrational&lt;/a&gt;”. People act very irrationally when it comes to money. The funny thing about it is that you can actually predict their irrational behavior.  In this book the author gives a unique insight to the human psyche. It’s fun to read. I recommend this one as well.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Software design and architecture&lt;/b&gt;&lt;br/&gt;Software design and architecture has been one of my interests for a long time and this year is no different. The Norwegian Developer Conference was packed with &lt;a href="http://arkiv.ndc2009.no/en/index.aspx?cat=1070"&gt;great speakers&lt;/a&gt; presenting on parallel tracks. Despite having a choice between great speakers I always found myself listening to &lt;a href="http://www.udidahan.com/"&gt;Udi Dahans&lt;/a&gt; presentations. Udi talks about SOA not only from a technical perspective but in the intersection between business and software. He has a great way of keeping things simple but not simplistic.&lt;/p&gt;
&lt;p&gt;&lt;img align="right" src="http://bjarte.com/uploads/tumblr_kvd1ikf08G1qzl1ms.jpg" class="person"/&gt;I have been following &lt;a href="http://codebetter.com/blogs/gregyoung/"&gt;Greg Youngs blog on Code Better&lt;/a&gt; for quite some while, and was thrilled when I got the opportunity to attend his class on the &lt;a href="http://bjarte.com/post/205812576/great-ddd-course-with-greg-young"&gt;CQRS architecture&lt;/a&gt; in Bergen.  The CQRS architecture works great together with domain driven design to create and manage complex domain models. It’s worth reading up on.&lt;/p&gt;
&lt;p&gt;The best software design book I have read this year is “&lt;a href="http://www.amazon.co.uk/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1261821790&amp;amp;sr=1-1"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;”.  The material is presented in a clear and concise manner and the book is a great read. No wonder it has cult status in the developer community.&lt;/p&gt;
&lt;p&gt;Another great book is the free book “&lt;a href="https://gettingreal.37signals.com/"&gt;Getting real&lt;/a&gt;” by 37 Signals. It talks about every aspect of developing web software. The big takeaway from reading this one is “Keep it simple”. It’s separated into several small essays. Reading an essay takes 5 minutes and every one contains gems of knowledge.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;The process of developing software&lt;/b&gt;&lt;br/&gt;Thru my work I have seen many interesting takes on how you should develop software, some good, some bad.  There is no “one true way” of developing software. I believe that your choice of process greatly depends on the culture in your company and the physical location of the people involved. Distributed teams have many limitations and should be avoided if possible.&lt;/p&gt;
&lt;p&gt;Agile and Lean software development is interesting. I have been reading the Poppendieck books on Lean and some of the more business oriented books of Womack and Jones. However the highlight of the year is “&lt;a href="http://www.amazon.co.uk/gp/product/0566086654/"&gt;The Goal&lt;/a&gt;”. It is written as a novella which makes the subject even more interesting.  This book introduces “&lt;a href="http://en.wikipedia.org/wiki/Theory_of_Constraints"&gt;the theory of constraints&lt;/a&gt;” which is a very interesting concept, and a “must know” for every developer (and business person).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Seeing the big picture&lt;/b&gt;&lt;br/&gt;Learning about business, process and software gives synergies. Each of the areas affects the others and you start seeing the bigger picture. This will make you a better developer, or as in my case a great one ;)&lt;/p&gt;</description><a10:updated>2009-12-28T12:24:00+01:00</a10:updated></item><item><guid isPermaLink="false">263339524</guid><link>http://bjarte.com/post/263339524</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>The roles of software development</title><description>&lt;p&gt;Building software requires people with a certain skill set. To build a successful product you need a person with a clear vision of where the product is going. This person is the most important member of the team. Without him (or her) you will not be successful. This person, the champion, can guide the development towards the goal. The champion knows what features to include and what features not to include in the product. His clear vision will stop feature creep and lengthy unproductive discussions. The champion listens to others but has the final word. Democracy is not the way to go if you want to build remarkable software.&lt;/p&gt;
&lt;p&gt;Developing a quality product is difficult, and a champion is only one piece of the puzzle. To build a great software product, you need great software. You won&amp;#8217;t fool anybody by putting lipstick on a pig.&lt;i&gt; This is a key aspect missed by a lot of companies. &lt;/i&gt;&lt;/p&gt;
&lt;p&gt;To build great  software you need a person who knows how to build software. It sounds obvious doesn&amp;#8217;t it&amp;#160;? This person, let&amp;#8217;s call him a developer lead, should be &lt;i&gt;responsible for the development team&lt;/i&gt;.  He is responsible for ensuring that sound software engineering practices are followed throughout the project and that the software quality is up to par. This is not a simple job.&lt;/p&gt;
&lt;p&gt;Ideally the champion and the developer lead is the same person. The reason is simple: Communication. Communicating the vision  is hard, and fewer people means simpler communication. If you want to develop software effectively you need to make trade-offs between the features you would like to have and the time it takes to implement them. Often you can make small adjustments to your requirements and gain a lot in terms of development time and better technical solutions. This translates to faster time to marked and eventually more revenue. Identifying these trade-offs are difficult, but if the champion knows the technical aspects of software development this problem disappears.&lt;/p&gt;
&lt;p&gt;Having one person doing the work of a champion and a developer lead can be a recipe for failure if this one person fails at any of the two roles. A common mistake is to put a domain expert to the task of leading the development team, and thinking that if you put enough developers on the team the software will build itself.&lt;/p&gt;
&lt;p&gt;I have seen many products become mediocre due to the lack of a champion or a dev. lead. The roles need not be explicit, but they need to be present in the team in some form.&lt;/p&gt;
&lt;p&gt;What kind of people do you think is required to develop remarkable software&amp;#160;?&lt;/p&gt;</description><a10:updated>2009-11-30T11:29:56+01:00</a10:updated></item><item><guid isPermaLink="false">249397744</guid><link>http://bjarte.com/post/249397744</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>HTML 5 looks nice</title><description>&lt;p&gt;I just had a look at HTML 5 the other day. The Chrome browser has support for a lot of the features and you can check them out &lt;a href="http://www.chromeexperiments.com/%20"&gt;here&lt;/a&gt; if you have &lt;a href="http://www.google.no/chrome"&gt;Chrome&lt;/a&gt; installed. To me it looks like Silverlight and Flash can get in trouble in the future. The first question that hit me was how long time it will take before the majority of the browsers support it. According to Microsoft it might take &lt;a href="http://www.infoworld.com/d/developer-world/html-5-could-it-kill-flash-and-silverlight-291"&gt;5-10 years&lt;/a&gt;, but I&amp;#8217;m not so sure about that considering the speed at which the web is developing.&lt;/p&gt;
&lt;p&gt;Check it out at &lt;a href="http://www.chromeexperiments.com/"&gt;&lt;a href="http://www.chromeexperiments.com/"&gt;http://www.chromeexperiments.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2009-11-19T08:10:00+01:00</a10:updated></item><item><guid isPermaLink="false">243468826</guid><link>http://bjarte.com/post/243468826</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>A simple exception handling strategy</title><description>&lt;p&gt;Time to scribble down some of the things I don&amp;#8217;t like seeing when reading C# code.&lt;/p&gt;
&lt;pre&gt;try {
    something();
}
catch(Exception e){
    //doNothing
}
&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;try {
    something();
}
catch(Exception e){
    logSomething();
    //do nothing
}
&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;try {
    something();
}
catch(Exception e){
    logSomething();
    return null;
}
&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;try {
    something();
}
catch(Exception e){
    //throw base Exception class
    throw new Exception("Something didn't happen");
}
&lt;/pre&gt;
&lt;p&gt;All of these are exception handling anti-patterns and the reason should be obvious. Still I see them all the time. I might even have written some code like this back in the days.&lt;/p&gt;
&lt;p&gt;One reason not to write software this way is that your system will have side effects that are impossible to spot. Also, I&amp;#8217;m guessing the users of the software won&amp;#8217;t like strange things happening in the UI.&lt;/p&gt;
&lt;p&gt;To avoid problems like this I&amp;#8217;m usually using a combination of custom exceptions and a back stop. When I see the possibility of an exception occuring in my code and it makes sense to create a more specific exception I do just that. Remember to keep the original exception as an inner exception of the new one. To prevent exceptions from bubbling onto the user interface I have a back stop where I catch all exceptions before they are exposed to the user. Since I am throwing custom exceptions in my code I can reason about the exceptions and give the user the proper feedback. Sometimes the exceptions require more attention than just giving feedback to the user. In these cases my exception might become an event that is picket up by the appropriate handler.&lt;/p&gt;
&lt;p&gt;I guess this is the common way to handle exceptions, but who knows. Do you have any other strategy&amp;#160;?&lt;/p&gt;</description><a10:updated>2009-11-14T09:45:17+01:00</a10:updated></item><item><guid isPermaLink="false">228763457</guid><link>http://bjarte.com/post/228763457</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Cucumber and the Gherkin language</title><description>&lt;p&gt;If you are able to read this entire post I will owe you a beer ;)&lt;br/&gt;&lt;br/&gt;The other day I was at a Norwegian .NET User Group (NNUG) meeting in Bergen. &lt;a href="http://twitter.com/aslak_hellesoy"&gt;Aslak Hellesøy&lt;/a&gt; was showing off his &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; tool. I will give a uber quick recap skipping a lot of detail and correct terminology.&lt;/p&gt;
&lt;p&gt;Cumcumber is a mature BDD testing framework written in Ruby. When using Cucumber you describe your features in English (or the language of your choice). Cucumber will parse the feature and generate test templates (a.k.a. step definitions) that the developer will be completing.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Feature&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;# language: en
Feature: Division
  In order to avoid silly mistakes
  Cashiers must be able to calculate a fraction
 
  Scenario: Regular numbers
    Given I have entered 3 into the calculator
    And I have entered 2 into the calculator
    When I press divide
    Then the result should be 1.5 on the screen

&lt;/pre&gt;
&lt;p&gt;The language used to describe a certain feature must follow a set of structural rules. The language is developed for Cucumber and is called &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber/gherkin"&gt;Gherkin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Step definitions&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Given a feature you would use Cucumber to generate a template for writing your tests, called step definitions.&lt;/p&gt;
&lt;pre&gt;Before do
  #todo
end
 
After do
end
 
Given /I have entered (\d+) into the calculator/ do |n|
  #todo
end
 
When /I press (\w+)/ do |op|
  #todo
end
 
Then /the result should be (.*) on the screen/ do |result|
  #todo
end

&lt;/pre&gt;
&lt;p&gt;This example is in Ruby but you can generate the steps definitions in other languages as well. Some languages seems to have good support, others not so much.&lt;/p&gt;
&lt;p&gt;When you have generated your step definitions and filled out the &lt;a href="http://github.com/aslakhellesoy/cucumber/blob/master/examples/i18n/en/features/step_definitons/calculator_steps.rb"&gt;missing code&lt;/a&gt; you can run the feature and see if your code is meeting the business specifications.&lt;/p&gt;
&lt;p&gt;Cucumber is pretty sweet and it&amp;#8217;s a shame it&amp;#8217;s not mature enough for usage with the .NET platform. Also there is to much friction installing it and getting it to run properly.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Digging deeper -Parsing&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not the kind of guy that needs to know every technology to feel complete. There are just way to much out there. When it comes to theory around software I don&amp;#8217;t like to be out in the dark. Things like patterns, architecture, processes and the business surrounding the software is very interesting to me.&lt;/p&gt;
&lt;p&gt;The question that caught my attention in the Cucumber presentation was&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;How do you take a feature and build test templates from it?&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One thing is for sure, you are not using &amp;#8220;find and replace&amp;#8221; :) I felt a gaping hole in my knowledge and needed to do some research. I was not interested in the technical aspects, but the theory behind it. I often like to start at the bottom and  work my way up. I knew I had to do some reading about parsing, but I did not quite know where to begin. After some googeling I found some nasty papers. I quickly realized I was missing the required background so I needed to find my old book from the university called &amp;#8220;&lt;a href="http://www.amazon.com/Introduction-Theory-Computation-Michael-Sipser/dp/053494728X"&gt;Introduction to the theory of computation&lt;/a&gt;&amp;#8221; by Michael Sipser. The book is theoretical but still not very hard to read for someone who has read similar books before. I am now about to give a summary in plain English  of my research, so that you don&amp;#8217;t have to read the book.&lt;/p&gt;
&lt;p&gt;Warning: I might be skipping some details and simplifying.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Languages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A language is basically a set of strings. A given string can be in the language or not. Looking back at Cucumber you can say that a feature (the string) is in the Gherkin language if it complies with the rules of the Gherkin language. But how do you describee these rules that decide if a given string is in the language or not? Also, if the feature is in the language, how do you break it down into it&amp;#8217;s components so that you can reason about the semantics,i.e the meaning, of the feature&amp;#160;?&lt;/p&gt;
&lt;p&gt;There are different ways to describe languages. Depending on your method of choice, you are able describe a language or not. Let me clarify.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Regular languages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A regular language is a language that can be described by using a regular expressions.&lt;/p&gt;
&lt;p&gt;If you want to describe the language consisting of all strings starting with &amp;#8220;a&amp;#8221;, then continuing with any number of &amp;#8220;b&amp;#8221;s and ending with an   &amp;#8220;a&amp;#8221;, i.e the set {aba, abba, abbba, ..}, you can describe this language with the regular expression &amp;#8220;ab+a&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Now you might think that you can describe any set of strings using regular expressions, but that is not the case. The language consisting of all string with  &amp;#8221;a&amp;#8221;s and continuing with the same number of &amp;#8220;b&amp;#8221;s cannot be described by a regular expression. (More formally you would describe this language as B={a&lt;sup&gt;n&lt;/sup&gt;b&lt;sup&gt;n&lt;/sup&gt; | n&amp;gt;=0})&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Context free languages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Context free languages are a superset of regular languages. Some of these languages cannot be described using regular expressions. You describe these languages using a set of rules (also known as productions). Let&amp;#8217;s look at the following rules.&lt;/p&gt;
&lt;blockquote&gt;A =&amp;gt; 0A1&lt;br/&gt;A =&amp;gt; B&lt;br/&gt;B =&amp;gt; #&lt;/blockquote&gt;
&lt;p&gt;For a given rule, the left side of the arrow contains a variable (upper case letter). The right side contains a string of variables and determinants. In this case the determinants are 0,1 and # and the variables are A and B.&lt;/p&gt;
&lt;p&gt;To build a string in the language using these rules follow the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write down the start variable. It is the variable on the left-hand side of the top rule unless specified otherwise.&lt;/li&gt;
&lt;li&gt;Find a variable that is written down and a rule that starts with that variable. Replace the written down variable with the right-hand side of that rule.&lt;/li&gt;
&lt;li&gt;Repeat step 2 until no variables remain.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Using the grammar above you can generate the string 000#111. The generation would go something like this, starting with the first rule.&lt;/p&gt;
&lt;p&gt;A =&amp;gt; 0A1 =&amp;gt; 00A11 =&amp;gt; 000A111 =&amp;gt; 000B111 =&amp;gt; 000#111&lt;/p&gt;
&lt;p&gt;Actually using these rules you could generate any string starting with any number of zeros, then a hash sign, and then ending with the same number of ones. This language cannot be described using a regular expression.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;A parse tree&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Building the string 000#111 above can be represented as a parse tree:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_ksdituxcJR1qzl1ms.png"/&gt;&lt;/p&gt;
&lt;p&gt;A parse tree is decomposing a string in the language into it&amp;#8217;s separate components. Now it starts getting interesting. If I somehow could create a parse tree from a feature in the Gherkin language I could do all kinds of sexy stuff with it. Cool!&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ambiguity&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The problem with context free languages is that you in some cases can have different parse-trees giving you the same string in the language. In other words applying the rules in a different order will give you the same string. If I am using the parse tree to reason about the meaning of the string, two different parse tree would give two different meanings to the same string. Not a good thing.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Parsing expression grammar&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;A grammar is another word for the rules describing the language. I.e a grammar is a set of rules. A  parsing expression grammar (&lt;a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar"&gt;PEG&lt;/a&gt;) is very similar to the context free grammars I described above. The big difference is that the languages described using a PEG are not ambiguous. For a given string in a language there is only one parse tree. Sweeeeeeeeeeet. Now we&amp;#8217;re talking :) (And no, I&amp;#8217;m not a nerd)&lt;/p&gt;
&lt;p&gt;It turns out that Gherkin is described using a PEG. Cool huh? In ruby there is a tool called &lt;a href="http://treetop.rubyforge.org/"&gt;TreeTop&lt;/a&gt; that takes the rules of the grammer as input. If you give it a string from the language, i.e a feature in this case, you will be able to generate a parse tree for this string.&lt;/p&gt;
&lt;p&gt;This is the point I am at in my research currently. I have also found a &lt;a href="http://www.codeproject.com/KB/recipes/grammar_support_1.aspx"&gt;.NET tool&lt;/a&gt; that is able to create a parse tree of a given string if you supply the rules to it. My next step is to steal the &lt;a href="http://github.com/aslakhellesoy/cucumber/blob/master/lib/cucumber/parser/feature.tt"&gt;rules of the Gherkin language&lt;/a&gt; and move them over to this tool, and see If I am able to build a parse tree for a Cucumber feature using this tool. That would be cool.&lt;/p&gt;
&lt;p&gt;Also I need to look at the theory of how you actually build a parse tree for a string. Not by starting  with the rules and building a string, but the other way around.&lt;/p&gt;
&lt;p&gt;Did this make sense&amp;#160;?  Am I on the right track&amp;#160;? Please tell :)&lt;/p&gt;
&lt;p&gt;Till next time.&lt;/p&gt;</description><a10:updated>2009-10-31T11:22:00+01:00</a10:updated></item><item><guid isPermaLink="false">224749430</guid><link>http://bjarte.com/post/224749430</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Set based validation in the CQRS Architecture</title><description>&lt;p&gt;Today we&amp;#8217;ll get our hands dirty.&lt;/p&gt;
&lt;p&gt;If you are following the CQRS design pattern you might run into trouble when it comes to set based validation. Consider the task of registering a new user. How would you in your domain figure out if that user name is unique? You can obviously not query your event store, because the event store is not built for that purpose.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Querying the reporting database&lt;/b&gt;&lt;br/&gt;The solution is actually querying the reporting database on the read side to figure out if the user name is unique. There is (in my opinion) a little problem with this approach. By querying this way you are making the read side responsible for knowing domain concerns. You are effectively making the read-side a part of the domains bounded context and adding more responsibilities to it. Before we introduced set based validation the separation was clean and nice. It is not that clean any more.&lt;/p&gt;
&lt;p&gt;You could keep the design clean by having a separate database with the only purpose of answering set based queries and keep this database within the bounded context of the domain. This would keep the design cleaner (perhaps), but it would not be a practical choice in most scenarios.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_ks4dn3oE0v1qzl1ms.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Another oops&lt;/b&gt;&lt;br/&gt;In a scalable architecture you are publishing events asynchronously. They are picked up by the read-side and applied to the reporting database thru the denormalizer. Consider the situation where the UserCreatedEvent(UserName=&amp;#8221;BjartN&amp;#8221;) is in the denormalizer queue, and the domain is instructed to add yet another user named &amp;#8220;BjartN&amp;#8221;. The reporting database knows northing of the first event resulting in the domain publishing the same event twice. When the second event hits the reporting database the entire thing blows up, because the user already exists. What to do next&amp;#160;? The event has already occurred (twice) and has been published to many other systems. Basically the events have occurred and you need to deal with it. The only way to fix it is to issue an compensating action. This could be issued by the denormalizer to the domain as a command.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Be consistent if you can&lt;/b&gt;&lt;br/&gt;Dealing with these kinds of concurrency issues is not something you want to do for fun. If you have the option to publish the event and save to the reporting database in a single transaction (e.g. synchronously) you should consider that.&lt;/p&gt;</description><a10:updated>2009-10-27T11:07:00+01:00</a10:updated></item><item><guid isPermaLink="false">220704030</guid><link>http://bjarte.com/post/220704030</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Why would you store the entire history of the domain ?</title><description>&lt;p&gt;I got this great question in one of my &lt;a href="http://bjarte.com/post/205812576/great-ddd-course-with-greg-young"&gt;comments&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Modeling the entire history of the domain seems to only be valuable if the domain requires it as part of your domain? I guess the biggest concern with a pattern like this would be how you would effectively deal with different versions of code that have existed at different points along the path. The report one would generate from 10 releases ago might not be the same if you are reapplying events as you go. This could certainly have business implications too, how do you suggest dealing with this?&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;If the the application of an event changes, do you simply create new events and never modify old ones?&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;I will try to answer some of it:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Storing the entire history&lt;/b&gt;&lt;br/&gt;It&amp;#8217;s not so much the domain that usually requires you to keep the entire history, but you keep it for auditing. If you only keep your current state in your database, how do you know that the data is correct&amp;#160;? Anything could have happened to keep it from being correct, like bugs and evil people :) With an add-only model you even have the possibility of writing the events to a write-once-storage. Now it is impossible to manipulate the data. If you write a bug that creates false events, you would later execute compensating actions to undo what you did. Remember that an event is something that  has happened (past tense) so it makes no sense to change it in any way.&lt;/p&gt;
&lt;p&gt;There is another good reason to keep the history as well. When saving events you are not saving data to your current data model, but you are actually storing all the user behaviour. If you only store the current state of the domain, the reporting you can do on this data is limited. The information stored in an add-only model is much richer. You can do reports on things you didn&amp;#8217;t event think of when you created the application.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Versioning&lt;br/&gt;&lt;/b&gt;If your events changes you would create a new version of that event, and  keep the old ones. To keep your domain code form being bloated with handling of all versions of  events you would basically introduce a component that converts your events from previous  to newer versions, and then apply them on the domain. Remember that events are things that actually happened in your domain so in most cases the information in deprecated events are valuable.&lt;/p&gt;
&lt;p&gt;That said, there are of course situations where you would choose different architectural patterns.&lt;/p&gt;</description><a10:updated>2009-10-23T08:13:00+02:00</a10:updated></item><item><guid isPermaLink="false">218824299</guid><link>http://bjarte.com/post/218824299</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Creating an event storage</title><description>&lt;p&gt;The event storage is basically where you persist all the events your domain is publishing. The only thing that makes it a little bit tricky to implement is the fact that you need to worry about concurrency. Concurrency is tricky, but not that tricky.&lt;/p&gt;  &lt;p&gt;Event storages can be created using various technologies.&amp;#160; According to &lt;a href="http://lh6.ggpht.com/_Q1mrguPcPO8/SthtjJERXuI/AAAAAAAAAHU/ewEWrhfgUSI/s1600-h/CabinTripwithTone0492.jpg"&gt;Greg &lt;/a&gt;the best way is to write the events onto the disc, circumventing the file system. Of course then you’ll need to write your own indexing as well. That’s just crazy stuff and I’m not digging into those APIs any time soon :p In this example I’ll be showing an event storage for a sql database. We need to be able to store our serialized events and keep track of what aggregate root published the event. Also we need to maintain the concurrency version of the aggregate root.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Database&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;First let’s look at the database schema&lt;/p&gt;  &lt;p&gt;EventProviders&lt;/p&gt;  &lt;blockquote&gt;EventProviderId (uniqueidentifier)   &lt;br /&gt;Type (nvarchar)    &lt;br /&gt;VersionNumber (int)&lt;/blockquote&gt;  &lt;p&gt;Events&lt;/p&gt;  &lt;blockquote&gt;FkEventProviderId (uniqueidentifier)   &lt;br /&gt;DateTime (datetime)    &lt;br /&gt;Data (varbinary)&lt;/blockquote&gt;  &lt;p&gt;The name “event provider” refers in this case to the aggregate root. Each event provider has an id, a type name and a version number. The version number is used to do optimistic locking, making sure we don’t update an aggregate root that has been changed in the meantime. The version number also serves another task; the version number is always equal to the number of events published by the aggregate root.&lt;/p&gt;  &lt;p&gt;Now let’s look at the events table. Each event has a reference to the event provider that published the event. We also store a serialized version of the event and the time it was persisted. Notice we have no “eventId”. We don’t need one.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Event storage&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;We will access the event storage using the IEventStorage interface.&lt;/p&gt;  &lt;pre&gt;public interface IEventStorage
{
    IEnumerable GetAllEventsForEventProvider(Guid id);
    void Save(IEventProvider provider);
}&lt;/pre&gt;

&lt;p&gt;To save an aggregate root we pass the a reference to the IEventProvider interface (implemented by the aggregate root) to the event storage.&lt;/p&gt;

&lt;pre&gt;public interface IEventProvider
  {
    IEnumerable GetChanges();
    void ClearChanges();
    Guid Id { get; set; }
    int Version { get; set; }
  }&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;The Save method&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;To save the IEventProvider (i.e. Aggregate Root) we need to do the following&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Start transaction 
    &lt;ul&gt;
      &lt;li&gt;Get the event provider from the database &lt;/li&gt;

      &lt;li&gt;If the event provider does not exist in the database, create it &lt;/li&gt;

      &lt;li&gt;If the event provider exists, check that the database version matches the current version of the aggregate root. If not throw a concurrency exception. &lt;/li&gt;

      &lt;li&gt;Save all events the event provider has published after previous version &lt;/li&gt;

      &lt;li&gt;Update the version number in the event provider. The version number is now the previous version number plus the number of events published since previous version. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;End transaction &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The implementation is pretty straight forward. As you see all the complexity in this operation comes from the fact that we need to check for concurrency violations.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Included project&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I am including a project with an &lt;a href="http://cqrs.codeplex.com/"&gt;implementation of the event&lt;/a&gt; store and some other things like the repository and the aggregate root base class. This was written quickly at the &lt;a href="http://bjarte.com/post/205812576/great-ddd-course-with-greg-young"&gt;DDD Course&lt;/a&gt; by me and some other peeps, and is far from production ready and it has no UI. However I think it’s better to post this (crappy) code than to post nothing at all. The idea is that you can have some code to look at. There are some integration tests you can run if you set up the database. If you want to use an implementation like this, you can get some speed optimizations by using stored procedures. It’s evil, but still.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Some things to keep in mind&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;I have not talked about implementing snapshots to improve performance but it is really not that hard. I would use the Memento Pattern and not store the actual aggregate root. From there on it is just plankekjøring ;) &lt;a href="http://blog.fohjin.com/"&gt;Mark Nijhof&lt;/a&gt; is publishing an extensive example at some point in the near or far future.&lt;/p&gt;</description><a10:updated>2009-10-21T07:45:52+02:00</a10:updated></item><item><guid isPermaLink="false">216453417</guid><link>http://bjarte.com/post/216453417</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Creating a Microsoft Surface application for Norwegian Television</title><description>&lt;p&gt;I had a great conversation with &lt;a href="http://en.wikipedia.org/wiki/Model-view-presenter"&gt;MVP&lt;/a&gt; &lt;a href="http://www.ingebrigtsen.info/"&gt;Einar Ingebrigtsen&lt;/a&gt;. He was the one who invited me to Wave, and I figured why not use Wave to do an interview on his latest project. He has been working on an application for a Norwegian television show called &amp;#8220;&lt;a href="http://www.nrk.no/programmer/sider/de_ukjente/"&gt;De Ukjente&lt;/a&gt;&amp;#8221;. It is an WPF application for Microsoft Surface. In this interview he talks about all the challenges he faced creating this application.&lt;/p&gt;
&lt;p&gt;It is apparent that Einar is a developer with a taste for developing quality software. It really shines thru in this interview.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;First a couple of &amp;#8220;teaser&amp;#8221; screenshots&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The first one is for the actual application, and the next ones are from the admin console&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/RrFMS98oHXxA-Wwlly0cTA?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_aNh1PT1cl-4/SttS9BzmImI/AAAAAAAAAI8/oNYRpdaZmw4/s144/Screen%20shot%202009-10-18%20at%207.22.24%20PM.png"/&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.com/lh/photo/aS9Ma850Sk-MQywRj_YbOA?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_aNh1PT1cl-4/SttS9Sb9SPI/AAAAAAAAAJA/cYNOTEYhlgU/s144/Screen%20shot%202009-10-18%20at%207.21.38%20PM.png"/&gt;&lt;/a&gt; &lt;a href="http://picasaweb.google.com/lh/photo/6JA8spFM4i0C42ul0IBCHw?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_aNh1PT1cl-4/SttS9gPzqaI/AAAAAAAAAJE/eLHy2wpAQP4/s144/Screen%20shot%202009-10-18%20at%207.20.06%20PM.png"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can even &lt;a href="http://www1.nrk.no/nett-tv/klipp/561576"&gt;watch the show here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;..and then the interview&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;1) What problem does your software solve&amp;#160;?&lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;The television program was a gameshow, and their alternative was to have physical items on a table for the interaction. The purpose of the gameshow is to match known professions with unknown persons in studio. The application was used to solve this interaction, and more. The administrator could send clues to the tables that was displayed per face when touched. In addition there was a monitor application that the gameshow host used to monitor the interaction.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;2) What  did you use to develop this software&amp;#160;? &lt;a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation"&gt;WPF&lt;/a&gt;? &lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;The project was originally not targetting surface, but Windows 7 multitouch and HP Touchsmart desktop machines, so we started out in WPF 4. But 2 weeks before we were supposed to be finnished, we got hold of 2 surface tables and decided to go for Surface. We then needed to rewrite the touch logic, which was fairly simple since I had pretty much abstracted that away. And we ended up doing a WPF 3.5 SP1 solution using the Surface SDK 1.0.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;3) How did you develop the user interface&amp;#160;? Is it all your work, or did you do it togheter with a designer&amp;#160;? &lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;The television channel provided the graphics elements in Adobe Illustrator format - they controlled the look. I did not do any graphics myself, but was in control of the layout of things and had some &amp;#8220;artistic freedom&amp;#8221;.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;4) Assuming you  used XAML. Did you write the raw XAML or did you use Blend&amp;#160;?&lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;Handwritten in Xaml for the most part - only did a couple of storyboards in Blend. I feel a lot more productive in Xaml. When I first started doing Xaml based development, I started in Blend, but after å while I ended up feeling a lot more productive hand-writing Xaml.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;5) Did you use any design patterns to shape the user interface. MVVM?&lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;The entire solution was built around MVVM and was 100% test driven all the way from the backend to the UI. All in all the solution consists of 7-10 views, all with different viewmodels, some user controls with their own viewmodels and data from a database with an abstraction layer built on top of DevExpress Persistent Objects. It uses commands for handling behavior. It was crucial to go with test driven and use well known patterns, as this was to be on television and we needed to have control of code quality right from the start.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;6) Did you have any challanges related to the fact that you developed for Microsoft Surface&amp;#160;?&lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;My main challenge was the lack of hands on with an actual surface during the main development. I was pretty much doing this blindfolded. Had a chance the last day of development to sit down with the actual surfacetables and tweak things. The simulator worked out pretty good for me though. The challenges in the project was more related to other technical difficulties, such as concurrency, realtime data transfers between all the clients and such.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;7 ) Did you have any bugs in production, that is in the TV show&amp;#160;?&lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;Bugs - what do you mean?   :)   Well, the first show we had a couple of issues. The entire solution was using UDP broadcasting to let all the clients communicate with each other, they shared this code. That all worked out great, only thing was I left some experimental code in the receiverthread that allocated 10MB of data everytime an UDP packet was received, needless to say - OutOfMemoryException occured a couple of times.   But thanks to the fact I did it all TDD, we got lucky and didn&amp;#8217;t have much bugs and the ones that occured was really easy to get fixed and tested. After the second show I never heard back from the TV channel, which is a good thing. Only thing I heard from them was that they wanted to do a nother program with surface in it, so look out on NRK2 at the end of October, there will be a program called Tekno with a WebBrowser created for Surface that can be rotated and scaled and moved around on the table. Also something I will be putting up a blogpost on how to do, btw.&lt;/blockquote&gt;
&lt;p&gt;&lt;i&gt;8) I have been wathcing a couple of episodes of the show, and it seems the participants are having some problems moving items on the screen. I&amp;#8217;m guessing this has nothing to do with you, and everything to do with the nature of MS Surface &lt;/i&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;Both yes and no. We had some issues with lighting in the studio. The technology behind surface uses cameras within the table that captures the interaction on the table, if one is not careful with the lighting it will think that shadows on the table are interaction. That being said, we had a bug we didn&amp;#8217;t have time to fix - the snap mechanism didn&amp;#8217;t take into consideration the scaling of the pictures being moved. So in some cases the faces did not snap. It is not that apparent on the show, since we prepped the contestants to be aware of this. But some times you can actually see this problem. You can also see they have some problems moving things at all, and this is because of lighting in the studio. &lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><a10:updated>2009-10-18T20:00:00+02:00</a10:updated></item><item><guid isPermaLink="false">214540942</guid><link>http://bjarte.com/post/214540942</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>People and software design</title><description>&lt;p&gt;I my last posts I have been talking about DDD and the CQRS Architecture. There are certainly situations where the CQRS Architecture would be a good solution form a theoretical point of view. I know from experience that rolling the best suitable architecture is not always the way to go.  We need to consider the people as well. It is really dependent on the culture in the company if a &amp;#8220;new&amp;#8221; architecture can be rolled out.&lt;/p&gt;
&lt;h4&gt;Company culture&lt;/h4&gt;
&lt;p&gt;In some companies being a craftsman is valued. You are working in an environment where creating unreadable code will get you in trouble and major design decisions are well thought thru.  There&amp;#8217;s process, there&amp;#8217;s design and there&amp;#8217;s coding. The goal is to create code that can be maintained over time and at the same time meeting the needs of the business.&lt;/p&gt;
&lt;p&gt;In other companies there is chaos. The recognition that software needs to be built with care does not exist. The goal is to create the next feature without any thought of the maintenance hell you will experience in the future. The developer who implements the next feature in the shortest amount of time is the one who gets rewarded. Spending time creating SOLID software with well proven development practices is not valued.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m painting a black and white picture here, and as we all know, the world is grey :) Now, let me continue my rant.&lt;/p&gt;
&lt;p&gt;Both these companies can grow and gain marked share. If you are in a marked where you have monopoly, or are one among a few you can keep delivering mediocre software and still be in business. If you are in the &amp;#8220;chaos company&amp;#8221; category you will start seeing problems when competitors starts entering your marked or when you just can&amp;#8217;t deliver more features in reasonable time. Suddenly you are dealing with crappy software, unmotivated developers and a bad business.  Not a good place to be if you are in the business of making software.&lt;/p&gt;
&lt;h4&gt;The best design decicions are not always the best design decisions.&lt;/h4&gt;
&lt;p&gt;Back to my original thought. Yes. I was planning to advice you not to apply the CQRS Architecture, or any architecture that requires a certain amount of thought in companies following the chaos model. You will probably cause more problems than you solve. You need to be able to control your environment to roll these kinds of solutions. Eric Evans talks about creating bubbles of quality software in your organization. These kinds of bubbles burst quickly if you are in the wrong company. In other companies a bubble is a viable solution.&lt;/p&gt;
&lt;p&gt;Introducing new ideas in a company must be done with care and the first thing you need to consider is the people and the culture, not the best design from a technical perspective.&lt;/p&gt;
&lt;p&gt;&amp;#8230;and that was todays rant.  Makes sense&amp;#160;?  Hit me with a comment :)&lt;/p&gt;</description><a10:updated>2009-10-16T10:26:00+02:00</a10:updated></item><item><guid isPermaLink="false">212693682</guid><link>http://bjarte.com/post/212693682</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Implementing an aggregate root</title><description>&lt;p&gt;This post is related to the following ones&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://bjarte.com/post/205812576/great-ddd-course-with-greg-young"&gt;Introduction to CQRS&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://bjarte.com/post/206582009/testing-the-domain"&gt;Testing the domain&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://bjarte.com/post/209983853/using-the-same-model-for-reporting-and-transactions"&gt;Modeling behavior&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Implementing an aggregate root &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In one of my previous post I explained the testing benefits of the CQS architecture.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I arrange my tests by replaying a set of events. &lt;/li&gt;    &lt;li&gt;I act by executing a set of commands. &lt;/li&gt;    &lt;li&gt;And I assert by comparing the events published by the aggregate root to the events I expected to be published. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I am doing Act-Arrange-Assert testing in the simplest most readable way and at the same time creating business value.    &lt;br /&gt;    &lt;br /&gt;In this post I will look at how I would implement my aggregate root to enable this kind of testing. What we need to look at is how the aggregate root implements the replaying of events. This is the key to loading the aggregate root into it’s current state.&lt;/p&gt;  &lt;h4&gt;The base class&lt;/h4&gt;  &lt;p&gt;In addition to managing it’s domain logic each aggregate root is responsible for&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keeping list of all the events that the aggregate root has published after it was loaded. &lt;/li&gt;    &lt;li&gt;Maintaining a mapping between events and the methods for applying the events to the aggregate root. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;When saving an aggregate root to the event store you would ask for the events that has been published since it was loaded. That is why we need to store this information. In a testing scenario it is also useful to be able to assert against the events published by the aggregate. For each event, the aggregate root has a method for applying that event. A dictionary of these event-method pairs is maintained by the aggregate root. These responsibilities are common for all aggregate roots, so we will put it in a base class. Before I elaborate on this base class (called &lt;i&gt;HandlesEvents&lt;/i&gt;) lets look at an example.&lt;/p&gt;  &lt;h4&gt;The aggregate root&lt;/h4&gt;  &lt;p&gt;The aggregate root has a behaviour (i.e. method) that corresponds to a command. Given a &lt;i&gt;ChangeDescriptionCommand &lt;/i&gt;coming from the UI you would typically have a &lt;i&gt;ChangeDescription &lt;/i&gt;method on the aggregate root. In the command handler you would map a command to a behaviour on the aggregate root.     &lt;br /&gt;    &lt;br /&gt;The implementation of a given behaviour is the key here. In a behaviour you would&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;validate the input, &lt;/li&gt;    &lt;li&gt;create an event &lt;/li&gt;    &lt;li&gt;and call a method that applies the event to the aggregate root. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The &lt;i&gt;ChangeDescription &lt;/i&gt;behaviour implementation would look something like this:&lt;/p&gt;  &lt;pre&gt;public class Foo:HandelsEvents {

  private string _description;
  
  public Foo(){
    RegisterHandler&amp;lt;ChangeDescriptionEvent&amp;gt;(applyChangeDescripionEvent);
  } 
      
  public void ChangeDescription(string description){
    if(description == null)
      throw new InvalidDescriptionException();

    ApplyEvent(new ChangeDescriptionEvent(description));
  }

  private applyChangeDescripionEvent(ChangeDescriptionEvent e) {
    _description = e.Description;
  }
}&lt;/pre&gt;

&lt;p&gt;When the &lt;i&gt;ChangeDecription &lt;/i&gt;behaviour is called, the input is validated, the event is created and applied to the aggregate root. Notice I’m am calling the &lt;i&gt;applyChangeDescriptionEvent &lt;/i&gt;method thru the base class in stead of calling it directly. This is to enable the base class to do some bookkeeping on what events are called and how they are applied to the aggregate root. Notice that we register the mapping between the event and the method in the constructor. This way the base class knows which method to call when applying the event, both when you are loading an aggregate root into it’s current state and when your applying the event thru a behaviour. 

  &lt;br /&gt;

  &lt;br /&gt;&lt;img src="http://bjarte.com/uploads/tumblr_krhqvtTV5k1qzl1ms.png" /&gt;&lt;/p&gt;

&lt;h4&gt;More on the base class&lt;/h4&gt;

&lt;p&gt;Now lets look at the base class HandlesEvents. The &lt;i&gt;HandlesEvents &lt;/i&gt;base class is here for convenience. If I want to replay a set for events I will only need to call the method &lt;i&gt;LoadFromHistory(IEnumerable&amp;lt;IEvent&amp;gt; history) &lt;/i&gt;on the &lt;i&gt;HandlesEvent &lt;/i&gt;class. The &lt;i&gt;HandlesEvent &lt;/i&gt;class will then get the aggregate root in the required state by applying the events to the appropriate methods.&lt;/p&gt;

&lt;pre&gt;public void LoadFromHistory(IEnumerable&amp;lt;IEvent&amp;gt; history)
{
  foreach(var e in history)
      ApplyEvent(e,false);
}&lt;/pre&gt;

&lt;p&gt;The &lt;i&gt;ApplyEvent &lt;/i&gt;method finds the given handler method for the event and call this method with the event as an parameter. The boolean parameter &lt;i&gt;false &lt;/i&gt;is an instruction to the &lt;i&gt;ApplyEvent &lt;/i&gt;method not to keep a record of this event. We are only interested in the events that happend after the aggregate root was put in its current state. The &lt;i&gt;ApplyEvent &lt;/i&gt;in the &lt;i&gt;HandlesEvent &lt;/i&gt;base class will look something like this.&lt;/p&gt;

&lt;pre&gt;protected void ApplyEvent(IEvent e, bool add)
{
  AppliesEvent handler;

  if(!_lookUp.TryGetValue(e.GetType(), out handler))
    throw new HandlerNotFoundException();
  
  handler(e);

  if(add) _events.Add(e);
}&lt;/pre&gt;

&lt;p&gt;The &lt;i&gt;HandelsEvents&lt;/i&gt; base class will also have a public method &lt;i&gt;GetChanges &lt;/i&gt;to expose all the events that where published after the aggregate root was loaded into it’s initial state. 

  &lt;br /&gt;

  &lt;br /&gt;So lets sum up what we’ve got here.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You can load a set of events into your aggregate root to get it to the required state &lt;/li&gt;

  &lt;li&gt;You can invoke a behaviour on the aggregate root &lt;/li&gt;

  &lt;li&gt;You can get a list of events that the aggregate root has published &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You are ready to start testing.&lt;/p&gt;

&lt;p&gt;Should I go deeper into this stuff ? Was this post just confusing ? Is this English ? Hit me with a comment :)&lt;/p&gt;

&lt;ol&gt;&lt;/ol&gt;</description><a10:updated>2009-10-14T09:52:00+02:00</a10:updated></item><item><guid isPermaLink="false">209983853</guid><link>http://bjarte.com/post/209983853</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Using the same model for reporting and transactions</title><description>&lt;p&gt;I got this question in my comments section. I’ll try to answer it the best I can, but I might be leaving out good arguments. Who knows..&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Why cannot a single model serve reporting, transactions and searching at the same time? I guess it has something to do with scalability and performance of the application to do. What I have read about CQS this far I have not seen any list of all the benefits of it and I have not yet found the real arguments that I can use to convince the other guys in the team.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;The main reason for applying the CQS architecture and DDD is to model complex behaviours in your organization. If your only goal is to put a set of forms on top of your relational database, this approach is not for you.&amp;#160; In that case you would go with Active Record or Row Data gateway, or smack a MS Access application on top of your database. Also if you wan’t to utilize the CQS Architecture it’s best done in green field projects.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Behaviours and data&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;In object-oriented programming behaviours are the things the objects can do. If I wan’t to create a scalable object model of my (complex) domain I am interested in exposing the behaviour of my objects and encapsulating the internal state of the object (the data). I aim to&amp;#160; keep my object seams as tight as possible. A seam in this context is the exposed interface of my object.&lt;/p&gt;  &lt;p&gt;I will now try to explain the difference between exposing data and exposing behaviour.&lt;/p&gt;  &lt;p&gt;Let consider the entity “Employee” in a Human Resources Management application. At some point you would like to increase the salary of the employee. In a typical system you would update the “Salary” property on the employee to reflect the changes. Obviously there was a reason for the employee to get his salary changed. Maybe he got promoted, maybe it was just the yearly correction, or maybe he finally completed his master thesis. Let assume the reason was that he finally completed his master thesis. In many companies (at least in Norway) the salary is partly based on education. To capture the new education you would update the “YearsOfEducation” property on the Employee as well. (Simplified, but still.)&lt;/p&gt;  &lt;p&gt;The person who is managing the employees need to update different properties in the HRM application to complete his task. Maybe he even has a written note of all the things he has to do in the system in order to update the education of the employee:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_krhrbfUcZR1qzl1ms.png" /&gt;&lt;/p&gt;  &lt;p&gt;In a behaviour centric system this behavior would have been captured by exposing an AddEducation(..) behaviour on the employee. This behaviour (i.e. method) would be responsible for handling all the things that happens when an Employee adds on his education, like getting his salary increased. It would even publish an event so that the salary application could pick up the changes in the employees status.&lt;/p&gt;  &lt;p&gt;We want to expose behaviours not data. As a consequence&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Setters (i.e public settable properties) are a domain anti-pattern&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;Since I am interested in modelling behaviours in my domain and keeping a maintainable object model I do not wan’t to expose the data the behaviours is operating upon. This would lead to hard times when I need to change the implementation of my behaviors. As a consequence&lt;/p&gt;  &lt;p&gt;&lt;i&gt;Getters are a domain anti-pattern.&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;To summarize: Do not expose data on your domain model&lt;/p&gt;  &lt;p&gt;…and that is the very short answer to why you would have one model for reporting and one for transactions on your domain.&lt;/p&gt;  &lt;p&gt;This is the best resource on the&amp;#160; web for really getting why you would model behaviour in your application (and yes, I have checked the entire internet): &lt;a href="http://herdingcode.com/?p=189"&gt;&lt;/a&gt;&lt;a href="http://herdingcode.com/?p=189"&gt;http://herdingcode.com/?p=189&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Performance:&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I am hoping to go deeper into consistency, partitioning and availability in an upcoming post. Still, what is interesting about the CQS Architecture is that in many cases you can fire off your commands on the domain asynchronously. Fire and forget. You don’t need to wait for the entire processing to have occurred before returning control to your user.&lt;/p&gt;  &lt;p&gt;I hope this answers at least some of your questions Anders.&lt;/p&gt;</description><a10:updated>2009-10-11T11:03:00+02:00</a10:updated></item><item><guid isPermaLink="false">206582009</guid><link>http://bjarte.com/post/206582009</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Testing the domain</title><description>&lt;p&gt;One of the most powerful features of the CQS Architecture is the ability to create highly expressive tests.&lt;/p&gt;  &lt;p&gt;When a set of commands are executed on an aggregate root the expected result is one or more events.    &lt;br /&gt;    &lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_aNh1PT1cl-4/SsxZKECnkGI/AAAAAAAAAHI/7f4FpFipC_U/s800/CQS%20testing2.png" width="311" height="324" /&gt;    &lt;br /&gt;    &lt;br /&gt;Before you execute your commands you must get your aggregate root in the required state, in other words you need to set up the context of the test. Loading an aggregate root into the required state is done by replaying a set of events.     &lt;br /&gt;    &lt;br /&gt;Do you see the power of this way of testing ? You can express your test only using events and commands ! Yes. It deserves an exclamation mark. A specification/test would look something like this:     &lt;br /&gt;&lt;i&gt;     &lt;br /&gt;Given&lt;/i&gt; &lt;i&gt;     &lt;br /&gt;UserCreatedEvent {Name=”Greggy”, Age=12, Address=”Bergen”}      &lt;br /&gt;&lt;/i&gt;&lt;i&gt;     &lt;br /&gt;When&lt;/i&gt; &lt;i&gt;     &lt;br /&gt;ChangeUserNameCommand{Name=”Greg”}      &lt;br /&gt;&lt;/i&gt;    &lt;br /&gt;&lt;i&gt;Then&lt;/i&gt; &lt;i&gt;     &lt;br /&gt;UserNameChangeEvent{Name=”Greg”}&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;OK, I’ll admit to the fact that this wasn’t a very good example :) Ignoring that, I’m hoping you see the power of writing tests this way. Look at how the language of the events in the past tense and the commands in the imperative form goes together with the “Given-When-Then” paradigm. It’s beautiful how things just fit together using BDD and DDD this way. Of course you would expect that from two so similar abbreviations. In case your were wondering, it was Greg who pointed this out :)     &lt;br /&gt;    &lt;br /&gt;Creating the specifications this way fits well in with DDD idea of the ubiquitous language. You are really getting closer to the BDD dream of having your business people writing your specifications. Sweet.&lt;/p&gt;  &lt;p&gt;Should I give some code examples perhaps?&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Edit:&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;In the post I omitted the fact that it’s the command handlers in front of the aggregate root that is actually getting the commands and mapping them to behaviors in the aggregate root. It won’t change the post that much, but it’s important information.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://bjarte.com/uploads/tumblr_kr5lwgLUeS1qzl1ms.png" /&gt;&lt;/p&gt;</description><a10:updated>2009-10-07T11:24:00+02:00</a10:updated></item><item><guid isPermaLink="false">205812576</guid><link>http://bjarte.com/post/205812576</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Great DDD course with Greg Young.</title><description>&lt;p&gt;I have been on a two day intensive DDD course with Greg Young. The course was great both from a social and educational perspective. To make sure I don’t forget all of what I’ve learned at the course I will try to write a couple of blog posts to remind myself, and perhaps give others some valuable information.   &lt;br /&gt;    &lt;br /&gt;The majority of the course revolved around the Command Query Separation (CQS) architecture promoted by Greg in various presentations.&lt;/p&gt;  &lt;p&gt;&amp;lt;EDIT&amp;gt;   &lt;br /&gt;We now call it&amp;#160; command and query responsibility segregation CQRS :)    &lt;br /&gt;&amp;lt;/EDIT&amp;gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a id="f-sa" title="http://www.infoq.com/presentations/greg-young-unshackle-qcon08" href="http://www.infoq.com/presentations/greg-young-unshackle-qcon08"&gt;&lt;/a&gt;&lt;a href="http://www.infoq.com/presentations/greg-young-unshackle-qcon08"&gt;http://www.infoq.com/presentations/greg-young-unshackle-qcon08&lt;/a&gt;&lt;/a&gt;    &lt;br /&gt;&lt;a id="ye7t" title="http://www.infoq.com/interviews/greg-young-ddd" href="http://www.infoq.com/interviews/greg-young-ddd"&gt;&lt;/a&gt;&lt;a href="http://www.infoq.com/interviews/greg-young-ddd"&gt;http://www.infoq.com/interviews/greg-young-ddd&lt;/a&gt;&lt;/a&gt;    &lt;br /&gt;&lt;a id="gixj" title="http://www.vimeo.com/3171910" href="http://www.vimeo.com/3171910"&gt;&lt;/a&gt;&lt;a href="http://www.vimeo.com/3171910"&gt;http://www.vimeo.com/3171910&lt;/a&gt;&lt;/a&gt;    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;The CQS architecture follows the same principle as Bertrand Meyer’s Query Command Separation principle ( &lt;a id="sdyw" title="http://en.wikipedia.org/wiki/Command-query_separation" href="http://en.wikipedia.org/wiki/Command-query_separation"&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Command-query_separation"&gt;http://en.wikipedia.org/wiki/Command-query_separation&lt;/a&gt;&lt;/a&gt; ), but they are not the same.    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;Overview of the CQS architecture &lt;/b&gt;    &lt;br /&gt;One of the main ideas of the CQS architecture is keeping a clear separation between changing the state of the domain and querying . The key is that:    &lt;br /&gt;    &lt;br /&gt;“A single model cannot be appropriate for reporting, searching and transactional data”    &lt;br /&gt;    &lt;br /&gt;In box style the architecture it will look something like this:    &lt;br /&gt;    &lt;br /&gt;&lt;img alt="Command Query Separation Architecture" src="http://lh6.ggpht.com/_aNh1PT1cl-4/SssrGFda0kI/AAAAAAAAAGQ/KhvVXlVLr0k/s800/CQS.png" /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;The write side &lt;/b&gt;    &lt;br /&gt;The UI will query the read model to get the DTOs it wishes to display. In the UI the user will build up commands and send them to the domain. The commands will be in the imperative form like “ChangeDescriptionCommand”. The domain will process the commands and events. The events will be in the past tense like “DescriptionChangedEvent”. The language is important. It does not need to be a one-to-one relationship between the commands and the events as in the example I just gave.    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;The read side &lt;/b&gt;    &lt;br /&gt;On the “read” side the denormalizer subscribes to the events from the domain, and changes the model according to the events published by the domain. The read model is usually optimized for querying, and is often kept in 1. normal form. Depending on your non-functional requirements, the read model can be fully consistent or eventually consistent with the domain.    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;Add only model &lt;/b&gt;    &lt;br /&gt;The domain events are stored in the event store. The events are serialized and stored in the order the are published. The event store is important. Notice we have a add-only model. As opposed to the common CRUD paradigm we are only adding information. We are not updating or deleting anything in the event store. That means that we don’t loose any information. Consider a shopping cart. A user adds an item to the shopping cart, and then he removes it again. In a common CRUD scenario we would insert the item and then delete it. When inspecting the data we would see an empty shopping cart. The fact that it was added and then removed is lost. In a add-only model we would still have this information. For “the business” these things can be very valuable.    &lt;br /&gt;    &lt;br /&gt;Of course in a CRUD model you could start recording this information and in a couple of months you could start giving “the business” reports about users adding and removing items. In an add-only model your could create a report of user behavior from the beginning of time. Do you see the difference ? Using an add only model you don’t loose information. You are capturing user behavior as opposed to just updating the data. It’s sweet.    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;Loading an aggregate root &lt;/b&gt;    &lt;br /&gt;Loading an aggregate root is a little bit different. Since you are not storing the current state of the domain, but the just the events that have happened you need to load up the aggregate root by supplying all the events that have occurred since the beginning of time and replaying these. This will obviously give an performance problem if you need to load 500 000 events to get your aggregate root to the current state. To solve this problem you can store a snapshot of the aggregate root at certain intervals. When loading the aggregate you load up the last snapshot of the aggregate and replay only the events that happened after the last snapshot.    &lt;br /&gt;    &lt;br /&gt;Implementing the event storage and the snapshots is straight forward, but as in all systems you need to handle concurrency issues which makes it a little bit tricky.    &lt;br /&gt;    &lt;br /&gt;&lt;b&gt;To be continued..&lt;/b&gt;     &lt;br /&gt;I’m planning to make a series of blog posts digging deeper into various topics and looking at how you would solve some of the obvious problems you will run into using this architecture. I am hoping to cover the following topics, but no promises :)&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Building up commands &lt;/li&gt;    &lt;li&gt;Handling commands &lt;/li&gt;    &lt;li&gt;Building up aggregate roots using the repository and event storage &lt;/li&gt;    &lt;li&gt;Creating the event storage &lt;/li&gt;    &lt;li&gt;Concurrency issues &lt;/li&gt;    &lt;li&gt;Set based validation &lt;/li&gt;    &lt;li&gt;Testing the domain in a BDD style &lt;/li&gt;    &lt;li&gt;Testing the denormalizer &lt;/li&gt;    &lt;li&gt;Disconnected clients &lt;/li&gt;    &lt;li&gt;Contract first development &lt;/li&gt;    &lt;li&gt;Enriching events and moving domain logic into independent components. &lt;/li&gt; &lt;/ul&gt;</description><a10:updated>2009-10-06T13:42:00+02:00</a10:updated></item><item><guid isPermaLink="false">192445191</guid><link>http://bjarte.com/post/192445191</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>The subtleties of leaky abstractions. </title><description>&lt;p&gt;I just read a great example of a leaky abstraction at &lt;a href="http://ayende.com/Blog/archive/2009/09/20/how-to-lead-a-convoy-to-safety.aspx"&gt;Ayendes blog&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;public interface IQueue
{
    void Enqueue(T o);
    T Dequeue();
    bool IsEmpty { get; }
}
&lt;/pre&gt;
&lt;p&gt;Ayende is using this abstraction to handle queuing. What if the queue gets so big it starts eating into your memory&amp;#160;? You would need to save the queue to the disk right&amp;#160;? Well, then suddenly T needs to serializable. But it does not end there. All objects that are referenced by T also need to be serializable. Suddenly you&amp;#8217;ve got a big problem on your hand due to a leaky abstraction.&lt;/p&gt;
&lt;p&gt;I love the subtleties of software design :)&lt;/p&gt;</description><a10:updated>2009-09-20T12:07:00+02:00</a10:updated></item><item><guid isPermaLink="false">190893138</guid><link>http://bjarte.com/post/190893138</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>What we've got where is a failure to communicate.</title><description>&lt;p&gt;Shu-Ha-Ri is a Japanese martial arts concept describing the three stages of learning. When you start doing martial arts you learn by repeating the same techniques over and over. You are at a Shu level of learning. Later you start using other techniques and putting them together. You are reflecting over your techniques and figuring out what works for you. You are now at a Ha level. At some point it all comes natural to you and you don&amp;#8217;t even think about what you are doing. It&amp;#8217;s all reflex. You are at a Ri level. &lt;br/&gt;&lt;br/&gt; The same concept can, with some imagination, be used in the software industry. Often I find myself in situations where I’m having problems explaining my points of view when it comes to technical decisions. This mostly occurs when I am talking to PMs (of course) and sometimes when I am talking to fellow developers. &lt;br/&gt;&lt;br/&gt; When talking to business minded PMs the answer is always to focus on the business aspect of the problem. This is a good way to think about software in general by the way. You are in a business, and even if you think unit testing is the most important thing in the world, it is not. Money is. Luckily making money and making quality software usually coincides. (But not always) &lt;br/&gt;&lt;br/&gt; Discussing technical practices together with my fellow developers is a whole other issue. Let me give you a contrived example: &lt;br/&gt;&lt;br/&gt; In most cases I advocate using some kind of presentation pattern when developing a user interface. To me the reasons are pretty obvious; separation of concerns, testability, maintainability and so on. Sometimes you will find complex logic stuffed inside the code behind file with no separation of anything (Yes I’m talking about you Mr. ASP.NET Web Forms). Data access, business logic and user interaction logic all stuffed into a big pile of mud.  This is where I step in and tell the developer that he should separate the code into several classes to keep the concerns separated and the code testable and maintainable. I continue my rant by explaining some of the intricacies of the different presentation patterns and how lovely test first development is. The developer will sit quietly and try to absorb all the information.  The next time I look at the code nothing has changed. I got what I deserved.  &lt;br/&gt;&lt;br/&gt; Why? &lt;br/&gt;&lt;br/&gt; I am talking to a Shu level developer as he was a Ha or Ri level developer. The attempt to communicate this way is futile. It is blatantly obvious that you need to communicate differently depending of the level the developer is at. Still I keep forgetting it. This post is to remind myself.&lt;/p&gt;
&lt;h4&gt;A little tip:&lt;/h4&gt;
&lt;p&gt;If you find yourself in an argument with a fellow developer and your crushing arguments seem to have no impact, consider that you might be on different levels.  You might even be the Shu level person in the discussion. Well. No. That doesn’t make sense ;)&lt;/p&gt;</description><a10:updated>2009-09-18T12:03:00+02:00</a10:updated></item><item><guid isPermaLink="false">181799269</guid><link>http://bjarte.com/post/181799269</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>Do I really need to make my own blogging software?</title><description>&lt;p&gt;Any developer will at some point get fed up with their blogging platform and start dreaming about writing their own. I got to this stage today when the tumblr text editor started crapping on my posts. It reformatted my nice html examples and started doing crazy shit. Also there is not a buildt in commenting feature in Tumblr which also causes some friction. The last thing that pissed me off is the fact that I cannot upload pictures.&lt;/p&gt;
&lt;p&gt;What I need from a blogging platform is not much:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RSS feeds&lt;/li&gt;
&lt;li&gt;Plain text editor. I know HTML and wan&amp;#8217;t to write my posts using it. And I don&amp;#8217;t want the editor to change my HTML.&lt;/li&gt;
&lt;li&gt;Comments.&lt;/li&gt;
&lt;li&gt;Uploading files.&lt;/li&gt;
&lt;li&gt;Changing the theme.&lt;/li&gt;
&lt;li&gt;Authentication for editors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;#8217;s very tempting to fire up Visual Studio and start making a sexy simple MVC blogging app for myself. But I just know It will consume way too much of my time. I&amp;#8217;m in deep pain. Please comfort me.&lt;/p&gt;</description><a10:updated>2009-09-07T09:19:00+02:00</a10:updated></item><item><guid isPermaLink="false">178736202</guid><link>http://bjarte.com/post/178736202</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>The ugly green form</title><description>&lt;p&gt;&lt;i&gt;(The indentation got crapped on by the editor. Will fix it soon.)&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;If you work with javascript (+jquery), html and css and always seem to make overly complex and unmaintainable code this little rant is for you :)&lt;/p&gt;
&lt;h4&gt;The task&lt;/h4&gt;
&lt;p&gt;Imagine yourself getting the task of creating the most ugly registration form in the world. Let&amp;#8217;s call it &amp;#8220;the ugly green form&amp;#8221;. I&amp;#8217;m guessing you would create something like this guy here:&lt;/p&gt;
&lt;p style="background-color:Lime"&gt;Name &lt;input id="name"&gt;&lt;br/&gt;Age &lt;input id="age"&gt;&lt;br/&gt;&lt;input type="button" value="Save details"&gt;&lt;/p&gt;
&lt;p&gt;Even if you are creating the ugliest form in the world, you would not implement it using the markup below. Why? Because you care about the separation of concerns and you care about the people maintaining the code in the future.&lt;/p&gt;
&lt;h4&gt;Don&amp;#8217;t do this&lt;/h4&gt;
&lt;div style="font-family: Lucida Console; font-size: 10pt; color: #bebec8; background: #141414;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;script type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;text/javascript&amp;#8221;&lt;/span&gt;&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;function save() {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;var name &lt;span style="color: #cda869;"&gt;=&lt;/span&gt; $(&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;#name&amp;#8221;&lt;/span&gt;)&lt;span style="color: #cda869;"&gt;.&lt;/span&gt;val();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;var age &lt;span style="color: #cda869;"&gt;=&lt;/span&gt; $(&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;#age&amp;#8221;&lt;/span&gt;)&lt;span style="color: #cda869;"&gt;.&lt;/span&gt;val();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #5f5a60;"&gt;//do something with the data&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;alert(name &lt;span style="color: #cda869;"&gt;+&lt;/span&gt; &lt;span style="color: #8f9d6a;"&gt;&amp;#8221; - &amp;#8220;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;+&lt;/span&gt; age);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;script&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;table style&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;background-color: Lime&amp;#8221;&lt;/span&gt;&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;tr&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;Name&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;text&amp;#8221;&lt;/span&gt; id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;name&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;tr&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;tr&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;Age&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;text&amp;#8221;&lt;/span&gt; id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;age&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;tr&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;tr colspan&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;2&amp;#8221;&lt;/span&gt;&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;button&amp;#8221;&lt;/span&gt; onclick&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;save();&amp;#8221;&lt;/span&gt; value&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;Save details&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;td&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;tr&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;table&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;We are not doing a good job of separating the concerns here. This page is doing too much. What&amp;#160;? Too much&amp;#160;? Oh yes! This piece of markup contains the structure, the styling and the behavior of the form. We need to split them up.&lt;/p&gt;
&lt;p&gt;Heeeeeeeeeeeeeelp meeeeeeee!&lt;/p&gt;
&lt;p&gt;The solution is simple. Put the css skinning in a css file. Put the javascript behavior in a javascript file. Put the html in html file. (Also fix up the HTML to use nice clean markup instead of overly verbose table markup.) You end up with something like this:&lt;/p&gt;
&lt;h4&gt;Html file&lt;/h4&gt;
&lt;div style="font-family: Lucida Console; font-size: 10pt; color: #bebec8; background: #141414;"&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;div id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;form&amp;#8221;&lt;/span&gt;&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;div&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;span&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;Name&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;span&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;text&amp;#8221;&lt;/span&gt; id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;name&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;div&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;div&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;span&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;Age&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;span&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;text&amp;#8221;&lt;/span&gt; id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;age&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;div&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;&lt;/span&gt;input type&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;button&amp;#8221;&lt;/span&gt; id&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;submit&amp;#8221;&lt;/span&gt; value&lt;span style="color: #cda869;"&gt;=&lt;/span&gt;&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;Save details&amp;#8221;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;&amp;lt;/&lt;/span&gt;div&lt;span style="color: #cda869;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h4&gt;Javascript file&lt;/h4&gt;
&lt;div style="font-family: Lucida Console; font-size: 10pt; color: #bebec8; background: #141414;"&gt;
&lt;p style="margin: 0px;"&gt;function init() {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;$(&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;#submit&amp;#8221;&lt;/span&gt;)&lt;span style="color: #cda869;"&gt;.&lt;/span&gt;click(save);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;function save() {&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;var name &lt;span style="color: #cda869;"&gt;=&lt;/span&gt; $(&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;#name&amp;#8221;&lt;/span&gt;)&lt;span style="color: #cda869;"&gt;.&lt;/span&gt;val();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;var age &lt;span style="color: #cda869;"&gt;=&lt;/span&gt; $(&lt;span style="color: #8f9d6a;"&gt;&amp;#8220;#age&amp;#8221;&lt;/span&gt;)&lt;span style="color: #cda869;"&gt;.&lt;/span&gt;val();&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #5f5a60;"&gt;//do something with the data&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;alert(name &lt;span style="color: #cda869;"&gt;+&lt;/span&gt; &lt;span style="color: #8f9d6a;"&gt;&amp;#8221; - &amp;#8220;&lt;/span&gt; &lt;span style="color: #cda869;"&gt;+&lt;/span&gt; age);&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;h4&gt;..and the CSS file&lt;/h4&gt;
&lt;div style="font-family: Lucida Console; font-size: 10pt; color: #bebec8; background: #141414;"&gt;
&lt;p style="margin: 0px;"&gt;#form&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;background&lt;span style="color: #cda869;"&gt;-&lt;/span&gt;color:Lime;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;width:&lt;span style="color: #9b7032;"&gt;200&lt;/span&gt;px;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;#form span&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;width:&lt;span style="color: #9b7032;"&gt;60&lt;/span&gt;px;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;&lt;span style="color: #cda869;"&gt;float&lt;/span&gt;:left;&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Are we done&amp;#160;? Nope. We&amp;#8217;re not. If we wan&amp;#8217;t to test the behavior of a form like this, it would be nice to be able to separate the view (html) from the javascript completely so that the javascript code could be tested in isolation. I will write another post about this in the near future.&lt;/p&gt;</description><a10:updated>2009-09-03T14:02:00+02:00</a10:updated></item><item><guid isPermaLink="false">177943871</guid><link>http://bjarte.com/post/177943871</link><a10:author><a10:name>Bjarte Djuvik Næss</a10:name></a10:author><title>The difference between supervising controller and passive view makes my head spin</title><description>&lt;p&gt;First let me supply some context by supplying you with the two reads leading to this rant:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.jeremydmiller.com/ppatterns/SupervisingController.ashx"&gt;Supervising controller&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jeremydmiller.com/ppatterns/PassiveView.ashx"&gt;Passive view&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now over to my rant:&lt;/p&gt;
&lt;p&gt;So say you are making a passive view with the task of registering a new user. The view might look like this:&lt;/p&gt;
&lt;pre&gt;    public interface IRegisterUserView {
	    string UserName{get;}
	    string Password{get;}
	    event Action OnSubmit;
    }
&lt;/pre&gt;
&lt;p&gt;Now the presenter would look something like&lt;/p&gt;
&lt;pre&gt;  
    public class RegisterUserPresenter
    {
        private readonly IRegisterUserView _view;
        private readonly IUserService _service;

        public RegisterUserPresenter(IRegisterUserView view,  IUserService service)
        {
            _view = view;
            _service = service;

            _view.OnSubmit += submit;
        }

        void submit()
        {
            _service.CreateUser(_view.UserName,_view.Password);
        }
    }
&lt;/pre&gt;
&lt;p&gt;This would be an implementation of the passive view. What if I now, instead of having a two properties UserName and Password in my view, created a whole new object and called it the &amp;#8220;Model&amp;#8221;&lt;/p&gt;
&lt;pre&gt;    public class Model
    {
        public string UserName { get; }
        public string Password { get; }
    }
&lt;/pre&gt;
&lt;p&gt;And then I create a new view that looks like this. To make it even more superviser-controllerish I could remove the event and replace it with a method &amp;#8220;Submit&amp;#8221;&lt;/p&gt;
&lt;pre&gt;    public interface IRegisterUserView2
    {
        Model Model { get; }
        void Submit();
    }
&lt;/pre&gt;
&lt;p&gt;Now the presenter would look something like this:&lt;/p&gt;
&lt;pre&gt;public class RegisterUserPresenter2
 {
        private readonly IRegisterUserView2 _view;
        private readonly IUserService _service;

        public RegisterUserPresenter2(IRegisterUserView2 view, IUserService service)
        {
            _view = view;
            _service = service;
        }

        public void Submit()
        {
            _service.CreateUser(_view.Model.UserName, _view.Model.Password);
        }
 }
&lt;/pre&gt;
&lt;p&gt;The first example is an implementation the &amp;#8220;passive view&amp;#8221; pattern, and the other is an implementation of the &amp;#8220;supervising controller&amp;#8221;. The thing separating the two is that in the last example the view works intimately with the model. In the &amp;#8220;passive view&amp;#8221; example the view knows nothing about the model (which in this example is the IUserService).&lt;/p&gt;
&lt;p&gt;But are we really talking about the same model here&amp;#160;? No. We are not. So my claim is that the difference between supervising controller and passive view is minimal. Maybe non existing.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m guessing the reason I am having trouble seeing the difference here is due to a lack of understanding of this pattern. I&amp;#8217;ll be back with a new post when I finally figure out why the above rant is wrong.&lt;/p&gt;</description><a10:updated>2009-09-02T15:40:00+02:00</a10:updated></item></channel></rss>