﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com/blog/</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2012 (c) 2013</copyright><ttl>60</ttl><item><title>Querying your way to madness: the Facebook timeline</title><description>&lt;p&gt;Facebook certainly changed the way we are doing things. Sometimes, that ain’t always for the best, as can be seen from the way too much time humanity as a whole spend watching cat videos. &lt;/p&gt; &lt;p&gt;One of the ways that Facebook impacted our professional lives is that a lot of people look at that as a blue print of how they want their application to be. I am not going to touch on whatever that is a good thing or not, suffice to say that this is a well known model that is very easy for a lot of users to grasp.&lt;/p&gt; &lt;p&gt;It is also a pretty hard model to actually design and build. I recently had a call from a friend who was tasked with building a Facebook like timeline. Like most such tasks, we have the notion of social network, with people following other people. I assume that this isn’t actually YASNP (yet another social network project), but I didn’t check too deeply.&lt;/p&gt; &lt;p&gt;The question was how to actually build the timeline. The first thing that most people would try is something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; var user = session.Load&amp;lt;User&amp;gt;(userId);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; var timelineItems = &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;    session.Query&amp;lt;Items&amp;gt;()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;       .Where(x=&amp;gt;x.Source.In(user.Following))&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;       .OrderByDescending(x=&amp;gt;x.PublishedAt)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;       .Take(30)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;       .ToList();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Now, this &lt;em&gt;looks&lt;/em&gt; good, and it would work, as long as you have small number of users and no one follows a lot of people. And as long as you don’t have&amp;nbsp; a lot of items. And as long as you don’t have to do any additional work.&amp;nbsp; When any of those assumption is broken… well, welcome to unpleasantville, population: you.&lt;/p&gt;
&lt;p&gt;It &lt;em&gt;can’t&lt;/em&gt; work. And I don’t care what technology you are using for storage. You can’t create a good solution using queries for something like the timeline.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nitpicker corner:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you have users that are following a LOT of people (and you will have those), you are likely to get into problems with the query.&lt;/li&gt;
&lt;li&gt;The more items you have, the slower this query becomes. Since you need to sort them all before you can return results. And you are likely to have a LOT of them.&lt;/li&gt;
&lt;li&gt;You can’t really shard this query nicely or easily.&lt;/li&gt;
&lt;li&gt;You can’t apply additional filtering in any meaningful way.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;
&lt;p&gt;Let us consider the following scenario. Let us assume that I care for this Rohit person. But I really &lt;em&gt;don’t&lt;/em&gt; care for Farmville. &lt;/p&gt;
&lt;p&gt;&lt;img title="farmville-ribbon" border="1" alt="hide farmville ribbon" src="http://www.quickonlinetips.com/archives/wp-content/uploads/farmville-ribbon.png"&gt;&lt;/p&gt;
&lt;p&gt;And then:&lt;/p&gt;
&lt;p&gt;&lt;img title="hide-farmville" alt="hide farmville " src="http://www.quickonlinetips.com/archives/wp-content/uploads/hide-farmville.png" width="500" height="62"&gt;&lt;/p&gt;
&lt;p&gt;Now, try to imagine doing this sort of thing in a query. For fun, assume that I &lt;em&gt;do&lt;/em&gt; care for Farmville updates from &lt;em&gt;some&lt;/em&gt; people, but not from all. That is what I mean when I said that you want to do meaningful filtering.&lt;/p&gt;
&lt;p&gt;You can’t do this using queries. Not in any real way.&lt;/p&gt;
&lt;p&gt;Instead, you have to turn it around. You would do something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; var user = session.Load&amp;lt;User&amp;gt;(userId);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; var timelineItmes = session.Query&amp;lt;TimeLineItems&amp;gt;() &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;       .Where(x=&amp;gt;x.ForUser == userId)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;       .OrderBy(x=&amp;gt;x.Date)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;       .ToList();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Note how we structure this. There is a set of TimeLineItems objects, which store a bit of information about a set of items. Usually we would have one per user per day. Something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;users/123/timeline/2013-03-12&lt;/li&gt;
&lt;li&gt;users/123/timeline/2013-03-13&lt;/li&gt;
&lt;li&gt;users/123/timeline/2013-03-14&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;That means that we get well scoped values, we only need to search on a single set of items (easily sharded, with a well known id, which means that we can also just load them by id, instead of querying for them).&lt;/p&gt;
&lt;p&gt;Of course, that means that you have to have something that &lt;em&gt;builds&lt;/em&gt; those timeline documents. That is usually an async process that run whenever you have a user that update something. It goes something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateFollowers(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; itemId)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     var item = session.Include&amp;lt;Item&amp;gt;(x=&amp;gt;x.UserId)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;         .Load(itemId);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;     var user = session.Load&amp;lt;User&amp;gt;(item.UserId);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// user.Followers list of documents with batches of followers&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// we assume that we might have a LOT, so we use this techinque&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// to avoid loading them all into memory at once&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// http://ayende.com/blog/96257/document-based-modeling-auctions-bids&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;(var followersDocId &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; user.Followers)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;         NotifyFollowers(followersDocId, item);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; NotifyFollowers(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; followersDocId, Item item)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;     var followers = session.Include&amp;lt;FollowersCollection&amp;gt;(x=&amp;gt;x.Followers)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;         .Load(followersDocId);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;(var follower &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; followers.Followers)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;         var user = session.Load&amp;lt;User&amp;gt;(follower);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(user.IsMatch(item) == &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;continue&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;         AddToTimeLine(follower, item);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;As you can see, we are batching the operation, loading the followers and batched on their settings, decide whatever to let that item to be added to their timeline or not.&lt;/p&gt;
&lt;p&gt;Note that this has a lot of implications. Different people will see this show up in their timeline in different times (but usually very close to one another). Your memory usage is kept low, because you are only processing some of it at any given point in time. For users with a LOT of followers, and there will be some like those, you might want to build special code paths, but this should be fine even at its current stage.&lt;/p&gt;
&lt;p&gt;What about post factum operations? Let us say that I want to start following a new user? This require special treatment, you would have to read the latest timeline items from the new user to follow and start merging that with the existing timeline. Likewise when you need to delete someone. Or adding a new filter. &lt;/p&gt;
&lt;p&gt;It is a lot more work than just changing the query, sure. But you can get things done this way. And you cannot get anywhere with the query only approach.&lt;/p&gt;</description><link>http://ayende.com/blog/161537/querying-your-way-to-madness-the-facebook-timeline?key=81c5d40b-5061-4bc2-a0db-9700fa041be9</link><guid>http://ayende.com/blog/161537/querying-your-way-to-madness-the-facebook-timeline?key=81c5d40b-5061-4bc2-a0db-9700fa041be9</guid><pubDate>Mon, 22 Apr 2013 10:00:00 GMT</pubDate></item><item><title>My Passover Project: Introducing Rattlesnake.CLR</title><description>&lt;p&gt;Okay, after spending quite a lot of time digging through the leveldb codebase, and with several years of working with RavenDB, I can say with confidence that the CLR make it extremely hard to build high performance server side systems using the CLR.&lt;/p&gt; &lt;p&gt;Mostly, the issues are related to GC and memory. In particular, not having any way to control memory allocation and/or the GC means that we can’t optimize those scenarios in any meaningful way. At the same time, I do &lt;em&gt;not&lt;/em&gt; want to go back to the unmanaged world. As mentioned ,I just came back from a very deep dive into a non trivial C++ codebase ,and while I consider that codebase a really good one, that ain’t to say it is a pleasure to always be thinking about all the stuff that the CLR just takes away.&lt;/p&gt; &lt;p&gt;Therefor, I decided that I’m going to be doing something about it. And Rattlesnake.CLR was born:&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Implementing-LevelDB-in-managed-code-and_9F16/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Implementing-LevelDB-in-managed-code-and_9F16/image_thumb.png" width="157" height="161"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The major features of the Rattlesnake.CLR include explicit memory management &lt;em&gt;when&lt;/em&gt; required. Let us say that we know that we are going to be needing some amount of memory for a while, and then all of that can be thrown away. This is extremely common in scenarios such as a web request, pretty much all the memory that you generate during the processing web request can be safely free immediately. In RavenDB’s case, the memory we consume during indexing can be free immediately when we stop indexing. Right now this is a painful process of making sure that we allocate within the same gen0 and hoping that it won’t be too expensive, or that we won’t get a complete halt of the entire server while it is releasing memory. It also make it &lt;em&gt;really&lt;/em&gt; hard to do things like limit the amount of memory your code uses.&lt;/p&gt; &lt;p&gt;Another requirement that I have is that Rattlesnake.CLR should be able to execute existing .NET assemblies without any additional steps. Since I don’t fancy doing ports of stuff that already exists.&lt;/p&gt; &lt;p&gt;In order to handle this scenario with the given constraints, we have:&lt;/p&gt; &lt;blockquote&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; var heap = Heap.Create(HeapOptions.None, &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;     1024 * 1024,&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     512 * 1024 * 1024);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(MemoryAllocations.AllocateFrom(heap))&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;    var sb = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(var i = 0; i &amp;lt; 100; i ++ )&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;          sb.AppendLine(i);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;    Console.WriteLine(sb.ToString());&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt; heap.Destroy(); &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;All the code within the using statement is allocated in our own heap. In line 13, we are destroying all of that memory in one fell swoop.&lt;/p&gt;
&lt;p&gt;There are a few notes about this that we probably should address:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By default, memory allocated by this form is not subject to any form of GC. The idea is that this whole heap is getting released immediately.&lt;/li&gt;
&lt;li&gt;Note that last two parameters for the Heap.Create. The first is the initial size of the heap, and the second is&amp;nbsp; the max size. We now have a real way to actually limit the amount of memory a piece of code will use. This is really important on server applications where avoiding paging is critical.&lt;/li&gt;
&lt;li&gt;For that matter, we can now figure out how much memory a particular piece of code uses, and allocate our resources accordingly.&lt;/li&gt;
&lt;li&gt;You can use multiple heaps at the same time, although only one can be installed as the default allocation at a given point in time.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;There is the explicit heap.GarbageCollect() method that will do GC only on that heap, and which you can schedule at your own convenience.&amp;nbsp; You can have two heaps, and allocate from one while you are GCing from the other. And yes ,that means that GCs using this methods will &lt;em&gt;not&lt;/em&gt; stop the process!&lt;/p&gt;
&lt;p&gt;Memory allocated on the heap is obviously only valid as long as the heap is valid. That means that once the heap is destroyed, you can’t access any of the objects that were created there. This has implications for things like cache. We provide MemoryAllocations.AllocateOnGlobalHeap&amp;lt;T&amp;gt;(args) method to force you to use the global heap, instead, if you want this memory to be always available and subject to GC.&lt;/p&gt;
&lt;p&gt;This is early days yet, but we already see some really interesting performance improvements!&lt;/p&gt;
&lt;p&gt;How does this work?&lt;/p&gt;
&lt;p&gt;While an early experiment with Rattlensake.CLR was based on the Mono runtime. I quickly decided that I wanted to keep using the MS CLR. Now, it order to handle this I had to do some unnatural things (to say the least), but I think that I even managed to make this a supported option. Essentially, we are using the CLR Hosting API for this. In particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ICLRGCManager&lt;/li&gt;
&lt;li&gt;IHostMalloc&lt;/li&gt;
&lt;li&gt;IHostMemoryManager &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;You can use Rattlesnake.CLR like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.\Rattlesnake.exe Raven.Server.exe&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Just for fun, we also allowed to place limits on the default heap, so you can be sure that you aren’t allocating too much there.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.\Rattlesnake.exe Raven.Server.exe --max-default-heap-size=256MB&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;We are still running some tests, but this is looking really good. &lt;/p&gt;</description><link>http://ayende.com/blog/161889/my-passover-project-introducing-rattlesnake-clr?key=d79d601a-c67a-4d80-a182-117b2e343aac</link><guid>http://ayende.com/blog/161889/my-passover-project-introducing-rattlesnake-clr?key=d79d601a-c67a-4d80-a182-117b2e343aac</guid><pubDate>Mon, 01 Apr 2013 10:00:00 GMT</pubDate></item><item><title>Hibernating Rhinos Practices: A Sample Project</title><description>&lt;p&gt;I have previously stated that one of the things that I am looking for in a candidate is the actual candidate code. Now, I won’t accept “this is a project that I did for a client / employee”, and while it is nice to be pointed at a URL from the last project the candidate took part of, it is not a really good way to evaluate someone’s abilities.&lt;/p&gt; &lt;p&gt;Ideally, I would like to have someone that has an OSS portfolio that we can look at, but that isn’t always relevant. Instead, I decided to sent potential candidates the following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Hi,&lt;/p&gt; &lt;p&gt;I would like to give you a small project, and see how you handle that.&lt;/p&gt; &lt;p&gt;The task at hand is to build a website for Webinars questions. We run bi-weekly webinars for our users, and we want to do the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Show the users a list of our webinars (The data is here: &lt;a title="http://www.youtube.com/user/hibernatingrhinos" href="http://www.youtube.com/user/hibernatingrhinos"&gt;http://www.youtube.com/user/hibernatingrhinos&lt;/a&gt;)  &lt;li&gt;Show a list of the next few scheduled webinar (in the user’s own time zone)  &lt;li&gt;Allow the users to submit questions, comment on questions and vote on questions for the next webinar.  &lt;li&gt;Allow the admin to mark specific questions as answered in a specific webinar (after it was uploaded to YouTube).  &lt;li&gt;Manage Spam for questions &amp;amp; comments.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The project should be written in C#, beyond that, feel free to use whatever technologies that you are most comfortable with.&lt;/p&gt; &lt;p&gt;Things that we will be looking at:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Code quality  &lt;li&gt;Architecture  &lt;li&gt;Ease of modification  &lt;li&gt;Efficiency of implementation  &lt;li&gt;Ease of setup &amp;amp; deployment&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Please send us the link to a Git repository containing the project, as well as any instructions that might be necessary.&lt;/p&gt; &lt;p&gt;Thanks in advance,&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Oren Eini&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;This post will go live about two weeks after I started sending this to candidates, so I am not sure yet what the response would be.&lt;/p&gt;</description><link>http://ayende.com/blog/161026/hibernating-rhinos-practices-a-sample-project?key=36b548de-576b-479b-9eeb-9547a76aa1a3</link><guid>http://ayende.com/blog/161026/hibernating-rhinos-practices-a-sample-project?key=36b548de-576b-479b-9eeb-9547a76aa1a3</guid><pubDate>Fri, 22 Feb 2013 10:00:00 GMT</pubDate></item><item><title>Bug hunting in a massively multi threaded environment</title><description>&lt;p&gt;&lt;img style="display: inline; float: right" align="right" src="http://studio3music.com/wp-content/uploads/2009/12/bug-hunting.jpg" width="88" height="112"&gt;&lt;/p&gt; &lt;p&gt;We got a really nasty bug report from a user. Sometimes, out of the blue, RavenDB would throw an error:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;System.InvalidOperationException: Collection was modified; enumeration operation may not execute.&lt;br&gt;   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()&lt;br&gt;   at Raven.Json.Linq.RavenJArray.WriteTo(JsonWriter writer, JsonConverter[] converters) &lt;span class="kwrd"&gt;in&lt;/span&gt; c:\Builds\RavenDB-Stable\Raven.Abstractions\Json\Linq\RavenJArray.cs:line 174&lt;br&gt;   at Raven.Json.Linq.RavenJObject.WriteTo(JsonWriter writer, JsonConverter[] converters) &lt;span class="kwrd"&gt;in&lt;/span&gt; c:\Builds\RavenDB-Stable\Raven.Abstractions\Json\Linq\RavenJObject.cs:line 275
   at Raven.Json.Linq.RavenJObject.WriteTo(JsonWriter writer, JsonConverter[] converters) &lt;span class="kwrd"&gt;in&lt;/span&gt; c:\Builds\RavenDB-Stable\Raven.Abstractions\Json\Linq\RavenJObject.cs:line 275&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unfortunately, this error only happened once in a while, usually when the system was under load. But they weren’t able to provide a repro for that.&lt;/p&gt;
&lt;p&gt;Luckily, they &lt;em&gt;were&lt;/em&gt; able to tell us that they suspected that this is related to the replication support. I quickly setup a database with replication and wrote the following code to try to reproduce this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt;(var store = &lt;span class="kwrd"&gt;new&lt;/span&gt; DocumentStore
{
    Url = &lt;span class="str"&gt;"http://localhost:8080"&lt;/span&gt;,
    DefaultDatabase = &lt;span class="str"&gt;"hello"&lt;/span&gt;
}.Initialize())
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(var session = store.OpenSession())
    {
        session.Store(&lt;span class="kwrd"&gt;new&lt;/span&gt; ReadingList
        {
            UserId = &lt;span class="str"&gt;"test/1"&lt;/span&gt;,
            Id = &lt;span class="str"&gt;"lists/1"&lt;/span&gt;,
            Books = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;ReadingList.ReadBook&amp;gt;()
        });
        session.SaveChanges();
    }
    Parallel.For(0, 100, i =&amp;gt;
    {
        &lt;span class="kwrd"&gt;while&lt;/span&gt; (&lt;span class="kwrd"&gt;true&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;try&lt;/span&gt;
            {
                &lt;span class="kwrd"&gt;using&lt;/span&gt; (var session = store.OpenSession())
                {
                    session.Advanced.UseOptimisticConcurrency = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
                    session.Load&amp;lt;ReadingList&amp;gt;(&lt;span class="str"&gt;"lists/1"&lt;/span&gt;)
                            .Books.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; ReadingList.ReadBook
                            {
                                ReadAt = DateTime.Now,
                                Title = &lt;span class="str"&gt;"test "&lt;/span&gt; + i
                            });
                    session.SaveChanges();
                }
                &lt;span class="kwrd"&gt;break&lt;/span&gt;;
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (ConcurrencyException)
            {
                
            }
        }
    });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that reproduced the bug! Hurrah! Done deal, we can move on, right?&lt;/p&gt;
&lt;p&gt;Except that the bug was only there when we have &lt;em&gt;massive&lt;/em&gt; amount of threads hitting the db at once, and trying to figure out what is actually going on there was next to impossible using standard debugging tools. Instead, I reached down to my tracing toolbelt and starting pulling stuff out. First, we identified that the problem occurred when iterating over RavenJArray, which is our own object, so we added the following:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;        ConcurrentQueue&amp;lt;StackTrace&amp;gt;  addStackTraces = &lt;span class="kwrd"&gt;new&lt;/span&gt; ConcurrentQueue&amp;lt;StackTrace&amp;gt;();

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Add(RavenJToken token)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (isSnapshot)
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="str"&gt;"Cannot modify a snapshot, this is probably a bug"&lt;/span&gt;);

            addStackTraces.Enqueue(&lt;span class="kwrd"&gt;new&lt;/span&gt; StackTrace(&lt;span class="kwrd"&gt;true&lt;/span&gt;));

            Items.Add(token);
        }
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;And this one (where the exception is raised):&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteTo(JsonWriter writer, &lt;span class="kwrd"&gt;params&lt;/span&gt; JsonConverter[] converters)
{
    writer.WriteStartArray();

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Items != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
    {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var token &lt;span class="kwrd"&gt;in&lt;/span&gt; Items)
            {
                token.WriteTo(writer, converters);
            }
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (InvalidOperationException e)
        {
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var stackTrace &lt;span class="kwrd"&gt;in&lt;/span&gt; addStackTraces)
            {
                Console.WriteLine(stackTrace);
            }
            &lt;span class="kwrd"&gt;throw&lt;/span&gt;;
        }
    }

    writer.WriteEndArray();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the idea that we would actually be able to &lt;em&gt;get&lt;/em&gt; what is going on there. By tracking down who added items to this particular instance, I hoped that I would be able to figure out why we have an instance that is shared among multiple threads.&lt;/p&gt;
&lt;p&gt;When I had &lt;em&gt;that&lt;/em&gt;, it was pretty easy to see that it was indeed the replication bundle that was causing the issue. The problem was that the replication bundle was modifying an inner array inside the document metadata. We protected the root properties of the metadata from concurrent modifications, and most of the time, it works just fine. But the problem was that now we had a bundle that was modifying a &lt;em&gt;nested&lt;/em&gt; array, which &lt;em&gt;wasn’t&lt;/em&gt; protected.&lt;/p&gt;
&lt;p&gt;This is one of those bugs that are really hard to catch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My understanding of the code said that this is not possible, since I believed that we protected the nested properties as well*.&lt;/li&gt;
&lt;li&gt;This bug will only surface if and only if:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;You have the replication bundle enabled.&lt;/li&gt;
&lt;li&gt;You have a great deal of concurrent modifications (with optimistic concurrency enabled) to the same document.&lt;/li&gt;
&lt;li&gt;You are unlucky.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;
&lt;p&gt;I was grateful that the user figured out the replication connection, because I already sat on that bug previously, and there was no way I could figure out what is going on unless I had the trace to point me to where the actual problem was.&lt;/p&gt;</description><link>http://ayende.com/blog/160903/bug-hunting-in-a-massively-multi-threaded-environment?key=64348966-76a9-4818-841c-c7fda20b5d1d</link><guid>http://ayende.com/blog/160903/bug-hunting-in-a-massively-multi-threaded-environment?key=64348966-76a9-4818-841c-c7fda20b5d1d</guid><pubDate>Mon, 18 Feb 2013 10:00:00 GMT</pubDate></item><item><title>Hibernating Rhinos Practices: Design</title><description>&lt;p&gt;One of the things that I routinely get asked is how we design things. And the answer is that we usually do not. Most things does &lt;em&gt;not&lt;/em&gt; require complex design. The requirements we set pretty much dictate how things are going to work. Sometimes, users make suggestions that turn into a light bulb moment, and things shift very rapidly.&lt;/p&gt; &lt;p&gt;But sometimes, usually with the big things, we actually do need to do some design upfront. This is usually true in complex / user facing part of our projects. The Map/Reduce system, for example, was mostly re-written&amp;nbsp; in RavenDB 2.0, and that only happened after multiple design sessions internally, a full stand alone spike implementation and a lot of coffee, curses and sweat.&lt;/p&gt; &lt;p&gt;In many cases, when we can, we will post a suggested design on the mailing list and ask for feedback. Here is an example of such a scenario:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://groups.google.com/group/ravendb/browse_thread/thread/ff19340be0aa5e77/5ececad5208059b7?lnk=gst&amp;amp;q=TransformResults#5ececad5208059b7"&gt;Proposed change to TransformResults&lt;/a&gt; – May 18, 2012&lt;/li&gt; &lt;li&gt;&lt;a href="https://groups.google.com/group/ravendb/browse_thread/thread/c3d0e2cbcb9be4e3/3254eb72e99064d0?lnk=gst&amp;amp;q=Transform+Results#3254eb72e99064d0"&gt;The New Transform Results&lt;/a&gt; – Jan 25, 2013&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In this case, we didn’t get to this feature in time for the 2.0 release, but we kept thinking and refining the approach for that. &lt;/p&gt; &lt;p&gt;The interesting things that in those cases, we usually “design” things by doing the high level user visible API and then just let it percolate. There are a &lt;em&gt;lot&lt;/em&gt; of additional things that we would need to change to make this work (backward compatibility being a major one), so there is a lot of additional work to be done, but that can be done during the work. Right now we can let it sit, get users’ feedback on the proposed design and get the current minor release out of the door.&lt;/p&gt;</description><link>http://ayende.com/blog/161025/hibernating-rhinos-practices-design?key=14707226-592c-4b71-a7e6-8b691543ebd9</link><guid>http://ayende.com/blog/161025/hibernating-rhinos-practices-design?key=14707226-592c-4b71-a7e6-8b691543ebd9</guid><pubDate>Wed, 06 Feb 2013 10:00:00 GMT</pubDate></item><item><title>Hibernating Rhinos Practices: Pairing, testing and decision making</title><description>&lt;p&gt;We actually pair quite a lot, either physically (most of our stations have two keyboards &amp;amp; mice for that exact purpose) or remotely (Skype / Team Viewer).&lt;/p&gt; &lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/pairing-testing-and-decision-making_C5A6/2013-01-27%2014.05.24%20HDR_2.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="2013-01-27 14.05.24 HDR" border="0" alt="2013-01-27 14.05.24 HDR" src="http://ayende.com/blog/Images/Windows-Live-Writer/pairing-testing-and-decision-making_C5A6/2013-01-27%2014.05.24%20HDR_thumb.jpg" width="360" height="480"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And yet, I would say that for the vast majority of cases, we don’t pair. Pairing is usually called for when we need two pairs of eyes to look at a problem, for non trivial debugging and that is about it.&lt;/p&gt; &lt;p&gt;Testing is something that I deeply believe in, at the same time that I distrust unit testing. Most of our tests are actually system tests. That test the system end to end. Here is an example of such a test:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[Fact]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CanProjectAndSort()
{
    &lt;span class="kwrd"&gt;using&lt;/span&gt;(var store = NewDocumentStore())
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt;(var session = store.OpenSession())
        {
            session.Store(&lt;span class="kwrd"&gt;new&lt;/span&gt; Account
            {
                Profile = &lt;span class="kwrd"&gt;new&lt;/span&gt; Profile
                {
                    FavoriteColor = &lt;span class="str"&gt;"Red"&lt;/span&gt;,
                    Name = &lt;span class="str"&gt;"Yo"&lt;/span&gt;
                }
            });
            session.SaveChanges();
        }
        &lt;span class="kwrd"&gt;using&lt;/span&gt;(var session = store.OpenSession())
        {
            var results = (from a &lt;span class="kwrd"&gt;in&lt;/span&gt; session.Query&amp;lt;Account&amp;gt;()
                           .Customize(x =&amp;gt; x.WaitForNonStaleResults())
                           orderby a.Profile.Name
                           select &lt;span class="kwrd"&gt;new&lt;/span&gt; {a.Id, a.Profile.Name, a.Profile.FavoriteColor}).ToArray();


            Assert.Equal(&lt;span class="str"&gt;"Red"&lt;/span&gt;, results[0].FavoriteColor);
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most of our new features are usually built first, then get tests for them. Mostly because it is more efficient to get things done by experimenting a lot without having tests to tie you down.&lt;/p&gt;
&lt;p&gt;Decision making is something that I am trying to work on. For the most part, I have things that I feel very strongly about. Production worthiness is one such scenario, and I get annoyed if something is obviously stupid, but a lot of the time decisions can fall into the either or category, or are truly preferences issues. I still think that too much goes through me, including things that probably should not.&amp;nbsp; I am trying to encourage things so I wouldn’t be in the loop so much. We are making progress, but we aren’t there yet.&lt;/p&gt;
&lt;p&gt;Note that this post is mostly here to serve as a point of discussion. I am not really sure what to put in here, the practices we do are pretty natural, from my point of view. And I would appreciate any comments asking for clarifications.&lt;/p&gt;</description><link>http://ayende.com/blog/160902/hibernating-rhinos-practices-pairing-testing-and-decision-making?key=42eb0a9e-8481-4897-a1b5-13fbd2e09623</link><guid>http://ayende.com/blog/160902/hibernating-rhinos-practices-pairing-testing-and-decision-making?key=42eb0a9e-8481-4897-a1b5-13fbd2e09623</guid><pubDate>Tue, 05 Feb 2013 10:00:00 GMT</pubDate></item><item><title>Hibernating Rhinos Practices: Intro</title><description>&lt;p&gt;I was &lt;a href="http://ayende.com/blog/160706/design-patterns-in-the-test-of-time-iterator?key=6d22c7155f0d4cf29e6084648b24fb71"&gt;asked&lt;/a&gt; to comment a bit on our internal practices in Hibernating Rhinos. Before I can do that, I have to explain about how we are structured.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The development team in Israel compose the core of the company.&lt;/li&gt; &lt;li&gt;There are additional contractors that do work in Poland, the states and the UK. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We rarely make distinctions between locations for work, although obviously we have specializations. &lt;a href="http://blog.functionalfun.net/"&gt;Samuel&lt;/a&gt; is our go to guy for “Make things pretty” and “Silverlight hairloss”, for example, Arek is the really good in pointing to the right direction when there is a problem, and so on.&lt;/p&gt; &lt;p&gt;We currently have the following projects in place:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;RavenDB&lt;/li&gt; &lt;li&gt;Uber Profiler&lt;/li&gt; &lt;li&gt;RavenFS&lt;/li&gt; &lt;li&gt;License / Orders Management&lt;/li&gt; &lt;li&gt;RavenDB.Net&lt;/li&gt; &lt;li&gt;HibernatingRhinos.com&lt;/li&gt; &lt;li&gt;ayende.com&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Note that this is probably a partial list. And you might have noticed that I also included internal stuff, because that is also work, and something that we do.&lt;/p&gt; &lt;p&gt;In general, there isn’t a lot of “you work on this, or you work on that”, although again, there are areas of specialization. Fitzchak has been doing a lot of the work on Uber Prof, and Daniel is spending a lot of time on the RavenDB Studio. That doesn’t mean that tomorrow you wouldn’t find Fitzchak hacking on RavenDB indexes or Pawel working on exporting the profiler data to excel, and so on.&lt;/p&gt; &lt;p&gt;Next, I’ll discuss how we deal with the development workflow.&lt;/p&gt;</description><link>http://ayende.com/blog/160899/hibernating-rhinos-practices-intro?key=c8f1ab21-1220-44c8-b516-665a90e6a3a3</link><guid>http://ayende.com/blog/160899/hibernating-rhinos-practices-intro?key=c8f1ab21-1220-44c8-b516-665a90e6a3a3</guid><pubDate>Wed, 30 Jan 2013 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Mediator</title><description>&lt;p&gt;The mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Mediator_pattern"&gt;More about this pattern can be found here.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Like the Façade pattern, I can absolutely see the logic of wanting to use a mediator. It is supposed to make it easier to work with a set of objects, because it hides their interactions.&lt;/p&gt; &lt;p&gt;In practice, almost all known cases are bad ones. In fact, in most systems that I have seen any association of the name to the actual pattern it is supposed to represent is not very associated at &lt;em&gt;all.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;The differences between façade and mediator are minute, and you would think the same advice would apply. However, while you can find a &lt;em&gt;lot&lt;/em&gt; of usages of facades (or at least things people would call facades), there are very few real world examples of mediator pattern in use. And almost all of them carry the marks that say: “Just read GoF book, @w$0m3!!!”&lt;/p&gt;</description><link>http://ayende.com/blog/160737/design-patterns-in-the-test-of-time-mediator?key=22dc1aa4-b86e-42aa-b508-f14492b3d5d3</link><guid>http://ayende.com/blog/160737/design-patterns-in-the-test-of-time-mediator?key=22dc1aa4-b86e-42aa-b508-f14492b3d5d3</guid><pubDate>Mon, 21 Jan 2013 14:01:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Iterator</title><description>&lt;p&gt;In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Iterator_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It is really hard to think about any other pattern that has been more successful. In particular, patterns have long been about overcoming shortcoming of the language or platform.&lt;/p&gt; &lt;p&gt;In this case, iterators has became part of both language and platform in most modern systems.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;System.Collection.IEnumerable&lt;/li&gt; &lt;li&gt;java.util.Iterator&lt;/li&gt; &lt;li&gt;Python’s __iter__()&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Basically, it is so good, it is everywhere.&lt;/p&gt;</description><link>http://ayende.com/blog/160706/design-patterns-in-the-test-of-time-iterator?key=6d22c715-5f0d-4cf2-9e60-84648b24fb71</link><guid>http://ayende.com/blog/160706/design-patterns-in-the-test-of-time-iterator?key=6d22c715-5f0d-4cf2-9e60-84648b24fb71</guid><pubDate>Fri, 18 Jan 2013 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Interpreter</title><description>&lt;p&gt;In computer programming, the interpreter pattern is a design pattern that specifies how to evaluate sentences in a language. The basic idea is to have a class for each symbol (terminal or nonterminal) in a specialized computer language. The syntax tree of a sentence in the language is an instance of the composite pattern and is used to evaluate (interpret) the sentence.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Interpreter_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Along with the visitor pattern, this is still a very useful pattern, but in a very small but important context. Parsing and executing code. We see those quite often. In particular, JavaScript is probably the most common place where we see interpreters.&lt;/p&gt; &lt;p&gt;That said, unless you are actually dealing with executing code, there is very little reason for you to want to apply this pattern. In fact, I have seem people go for that several times for purposes that I really can’t explain.&lt;/p&gt; &lt;p&gt;Interpreter is for code execution. It has some interesting differences from compiling the code. For one, it is a lot easier to write, and for the most part, performance is great. This is especially true because the hard parts (the text parsing) are usually done up front and then you are just executing the AST.&lt;/p&gt; &lt;p&gt;From my perspective, we use Jint, a JS interpreter in RavenDB because compiling to IL and running that was complex. Any bugs there was &lt;em&gt;complex&lt;/em&gt; to figure out, and most important from our point of view, we really needed to be able to place limits on what you could do. The number of steps that can be taken, the recursion depth, and so on. Doing so with compiled code requires you to have kernel level access, or doing things like Thread Abort.&lt;/p&gt; &lt;p&gt;So Interpreters are good, but watch out when you use it, if it ain’t code that you are going to run, why are you writing this in the first place?&lt;/p&gt;</description><link>http://ayende.com/blog/160705/design-patterns-in-the-test-of-time-interpreter?key=6569a596-5b70-4570-8fb8-5168c9602c8a</link><guid>http://ayende.com/blog/160705/design-patterns-in-the-test-of-time-interpreter?key=6569a596-5b70-4570-8fb8-5168c9602c8a</guid><pubDate>Thu, 17 Jan 2013 10:00:00 GMT</pubDate></item><item><title>Active vs. Passive code bases</title><description>&lt;p&gt;I was review code at a customer site, and he had a lot of classes that looked something like this:&lt;/p&gt; &lt;blockquote&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ValidationData&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Type {get;set;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Value {get;set;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;In the database, he would have the data like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Active-vs.-Passing-code-bases_B440/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Active-vs.-Passing-code-bases_B440/image_thumb.png" width="499" height="172"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is obviously a very simple example, but it gets the job done, I think.&lt;/p&gt;
&lt;p&gt;In his code base, the customer had several instance of this example, for validation of certain parts of the system, for handling business rules, for checking how to handle various events, and I think you get the picture. &lt;/p&gt;
&lt;p&gt;I seriously dislike such codebases. You take an innocent piece of code and make it so passive it… well, you can see:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ayende.com/blog/Images/Windows-Live-Writer/Active-vs.-Passing-code-bases_B440/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://ayende.com/blog/Images/Windows-Live-Writer/Active-vs.-Passing-code-bases_B440/image_thumb_1.png" width="198" height="206"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is why this is bad. The code is passive, it is just a data holder. And that means that in order to process it you are going to have some &lt;em&gt;other&lt;/em&gt; code that handles that for you. That likely means a switch statement of the equivalent. And it also means that making any sort of change now have to happen on multiple locations. Puke.&lt;/p&gt;
&lt;p&gt;For fun, using this anti pattern all over your codebase result in you have to do this over and over again, for any new interesting thing that you are doing .It is a lot of work, and a lot of places that you have to change.&lt;/p&gt;
&lt;p&gt;But you can be a hero and set the code free:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.bigbadtoystore.com/images/products/out/large/HH10047.jpg" width="640" height="480"&gt;&lt;/p&gt;
&lt;p&gt;You do that by making a very simple change. Instead of having passive data containers that other pieces of the code need to react to, make them &lt;em&gt;active&lt;/em&gt;.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; AvoidCurseWordsValidator : IValidator&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] CurseWords {get;set;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate(...) { }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MaxLenValidator : IValidator&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MaxLen {get; set;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate(...) { }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; InvalidCharsValidator : IValidator&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;char&lt;/span&gt;[] InvalidChards {get;set;}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Validate(...) { }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now, if we want to modify / add something, we can do this in only one spot. Hurray for Single Responsibility and Open Closed principles.&lt;/p&gt;
&lt;p&gt;SO… don’t let your codebase be dominated by switch statements, parallel hierarchies and other nasties. Make it go active, and you’ll like the results.&lt;/p&gt;</description><link>http://ayende.com/blog/160514/active-vs-passive-code-bases?key=1a6bad43-b269-47ae-bab2-68d923538825</link><guid>http://ayende.com/blog/160514/active-vs-passive-code-bases?key=1a6bad43-b269-47ae-bab2-68d923538825</guid><pubDate>Thu, 03 Jan 2013 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Command, Redux</title><description>&lt;p&gt;In my previous post about the command pattern, I gushed about how much I loved it. That doesn’t mean that the command pattern as originally envisioned is still completely in fashion.&lt;/p&gt; &lt;p&gt;In particular, the notion of “Undo” was&amp;nbsp; one of the major features in the command pattern’s cap. Today, that is almost never the case. Sure, if you are building an application such as an editor. Something like Photoshop or a text editor would find the notion of commands with the ability to have an undo stack very compelling. Other than that, however, that is a very rare need.&lt;/p&gt; &lt;p&gt;In most business scenarios, there really is no good way to undo things. How would you implement SendEmailCommand.Undo(), for example? But even something like PlaceOrder.Undo() is a &lt;em&gt;lot&lt;/em&gt; more complex and hard to do than you would think. The mere notion of undoing the operation assumes that this isn’t going to have any side affects. But cancelling an order may result in cancellation fees, require you to ship back things you got back, end. It is &lt;em&gt;not&lt;/em&gt; “Undoing PlaceOrder”, rather that is a whole different and distinct business process, usually represented by another command: CancelOrder.&lt;/p&gt; &lt;p&gt;Another common issue that people have is the degeneration of the entire architecture to something like:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;CommandExecuter.Execute(Command cmd);&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;To that I answer, more power to you! I &lt;em&gt;love&lt;/em&gt; code that is composed of a lot of small classes all doing things about the same way. There is no easier way to look at a system, and that allows you to quite easily add additional functionality to the system easily. That said, mind how you handle routing in that scenario. I have seen people go into the “when a request comes to this URL, let us invoke the following commands” in XML. One of the reasons that people dislike this approach is &lt;em&gt;how&lt;/em&gt; you actually call this. If just getting to the command executer is hard and involved, you lose a lot of the advantages.&lt;/p&gt; &lt;p&gt;This popped up in the mailing list, and I &lt;em&gt;really&lt;/em&gt; dislike it. The notion of Composite Command. A command that can execute multiple commands. Now, from a programming point of view, I can easily see why you would want to do that. The PlaceOrderCommand operation &lt;em&gt;is &lt;/em&gt;composed of a lot of smaller commands. But, and this is &lt;em&gt;important&lt;/em&gt;, the notion of Composite Commands basically mean that you get the same thing as the PlaceOrderCommand, but you just lost the &lt;em&gt;name&lt;/em&gt;. And naming is important. Almost as important, error handling is quite different between different business scenarios, and you sometimes end up with something like:&lt;/p&gt; &lt;blockquote&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; placeOrderCommand = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositeCommand(&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RegisterOrderCommand(),&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ReserveStockCommand(),&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ChargeCardCommand(),&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ShipOrderCommand()&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; )&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;    Sequential = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;    StopOnError = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;And this is &lt;em&gt;simple&lt;/em&gt;, how do you handle an error in the ShipOrderCommand after you already charged the card, for example? &lt;/p&gt;</description><link>http://ayende.com/blog/159969/design-patterns-in-the-test-of-time-command-redux?key=a4f5a0b6-d2c6-4949-bc44-e9d567d16340</link><guid>http://ayende.com/blog/159969/design-patterns-in-the-test-of-time-command-redux?key=a4f5a0b6-d2c6-4949-bc44-e9d567d16340</guid><pubDate>Wed, 21 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Command</title><description>&lt;p&gt;The command pattern is a behavioral design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Command_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I &lt;em&gt;adore&lt;/em&gt; this pattern. If this pattern had a paypal account, I would donate it money on a regular basis.&lt;/p&gt; &lt;p&gt;In general, the notion of encapsulating the method call into an object (like the functor sin C++) is an incredibly powerful idea, because is separate the idea of selecting &lt;em&gt;what&lt;/em&gt; to invoke and &lt;em&gt;when&lt;/em&gt; to invoke it. Commands are used pretty much every where, WPF is probably the most obvious place, because it actually have the notion of Command as a base class that you are supposed to be using.&lt;/p&gt; &lt;p&gt;Other variations, like encapsulating a bunch of code to be executed later (job / task), or just being able to isolate a complex behavior into its own object, is also very useful. I base quite a lot of my architectural advice on the notion that you can decompose a system to a series of commands that you can compose and shuffle at will.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: Use it. Often. In fact, if you go so far as to say that the only reason we have classes is to have a nice vehicle for creating commands, you wouldn’t be going far enough.&lt;/p&gt; &lt;p&gt;Okay, I am kidding, but I really like this pattern, and it is a useful one quite often. The thing that you want to watch for are commands that are too granular. IncrementAgeCommand that is basically wrapping Age++ is probably too much, for example. Commands are supposed to be doing something &lt;em&gt;meaningful&lt;/em&gt; from the scope of the entire application.&lt;/p&gt;</description><link>http://ayende.com/blog/159873/design-patterns-in-the-test-of-time-command?key=c531f491-2497-4fe1-b341-db071f5c9aaa</link><guid>http://ayende.com/blog/159873/design-patterns-in-the-test-of-time-command?key=c531f491-2497-4fe1-b341-db071f5c9aaa</guid><pubDate>Mon, 19 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Chain of responsibility</title><description>&lt;p&gt;The chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It is actually quite common to see this pattern now-a-days using events. Something like &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.canceleventargs.aspx"&gt;CancelEventArgs&lt;/a&gt; and a &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.canceleventhandler.aspx"&gt;CancelEventHandler&lt;/a&gt; to handle the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx"&gt;FormClosing&lt;/a&gt; event of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx"&gt;Form&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;We use Chain of Responsibility in RavenDB in several places, like this one:&lt;/p&gt; &lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var requestResponderLazy &lt;span class="kwrd"&gt;in&lt;/span&gt; currentDatabase.Value.RequestResponders)
{
  var requestResponder = requestResponderLazy.Value;
  &lt;span class="kwrd"&gt;if&lt;/span&gt; (requestResponder.WillRespond(ctx))
  {
    var sp = Stopwatch.StartNew();
    requestResponder.Respond(ctx);
    sp.Stop();
    ctx.Response.AddHeader(&lt;span class="str"&gt;"Temp-Request-Time"&lt;/span&gt;, sp.ElapsedMilliseconds.ToString(&lt;span class="str"&gt;"#,# ms"&lt;/span&gt;, CultureInfo.InvariantCulture));
    &lt;span class="kwrd"&gt;return&lt;/span&gt; requestResponder.IsUserInterfaceRequest;
  }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that we have moved on the the behavioral patterns, and those tend to have withstand the test of time much better, in general.&lt;/p&gt;
&lt;p&gt;Other places where Chain of Responsibility is used is request routing and error handling. A common approach is to also have this done by delegating, where I am handling what I can and passing on to the next object if I don’t know how to handle a request.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: This is still a very useful pattern. One thing to note is that it is effectively an O(N) operation with respect to the number of items in the chain that you have. As usual, do not overuse, but it is a really nice pattern.&lt;/p&gt;</description><link>http://ayende.com/blog/159841/design-patterns-in-the-test-of-time-chain-of-responsibility?key=0db8c25c-820b-40f1-a31d-f3875d5a3303</link><guid>http://ayende.com/blog/159841/design-patterns-in-the-test-of-time-chain-of-responsibility?key=0db8c25c-820b-40f1-a31d-f3875d5a3303</guid><pubDate>Fri, 16 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Proxy</title><description>&lt;p&gt;A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Proxy_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Proxies are just about everywhere. Whenever you use NHibernate, WCF or Remoting – you are using proxies. In fact, proxies are such a success that they are literally baked into both the language and the platform. In .NET we have TransparentProxy and in Java has &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html"&gt;&lt;code&gt;java.lang.reflect.Proxy&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;At any rate, proxies are really useful, especially when you think about dynamic proxies. I am far less fond of static proxies, although we use &lt;a href="https://github.com/ayende/ravendb/blob/master/Raven.Studio/Features/Alerts/AlertProxy.cs"&gt;them as well&lt;/a&gt;. Dynamic proxies are quite useful to add behavior, especially cross cutting behavior, at very little cost.&lt;/p&gt; &lt;p&gt;That said, one of the major issues that arises from using proxies is an inherit assumptions that the proxy is the same as its target. Commonly you see this happening with remote proxies, where it isn’t obvious that actually making the call is &lt;em&gt;expensive&lt;/em&gt; as hell.&lt;/p&gt; &lt;p&gt;Proxies also tend to be used mostly for the infrastructure of your application, rather than for actual application code. In particular, business logic, rather than cross cutting concerns, is really hard to figure out / debug when you have it spread around in proxies.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recommendation: &lt;/strong&gt;Use it for infrastructure or cross cutting concerns. Try doing so using dynamic proxies, rather than by generating proxies by hand. Avoid putting business logic there and be aware that by using proxies you are hiding what is going on (that is pretty much the point), so doing non obvious things should be avoided.&lt;/p&gt;</description><link>http://ayende.com/blog/159809/design-patterns-in-the-test-of-time-proxy?key=fdcf3a50-5601-41f3-bb7b-65e765962555</link><guid>http://ayende.com/blog/159809/design-patterns-in-the-test-of-time-proxy?key=fdcf3a50-5601-41f3-bb7b-65e765962555</guid><pubDate>Thu, 15 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Flyweight</title><description>&lt;p&gt;A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Flyweight_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;On the face of it, this patterns looks very much like something from the old ages. And indeed, most implementations of Flyweight are actually focused deeply on low memory conditions. I would actually argue that you need to consider very carefully when you want to do that.&lt;/p&gt; &lt;p&gt;That said, it is actually used fairly often in high performance places. In the .NET framework, the notion of string interning is one way to get flywieghts (although the problem is that you need to start with a string to get the intern string sort of mess things up). In both the profilers and in RavenDB, we have used variations on the Flyweight pattern.&lt;/p&gt; &lt;p&gt;In the profiler, we are mostly dealing with parsing data from the profiled system, and that means doing a &lt;em&gt;lot&lt;/em&gt; of reading from a stream and creating objects. That created an unacceptable memory pressure on the system. We implemented a fairly complex system where we can read from the stream into a buffer, then get or create the string from it. We contributed the implementation back to the Protocol Buffers project. You can see the code &lt;a href="http://code.google.com/p/protobuf-csharp-port/source/browse/src/ProtocolBuffers/ByteStringStringInterning.cs?spec=svn93cf393ba04df690fb10d0eb8e5d5eb4642ea9fb&amp;amp;r=93cf393ba04df690fb10d0eb8e5d5eb4642ea9fb"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;In RavenDB, we deal a lot with documents, and many times we find it useful to be caching a document. The problem with doing that is that you need to return &lt;em&gt;something&lt;/em&gt; from the cache, which means that you have to return something mutable. Instead of copying all of the data all the time, the internal RavenDB data structures supports copy-on-write semantics, which means that we can easily create clones at basically no cost.&lt;/p&gt; &lt;p&gt;Recommendation: If you are in a perf optimization mode, and you worry about memory pressure, consider using this. Otherwise, like all optimizations, it should be left alone until you have profiler results that says you should consider this.&lt;/p&gt;</description><link>http://ayende.com/blog/159713/design-patterns-in-the-test-of-time-flyweight?key=8f8454bc-4d8a-4542-a110-bce30d8af36b</link><guid>http://ayende.com/blog/159713/design-patterns-in-the-test-of-time-flyweight?key=8f8454bc-4d8a-4542-a110-bce30d8af36b</guid><pubDate>Wed, 14 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Midbook pattern crisis: Do NOT reach for that pattern</title><description>&lt;p&gt;From a question in the mailing list:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;How do you do to "rollback" an entity state supposing the following scenario.&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; JsonResult Reschedule(&lt;span class="kwrd"&gt;string&lt;/span&gt; id, DateTime anotherDate)
{
            &lt;span class="kwrd"&gt;try&lt;/span&gt;
            {
                var dinner = session.Load&amp;lt;Dinner&amp;gt;(id);
                dinner.ChangeDate(anotherDate);
                schedulerService.Schedule(dinner); 

                &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Message = &lt;span class="str"&gt;"Bon apetit!"&lt;/span&gt; });
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (DinnerConcurrencyException ex) 
            {
                &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Message = ex.Message });
            }
}

&lt;span class="rem"&gt;// Base controller&lt;/span&gt;
&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnActionExecuted(ActionExecutedContext filterContext) 
{
      &lt;span class="kwrd"&gt;if&lt;/span&gt;(filterContext.Exception != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            &lt;span class="kwrd"&gt;return&lt;/span&gt;;
      session.SaveChanges();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The problem that I have is when the schedulerService throws a DinnerConcurrencyException, it is catched at the controller.
&lt;p&gt;After all, the OnActionExecuted will call SaveChanges and persist the dinner with an invalid state.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The next post was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have already tried to use Memento Pattern like this:&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;try&lt;/span&gt;
{
    var dinner = session.Load&amp;lt;Dinner&amp;gt;(id);
    dinner.SaveState();
    dinner.ChangeDate(anotherDate);
    schedulerService.Schedule(dinner); 

    &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Message = &lt;span class="str"&gt;"Bon apetit!"&lt;/span&gt; });
}
&lt;span class="kwrd"&gt;catch&lt;/span&gt; (DinnerConcurrencyException ex) 
{
    dinner = dinner.RestoreState();
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Message = ex.Message });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;But didn't work, beacuse I think Raven has proxied my dinner instance.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;And here is the Memento implementation:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;[Serializable]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Entity
{
    MemoryStream stream = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream();

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SaveState()
    {
        &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryFormatter().Serialize(stream, &lt;span class="kwrd"&gt;this&lt;/span&gt;);
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; T RestoreState&amp;lt;T&amp;gt;()
    {
        stream.Seek(0, SeekOrigin.Begin);
        &lt;span class="kwrd"&gt;object&lt;/span&gt; o = &lt;span class="kwrd"&gt;new&lt;/span&gt; BinaryFormatter().Deserialize(stream);
        stream.Close();

        &lt;span class="kwrd"&gt;return&lt;/span&gt; (T)o;
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;You might notice that this create a &lt;em&gt;new&lt;/em&gt; instance when you call RestoreState, and that has no impact whatsoever on the actual instance that is managed by RavenDB.&lt;/p&gt;
&lt;p&gt;The suggested solution?&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;catch&lt;/span&gt; (DinnerConcurrencyException ex) 
{
    &lt;font style="background-color: #ffff00"&gt;SkipCallingSaveChanges = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/font&gt;
    &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(&lt;span class="kwrd"&gt;new&lt;/span&gt; { Message = ex.Message });
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt;
&lt;p&gt;No need for patterns here. &lt;/p&gt;</description><link>http://ayende.com/blog/159777/midbook-pattern-crisis-do-not-reach-for-that-pattern?key=393bd5cd-c31e-4b6b-8af1-7ac27a599b27</link><guid>http://ayende.com/blog/159777/midbook-pattern-crisis-do-not-reach-for-that-pattern?key=393bd5cd-c31e-4b6b-8af1-7ac27a599b27</guid><pubDate>Tue, 13 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Midbook patterns crisis: Façade is and ain’t</title><description>&lt;p&gt;I decided to comment to some of the comments in the blog in a full blown post, because they are quite important.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;View Model is not a façade. It doesn’t allow any operation, and it doesn’t simplify things. It merely give you an easy access to aggregate information.&lt;/li&gt; &lt;li&gt;No, every class is not a Façade. I don’t care if “it provides simplified interface to a larger body of code”. If everything is a façade, then façade is meaningless. &lt;/li&gt; &lt;li&gt;No, Web Request is no a façade. Sure, it hides a lot of details about TCP, but that isn’t its point. Web Request implements HTTP spec, and that isn’t a façade at all. &lt;/li&gt; &lt;li&gt;Web Client / Tcp Client / Tcp Listener are facades – they drastically simplify how to work with sockets. Good facades, too, because when you need to do more, they don’t block you.&lt;/li&gt; &lt;li&gt;NHibernate ain’t a façade – it hides ADO.NET, sure, but it also does a lot more then just that.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The whole point of this series of posts was &lt;em&gt;not&lt;/em&gt; to talk about patterns. If you want to do that, go ahead and read the books. My attempt is to go and talk about how the patterns are actually &lt;em&gt;used&lt;/em&gt;. In practice, in real code. &lt;/p&gt; &lt;p&gt;Sure, in the real world, patterns aren’t used as per their text book definition. That doesn’t mean that we should look at the text book definition. That means that we need to look at how they are actually used! I am not writing a series of posts talking about the problems in the patterns, and that is important. I am writing about the problems in how people use them.&lt;/p&gt;</description><link>http://ayende.com/blog/159745/midbook-patterns-crisis-facade-is-and-aint?key=2008a8f5-3912-4e72-8bd0-e3b5f1c43b74</link><guid>http://ayende.com/blog/159745/midbook-patterns-crisis-facade-is-and-aint?key=2008a8f5-3912-4e72-8bd0-e3b5f1c43b74</guid><pubDate>Mon, 12 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Façade</title><description>&lt;p&gt;A façade is an object that provides a simplified interface to a larger body of code, such as a class library.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Facade_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The &lt;em&gt;intent &lt;/em&gt;of the façade was good: to wrap APIs that are poorly designed in something shiny and nice.&lt;/p&gt; &lt;p&gt;In &lt;em&gt;the real world&lt;/em&gt;, however, it is an evil pattern that is used to needlessly add abstractions for no particular reason. For example, look at &lt;a href="http://www.codeproject.com/Articles/22069/Building-a-Multi-Tier-Web-Application-in-the-NET-3"&gt;this article&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;img alt="Business Facade - Detailed View" src="http://www.codeproject.com/KB/aspnet/NTierApp_UsingLINQ/BusinessFacade.jpg"&gt;&amp;nbsp;&lt;img alt="Data Access - Detailed View" src="http://www.codeproject.com/KB/aspnet/NTierApp_UsingLINQ/DataAccess.jpg"&gt;&lt;/p&gt; &lt;p&gt;That sound you just heard is your architecture, it is hiding in the closet, weeping silent tears about emotional and physical abuse that just doesn’t end.&lt;/p&gt; &lt;p&gt;I have yet to see a real case were façade was actually used properly. In most cases, people built a façade because That Is How We Do Things. And because of that, they ended up with things like the one above. It adds exactly nothing, and it horrifyingly complicates the code.&lt;/p&gt; &lt;p&gt;Recommendation: Avoid this, you really don’t need to do this most of the time, and most implementations are bad.&lt;/p&gt;</description><link>http://ayende.com/blog/159681/design-patterns-in-the-test-of-time-facade?key=75ff1f15-0a92-4f9a-8bfb-99606f815f98</link><guid>http://ayende.com/blog/159681/design-patterns-in-the-test-of-time-facade?key=75ff1f15-0a92-4f9a-8bfb-99606f815f98</guid><pubDate>Fri, 09 Nov 2012 10:00:00 GMT</pubDate></item><item><title>Design patterns in the test of time: Decorator</title><description>&lt;p&gt;The decorator pattern is a design pattern that allows behaviour to be added to an existing object dynamically.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;More about this pattern.&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I don’t have a lot to say about this pattern.&lt;/p&gt; &lt;p&gt;&lt;img alt="Hipster Ariel - Decorator? Used it before it was cool" src="http://cdn.memegenerator.net/instances/400x/28784327.jpg"&gt;&lt;/p&gt; &lt;p&gt;The decorator pattern is still just as useful if not more so as the time it was initially announced. It forms a core part of many critical function of your day to day software.&lt;/p&gt; &lt;p&gt;The most obvious example is the notion of Stream, where you often decorate a stream (Buffered Stream, Compressing Stream, etc). This example is valid not just for the .NET framework, I can’t think of a single major framework that doesn’t use the Stream abstraction for its IO.&lt;/p&gt; &lt;p&gt;Then again, the cautionary side, people try to use it in… strange ways:&lt;/p&gt; &lt;blockquote&gt; &lt;div id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; CondimentDecorator : Beverage {}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Mocha : CondimentDecorator&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Beverage m_beverage;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Mocha(Beverage beverage)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_beverage = beverage;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; String Description&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;     {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;         get&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;         {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_beverage.Description + &lt;span style="color: #006080"&gt;", Mocha"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;         }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; Cost()               &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;     {                                      &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; 0.20 + m_beverage.Cost();&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;     }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Something like this, for example, is a pretty bad way of doing things. It assumes a very fixed model of looking at the universe, which is just not true. Decorator works best when you have just a single I/O channel. When you have multiple inputs &amp;amp; outputs, decorating something becomes &lt;em&gt;much&lt;/em&gt; harder.&lt;/p&gt;
&lt;p&gt;In particular, implementing business logic like the one above in decorators make it very hard to figure out why things are happening. In particular, CachingDecorator is something that you want to avoid (better to use infrastructure or a auto caching proxy, instead).&lt;/p&gt;
&lt;p&gt;Recommendation: It is a very useful pattern, and should be used when you actually have one input / output channel, because that is a great way to allow to dynamically compose the way we apply processing to it.&lt;/p&gt;</description><link>http://ayende.com/blog/159553/design-patterns-in-the-test-of-time-decorator?key=648efa8d-37ce-4374-ba92-eb1f6b86c485</link><guid>http://ayende.com/blog/159553/design-patterns-in-the-test-of-time-decorator?key=648efa8d-37ce-4374-ba92-eb1f6b86c485</guid><pubDate>Wed, 07 Nov 2012 10:00:00 GMT</pubDate></item></channel></rss>