<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7289947411527326869</id><updated>2011-07-08T15:31:44.309+02:00</updated><category term='Decoupling'/><category term='Unit testing'/><category term='language'/><category term='Rant'/><category term='DDD'/><category term='projects'/><category term='procedural'/><category term='converting'/><category term='Events'/><category term='CQRS'/><category term='NetworkMonitor'/><category term='Object Oriented'/><title type='text'>David Perfors</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-2343784827868855784</id><published>2010-04-02T11:24:00.000+02:00</published><updated>2010-04-02T11:24:02.450+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit testing'/><title type='text'>xUnit.net vs MSpec?</title><content type='html'>For my personal projects I use MSpec as a testing framwork. MSpec had it's advantages and disadvantages. Here is an example of a test I wrote.&lt;br /&gt;&lt;div style="background: none repeat scroll 0% 0% black; color: white; font-family: Bitstream Vera Sans Mono; font-size: 11pt;"&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;37&lt;/span&gt;&amp;nbsp;&lt;span style="color: #cc7832;"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;When_setting_the_state_of_a_host&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;38&lt;/span&gt; {&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;39&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832;"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;static&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;HostCheckResultCommand&lt;/span&gt; command;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;40&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832;"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;static&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;HostCheckResultCommandHandler&lt;/span&gt; commandHandler;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;41&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832;"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;static&lt;/span&gt; &lt;span style="color: #6897bb;"&gt;IRepository&lt;/span&gt; _repository;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;42&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832;"&gt;private&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;static&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;Host&lt;/span&gt; _host;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;43&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;44&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #6897bb;"&gt;Establish&lt;/span&gt; context = () =&amp;gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;45&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;46&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _host = &lt;span style="color: #cc7832;"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;Host&lt;/span&gt;(&lt;span style="color: #a5c25c;"&gt;"asterix"&lt;/span&gt;);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;47&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _repository = &lt;span style="color: #ffc66d;"&gt;MockRepository&lt;/span&gt;.GenerateMock&amp;lt;&lt;span style="color: #6897bb;"&gt;IRepository&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;48&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _repository.Expect(x =&amp;gt; x.GetById&amp;lt;&lt;span style="color: #ffc66d;"&gt;Host&lt;/span&gt;&amp;gt;(&lt;span style="color: #a5c25c;"&gt;""&lt;/span&gt;))&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;49&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; .IgnoreArguments()&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;50&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; .Return(_host);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;51&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _repository.Expect(x =&amp;gt; x.Add&amp;lt;&lt;span style="color: #ffc66d;"&gt;Host&lt;/span&gt;&amp;gt;(&lt;span style="color: #cc7832;"&gt;null&lt;/span&gt;)).IgnoreArguments();&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;52&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; command = &lt;span style="color: #cc7832;"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;HostCheckResultCommand&lt;/span&gt;(&lt;span style="color: #a5c25c;"&gt;"asterix"&lt;/span&gt;, &lt;span style="color: #6897bb;"&gt;HostState&lt;/span&gt;.Up);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;53&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; commandHandler = &lt;span style="color: #cc7832;"&gt;new&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;HostCheckResultCommandHandler&lt;/span&gt;(_repository);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;54&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;55&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;56&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #6897bb;"&gt;Because&lt;/span&gt; of = () =&amp;gt; commandHandler.Execute(command);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;57&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #6897bb;"&gt;It&lt;/span&gt; should_have_a_HostStateChanged_event = () =&amp;gt; ((&lt;span style="color: #6897bb;"&gt;IEventProvider&lt;/span&gt;)_host).GetChanges().First().ShouldBeOfType&amp;lt;&lt;span style="color: #ffc66d;"&gt;HostStateChanged&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;58&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #6897bb;"&gt;It&lt;/span&gt; the_event_should_have_HostState_Up = () =&amp;gt; ((&lt;span style="color: #6897bb;"&gt;IEventProvider&lt;/span&gt;)_host).GetChanges().First&amp;lt;&lt;span style="color: #ffc66d;"&gt;HostStateChanged&lt;/span&gt;&amp;gt;().NewState.ShouldEqual(&lt;span style="color: #6897bb;"&gt;HostState&lt;/span&gt;.Up);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;59&lt;/span&gt; }&lt;/div&gt;&lt;/div&gt;MSpec has a lot of advantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Once you are used to lambda expresions, it is relative easy to read.&lt;/li&gt;&lt;li&gt;Since every test is in it's own class, tests can't conflict with each other.&lt;/li&gt;&lt;li&gt;Every test statement (It) is named and run even when another test statement failes.&lt;/li&gt;&lt;/ul&gt;Disadvantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Everything in the class should be static, since the use of anonymous functions.&lt;/li&gt;&lt;li&gt;Can be difficult to get started. &lt;/li&gt;&lt;/ul&gt;At work I started using xUnit.net as testing framework.&lt;br /&gt;&lt;div style="background: none repeat scroll 0% 0% black; color: white; font-family: Bitstream Vera Sans Mono; font-size: 11pt;"&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #cc7832;"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;class&lt;/span&gt; &lt;span style="color: #ffc66d;"&gt;A_Person&lt;/span&gt; : &lt;span style="color: #ffc66d;"&gt;XPODatabaseTestFixture&lt;/span&gt;&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;{&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="color: #ffc66d;"&gt;Fact&lt;/span&gt;]&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #cc7832;"&gt;public&lt;/span&gt; &lt;span style="color: #cc7832;"&gt;void&lt;/span&gt; can_be_created()&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ffc66d;"&gt;Person&lt;/span&gt; person = ObjectSpace.CreateObject&amp;lt;&lt;span style="color: #ffc66d;"&gt;Person&lt;/span&gt;&amp;gt;();&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #ffc66d;"&gt;Assert&lt;/span&gt;.NotNull(person);&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;}&lt;/div&gt;&lt;/div&gt;Well we don't compare the tests, because they are completly different, but we can compare the frameworks.&lt;br /&gt;The main advantages xUnit.Net has are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Every test is performed isolated, for every test method a new instance of the object is created.&lt;/li&gt;&lt;li&gt;The test runner is very fast, tests are run in different threads, multiple at a time.&lt;/li&gt;&lt;li&gt;Can use the constructor for common setup and IDisposable for teardown. (Setup and teardown contain logic that is run before and after each test. other frameworks use the [Setup] and [Teardown] attributes)&lt;/li&gt;&lt;/ul&gt;The only disadvantage I found in both (and other) test framework is that there is no VisualStudio testsrunner provided. You either need to use the extenal test runner they provide, or a tool like Testdriven.Net, Resharper or DevExpress Coderush.&lt;br /&gt;&lt;br /&gt;Although I like MSpec very much, I am going to dump it for xUnit.net. With xUnit.net I don't have to think about making my members static.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-2343784827868855784?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/2343784827868855784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2010/04/xunitnet-vs-mspec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2343784827868855784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2343784827868855784'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2010/04/xunitnet-vs-mspec.html' title='xUnit.net vs MSpec?'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-4674509833005340562</id><published>2010-02-19T13:54:00.000+01:00</published><updated>2010-02-19T13:54:07.207+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Decoupling'/><category scheme='http://www.blogger.com/atom/ns#' term='CQRS'/><title type='text'>CQRS the simple way.</title><content type='html'>CQRS stands for Command Query Responsibility Segregation and is a pattern that splits an application into two parts: Commands and Queries.&lt;br /&gt;Queries are used to get data from a datasource (like a database) and commands are used to do something with the data.&lt;br /&gt;The simplest form of CQRS is the following:&lt;br /&gt;&lt;br /&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;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; BlogQueryService&lt;br /&gt;{&lt;br /&gt;    IEnumerable&amp;lt;Blog&amp;gt; GetAllBlogPosts();&lt;br /&gt;    Blog GetBlogPost(&lt;span class="kwrd"&gt;int&lt;/span&gt; blogid);&lt;br /&gt;    IEnumerable&amp;lt;Comment&amp;gt; GetAllCommentsForPost(&lt;span class="kwrd"&gt;int&lt;/span&gt; blogid);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; BlogCommandService&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; NewBlogPost(&lt;span class="kwrd"&gt;string&lt;/span&gt; title, &lt;span class="kwrd"&gt;string&lt;/span&gt; text);&lt;br /&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; EditBlogPost(Blog editedBlog);&lt;br /&gt;    &lt;span class="kwrd"&gt;void&lt;/span&gt; AddComment(&lt;span class="kwrd"&gt;int&lt;/span&gt; blogid, &lt;span class="kwrd"&gt;string&lt;/span&gt; comment);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The BlogCommandService just updates the datasource with the given data (and does validation if needed) the query service just return simple data.&lt;br /&gt;Of course this is not scalable and a lot of advantages that &lt;a href="http://www.udidahan.com/"&gt;Udi Dahan&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/gregyoung/default.aspx"&gt;Greg Young&lt;/a&gt; describe are not here, but it is a first step to decouple a lot of applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-4674509833005340562?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/4674509833005340562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2010/02/cqrs-simple-way.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4674509833005340562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4674509833005340562'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2010/02/cqrs-simple-way.html' title='CQRS the simple way.'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-2245472352058327716</id><published>2010-02-15T13:45:00.000+01:00</published><updated>2010-02-15T13:45:06.824+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit testing'/><title type='text'>Make development easier and faster with unit testing</title><content type='html'>&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;br /&gt;As software developers we always come across bugs, some bugs are not very difficult to fix and other bugs are more difficult. Sometimes it is even hard to find the place in code where the bug is coming from and sometimes when we fix a bug we introduce several other without knowing it.&lt;br /&gt;The solution for this problem are unit tests.&lt;br /&gt;&lt;br /&gt;Another problem we have is that the user wants to know that the software (s)he is using is reliable. We as software developers should be able to tell the user that the software we are writing is reliable. And we should be able to tell that we have implemented features the way the user wants it and not the way we think they want it or should use it. Basically the user is king.&lt;br /&gt;The way to get some reliability is unit testing.&lt;br /&gt;&lt;br /&gt;So what are unit tests?&lt;br /&gt;A unit test is code that is testing the software we have been writing or are going to write. You can test software on multiple levels.&lt;br /&gt;First we can test functions/methods directly like this:&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Add(&lt;span class="kwrd"&gt;int&lt;/span&gt; x, &lt;span class="kwrd"&gt;int&lt;/span&gt; y)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; x + y;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[Test]&lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestAdd()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;int&lt;/span&gt; result = Add(2, 3);&lt;br /&gt;   Assert.AreEqual(5, result);&lt;br /&gt;}&lt;/pre&gt;Second you can test bigger parts of the system:&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[Test]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; When_playing_files_that_donot_exist_give_error()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    ProgramPlayer player = &lt;span class="kwrd"&gt;new&lt;/span&gt; ProgramPlayer();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;       player.Play(&lt;span class="str"&gt;"filethatdoesnotexist.mp3"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;       Assert.Fail(&lt;span class="str"&gt;"Exception was not thrown"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;catch&lt;/span&gt;(FileNotFoundException ex)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        Assert.IsNotNull(ex);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }    &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;And you can test complete usecases and programs.&lt;br /&gt;&lt;br /&gt;For most people it seems like wast of time to write unit tests. When I first started with unit tests it was like I wasted time (although at that time I was at university), but after some time and a lot of improvements I realized that unit testing does help. Last year I had to write code for some really difficult calculation. A colleague made the calculations on paper so that I could validate it.&lt;br /&gt;So I wrote some tests for all those calculations and I started to work out a solution.&lt;br /&gt;I soon found out that is was easy to split up the solution in multiple parts, so I wrote unit tests for each part of the solution as well and soon I had a working implementation.&lt;br /&gt;At that moment I didn't even have a user interface to test it in. I found out that working with unit testing is much faster than without. You can test specific parts of the program very fast without the need of starting the application and navigate to the place where you are using the feature you are testing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-2245472352058327716?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/2245472352058327716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2010/02/make-development-easier-and-faster-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2245472352058327716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2245472352058327716'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2010/02/make-development-easier-and-faster-with.html' title='Make development easier and faster with unit testing'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-4352467157626356525</id><published>2010-01-07T10:08:00.001+01:00</published><updated>2010-01-07T10:08:35.551+01:00</updated><title type='text'>Refactor spagethi Form code to something usefull</title><content type='html'>There are a lot of applications that are very difficult to maintain. The original writers would not always agree about that statement, but others will see their code as an unmanageable mess.&lt;br&gt;I will not blame the original writers of those applications. A lot of them started with software development as their hobby or out of interest. During time they learned some "best practises" by reading tutorials about how to write desktop applications using forms (like in Visual Basic or Delphi). These tutorials tell you that in the event handlers you put the code that should be run when somebody presses a button or when an item is selected. There are even components like timers that could let you do stuff at specific times / intervals.&lt;br&gt;For tutorials this is OK and I did it as well, but I realised that it is plain stupid to do so. The problem is that you get large chunks of code within event handlers and forms. At some point it will be difficult to know where some piece of code can be found. Is it on FormA, FormB or (even worse) on both?&lt;br&gt;&lt;br&gt;In the rest of this post I want to describe some small steps to re-factor to easier to maintain and understand code. As an example I use a simple application to manage data from media files. There is a form that add/edit music, it has a save button and&amp;nbsp; a close button.&lt;br&gt;&lt;h2&gt;Get code out of event handlers.&lt;/h2&gt;The first step is to get event handlers as small as possible. Put all the code that is currently in the event handler into a method and call that method in the event handler. An example:&lt;br&gt;In the form for adding and editing music information we have a lot of code in the OnSaveClicked event handler. There is code to see whether we are adding or editing the music, there is code to fill the data set (or the sql query, or whatever we are using for persistence) and there is some validation code. That would be at least 15 to 30 rows of code. (depending on how much information we can fill in). By moving all this code to a separate method we can easily call this same method from the OnClosed event handler to let the user save the changes when closing the form.&lt;br&gt;&lt;h2&gt;Split code that is interacting with the controls from other code.&lt;/h2&gt;In the method to save the music information we are still asking the information from every input control. So let say we have a textbox to fill in the year of when the music is written, we would call txtYear.Text to get the information. We will probably do this at least two times (one for the validation, because this is a required field and two for saving the value). When we want to change to control to a DateTime control, we have change the code for validation and the code for saving the value which could lead to unexpected behaviour (a.k.a. bugs).&lt;br&gt;A better way would be to have a method that accepts parameters (one for every field that should be saved). You will then get the following code:&lt;br&gt;&lt;blockquote&gt;public void OnSavedEvent(object sender, EventArg e)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveMusic();&lt;br&gt;}&lt;br&gt;&lt;br&gt;private void SaveMusic()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string name = txtName.Text;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // int year = Int32.ParseToInt(txtYear.Text); // we used a textbox but now we have a special control called YearPicker which gives back an integer.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int year = yearPicker.Year;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string composer = txtComposer.Text;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveMusic(name, year, composer);&lt;br&gt;}&lt;br&gt;&lt;br&gt;private void SaveMusic(string name, int year, string composer)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // do a lot of stuff with name, year and composer&lt;br&gt;}&lt;br&gt;&lt;/blockquote&gt;This way we can easily change a control without worrying about whether something goes wrong with saving the data.&lt;br&gt;&lt;h2&gt;Separate concerns.&lt;/h2&gt;To be honest, I don't like to much knowledge within a form. A form is there to display data and to handle input and&amp;nbsp; a little but for orchestrate the application flow (more on this in a later post).&lt;br&gt;Doing stuff with data (and getting the data) could better be done in a separate class. So we can create a class called MusicDataService, which has the SaveMusic(string name, int year, string composer) method. It will also get some methods to load the data.&lt;br&gt;&lt;blockquote&gt;public struct Music&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Name;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Year;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Composer;&lt;br&gt;}&lt;br&gt;&lt;br&gt;public class MusicDataService&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void SaveMusic(Music music) {/* lot of stuff to be done... */ }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Music GetMusicWithName(string name)  {/* lot of stuff to be done... */ }&lt;br&gt;}&lt;br&gt;&lt;br&gt;public class MusicAddView()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private MusicDataService _service = new MusicDataService();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void OnSavedEvent(object sender, EventArg e)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveMusic();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private void SaveMusic()&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Music music = new Music();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;music.name = txtName.Text;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; music.year = yearPicker.Year;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;music.composer = txtComposer.Text;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;_service.SaveMusic(music);&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;/blockquote&gt;Now that we have the knowledge of saving music separated from it's form, we can use the same code at multiple places if we want.&lt;br&gt;&lt;h2&gt;Smaller methods.&lt;/h2&gt;As I said the SaveMusic method in the MusicDataService contains a lot of logic. It validates the input and it makes sure that it gets persisted. Since validation on it's own can contain a lot of code, it is recommended to put this in a separate method as well. This gives us an other advantage. We can now validate the Music structure multiple times even when we don't want to save. When editing the object we can directly validate the input and gave the user feedback.&lt;br&gt;The real implementations of validating and saving data I will not show, since this is very specific for each applications and there are just to much ways of doing it (and frameworks that could be used). This said it is probably a good idea to make that code pluggable, so we can swap the implementation if we want to. (how to do this could be another post.. you can also use google)&lt;br&gt;&lt;h2&gt;Conclusion.&lt;/h2&gt;In this post I tried to show that using some easy steps it is not to difficult to make your program easier to maintain, easier to test and easier to understand for new software developers. And this all leads to a more solid application.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-4352467157626356525?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/4352467157626356525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2010/01/refactor-spagethi-form-code-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4352467157626356525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4352467157626356525'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2010/01/refactor-spagethi-form-code-to.html' title='Refactor spagethi Form code to something usefull'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-3752879447664365563</id><published>2009-12-10T14:03:00.000+01:00</published><updated>2009-12-10T14:03:08.200+01:00</updated><title type='text'>Excellent post about CQRS by Udi Dahan</title><content type='html'>Udi Dahan has &lt;a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/"&gt;published an excellent blog post about Command Query Responsibility Segregation&lt;/a&gt;. This is a really interesting approach of software development, and I tend to follow that approach in my NetworkMonitoring system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-3752879447664365563?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/3752879447664365563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/12/excellent-post-about-cqrs-by-udi-dahan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3752879447664365563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3752879447664365563'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/12/excellent-post-about-cqrs-by-udi-dahan.html' title='Excellent post about CQRS by Udi Dahan'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-8457263910042224886</id><published>2009-12-09T10:52:00.000+01:00</published><updated>2009-12-09T10:52:14.529+01:00</updated><title type='text'>The power of patterns</title><content type='html'>The user interface is one of the most important parts of an application, at least for the end user. It is also the part of the application that will change a lot during the life cycle of an application. Sometimes I even think that you can just make some changes in the user interface and call it a new version of the product and users will be happy.&lt;br /&gt;So to be able to change the user interface without much trouble is a must. But with a lot of applications I saw, this is not possible.What is the problem? The user interface contains to much logic.&lt;br /&gt;This is a problem that many people had and there are some easy ways to solve this...&lt;br /&gt;&lt;span style="font-size: large;"&gt;Patterns&lt;/span&gt;&lt;br /&gt;When a couple of people found the same problem and a solution for it, we can call of a pattern. A pattern is just a &lt;b&gt;description&lt;/b&gt; of the solution and not the solution itself, so most of the time you have to modify the pattern a little bit to make it work efficiently in your own situation.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://yuml.me/1ea68bc" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="53" src="http://yuml.me/1ea68bc" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;A pattern we can use for our user interface problem is the &lt;b&gt;Model View Controller&lt;/b&gt; (MVC) pattern. &lt;br /&gt;In MVC we have the Model which is just the data that is requested by the user. The View is the actual form that shows the data from the Model and it will send actions from the user to the Controller. The Controller is responsible for giving the View the right data and update the Model. When the Model is updated it will send a notification to the View and the View will update itself.&lt;br /&gt;&lt;br /&gt;Now&amp;nbsp; this is a basic and fast description of MVC and there are a lot more (and better) descriptions on the internet and in books ;)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://yuml.me/7e96c9f8" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="44" src="http://yuml.me/7e96c9f8" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The 'problem' I have with MVC is that the Model sends updates to the view and the view knows a lot of the Model. And I am not the only one, because there is an other pattern called &lt;b&gt;Model View Presenter&lt;/b&gt; (MVP) which is basically a decoupled version of MVC. The Role of the Model is the same, but the View only shows data which it gets from the presenter, and it doesn't update anything by itself. The Presenter has a bigger role, whenever an action is performed it should update the data on the view. It could be frustrating, but it makes the view (user interface) easier to understand/change.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Changing the user interface&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Using this patterns makes it really easy to change the user interface, we can easily make a new view and add it it to the Presenter. How these are coupled is basically a matter of taste. I tend to go for Dependency Injection&lt;/span&gt;&lt;/span&gt;, but it is also possible to give the Presenter a little more knowledge and let it create the view manually.&lt;br /&gt;Although I am not sure about it because I never tried it, I think the MVC pattern family make it easy to change from a desktop application to a web application. There will be some changes in the infrastructure, but in the presenters and the models there shouldn't be much differences.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Testing the presenters&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;span style="font-size: small;"&gt;Testing the user interface is difficult, and testing logic in the user interface even more difficult. Using the MVC pattern makes it pretty easy to test at least the most of the logic since the logic is inside the Presenter. We can create a simple version of the view to test whether information is send to it and we can use it to see if the events are working.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So the only not tested parts of the system are the actual views, these should be tested by humans because automated tests will be to complicated (although there are tools who can do this...)&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;When you have a problem and don't know how to solve it, it is great to be able to find a pattern that describes a possible solution. The problem is that you should have seen the pattern before you know that you can use it. That was basically the purpose of this post. I introduced you to the problem of a fat UI and I mentioned a pattern that could solve the problem. But there are a lot more patterns you probably wan to know about. Therefore I want to redirect you to a few sites:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://martinfowler.com/eaaDev/"&gt;http://martinfowler.com/eaaDev/&lt;/a&gt;&amp;nbsp; - Application Architecture patterns, very interesting to read&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourcemaking.com/design_patterns"&gt;http://sourcemaking.com/design_patterns&lt;/a&gt; - a site that describe some basic design patterns&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dofactory.com/Patterns/Patterns.aspx"&gt;http://www.dofactory.com/Patterns/Patterns.aspx&lt;/a&gt; - an other site describing basic design patterns&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-8457263910042224886?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/8457263910042224886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/12/power-of-patterns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/8457263910042224886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/8457263910042224886'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/12/power-of-patterns.html' title='The power of patterns'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-3585168857397927930</id><published>2009-11-20T15:59:00.000+01:00</published><updated>2009-11-20T15:59:23.531+01:00</updated><title type='text'>To inject or not to inject, that is the question</title><content type='html'>When trying to implement the specification and implementation for scheduling a check, I had the problem of what method to use for sending the event.&lt;br /&gt;There are basically two options:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Inject a Bus&lt;/li&gt;&lt;li&gt;Use a static/well known object for sending the event.&lt;/li&gt;&lt;/ol&gt;Lets take a look at both options...&lt;br /&gt;&lt;h2&gt;Inject a bus&lt;/h2&gt;&lt;img src="http://yuml.me/1d0310cf" width="400" /&gt;&lt;br /&gt;When Injecting a bus (or an other service) the Host will need a variable/field that holds the implementation of the service. Somehow the real implementation should be injected into the object. Normally we will do that by using a framework like &lt;a href="http://structuremap.sf.net/"&gt;structuremap&lt;/a&gt; or some other Dependency Injection framework.&lt;br /&gt;But we have the problem that Host is an &lt;b&gt;Entity&lt;/b&gt; which we will not instantiate ourself, but we ask our repository. So there will be another place where we need to inject the right service and I think this will lead us to duplicate code.&lt;br /&gt;&lt;h2&gt;Use static object&lt;/h2&gt;&lt;img src="http://yuml.me/6cb41e41"/&gt;&lt;br /&gt;Using a static object would be much simpler. We have one object that sends all events to the right place. How the event handlers are registered depends on the architecture of the application, but basically this will be done via an Dependency Injection framework. This method is &lt;a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/"&gt;explained&lt;/a&gt; more deeply by &lt;a href="http://www.udidahan.com/?blog=true"&gt;Udi Dahan&lt;/a&gt;.&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;Injecting services into entities is just to complicated and in my opinion should be avoided.&lt;br /&gt;Using static classes as services should also be avoided, because it will make testing more difficult.&lt;br /&gt;&lt;br /&gt;So what do we use? I will choose for the static class, because it only routes the actual events to the right handler, it will be easy to implement and it will be easy to use it in tests. Other services should be non static classes so that it follows the normal object oriented philosophy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-3585168857397927930?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/3585168857397927930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/11/to-inject-or-not-to-inject-that-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3585168857397927930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3585168857397927930'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/11/to-inject-or-not-to-inject-that-is.html' title='To inject or not to inject, that is the question'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6673193055732122843</id><published>2009-11-18T13:48:00.000+01:00</published><updated>2009-11-18T13:48:33.374+01:00</updated><title type='text'>The host in charge or How to design software the good way.</title><content type='html'>Software design is something that can be really challenging. This becomes more clear when you are working on a project now and than, or have some very complicated software.&lt;br /&gt;In the last topic I talked about the challenge of defining the scheduler and what it should schedule. I thought it was a good and easy point to start with, but it is not. I think by starting with the scheduler I want to make it much to generic and I don't want to be to generic, I just want it to do what it should do.&lt;br /&gt;To identify what it should do I have to start somewhere else.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Host.&lt;/h2&gt;Within NetworkMonitor hosts play an important role. A host is a network device with a networkcard and an network address.&lt;br /&gt;The state of the host can be checked and set from the outside. The host itself is responsible to notify others that a new check should be scheduled, but the user should be able to schedule a check manually as well.&lt;br /&gt;&lt;br /&gt;This above text will leas us to the following design:&lt;img src="http://yuml.me/diagram/scruffy/class/[Host%7CState%7CSetState%28%29;ScheduleCheck%28%29]-%3E[Check],%20[Host]uses -.-%3E[ScheduleCheckEvent]" /&gt;&lt;br /&gt;&lt;br /&gt;The SetState and ScheduleCheck methods will have parameters, but I don't know them yet.&lt;br /&gt;The idea is that when the SetState method is called, the ScheduleCheck is called automaticly.&lt;br /&gt;The ScheduleCheck will fire an event (ScheduleCheckEvent) to schedule the check. The event will contain all the necesary information for others to get the right host, the right check and the right time to perform the check.&lt;br /&gt;Since the host has a public ScheduleCheck methode, the user can also schedule the check whenever he likes.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Tests&lt;/h2&gt;Since this is a learning project I want to start using a Test first approach. This means we start with writing tests and then write the code to let the tests pass.&lt;br /&gt;I am going to use specification style testing which means I write specifications/stories about what I need to test. Here are my specifications for the Host:&lt;br /&gt;&lt;blockquote&gt;Given: an Host&lt;br /&gt;When : ScheduleCheck is called&lt;br /&gt;Then : a ScheduleCheckEvent is raised&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Given: an Host&lt;br /&gt;When : the status is set via SetStatus&lt;br /&gt;Then : then a ScheduleCheckEvent is raised&lt;br /&gt;&lt;/blockquote&gt;I tried writing specifications before, but I found it always difficult to do. These specifications are as simple as can be. The reason for this (I think) is that I want to test less than before, or made things to complex.&lt;br /&gt;&lt;br /&gt;ok, but that is not code.. I am going to use &lt;a href="http://github.com/machine/machine.specifications"&gt;MSpec&lt;/a&gt; which is a .NET project for Behaviour Driven style testing.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;public class When_scheduling_a_check&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static Host hots;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Establish context = () =&gt; { host = new Host("10.1.1.2"); };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Because of = () =&gt; { host.ScheduleCheck(DateTime.Now); };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;It should_have_raised_a_ScheduleCheckEvent;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class When_setting_the_status&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;static Host hots;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Establish context = () =&gt; { host = new Host("10.1.1.2"); };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Because of = () =&gt; { host.SetState(State.Ok); };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;It should_have_raise_a_ScheduleCheckEvent;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;All that I have done here are writing the When (Establish context) and Then (Because of). The actual test is still pending.&lt;br /&gt;The funny code (() =&gt; {};) is part of the .NET syntax and are called lambda expressions. This makes it possible to put functions/methods inside a property to be run at a later moment.&lt;br /&gt;&lt;br /&gt;Well thats all for today. I will have to implement this first before I continue :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6673193055732122843?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6673193055732122843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/11/host-in-charge-or-how-to-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6673193055732122843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6673193055732122843'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/11/host-in-charge-or-how-to-design.html' title='The host in charge or How to design software the good way.'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6050876690228581359</id><published>2009-11-05T20:01:00.000+01:00</published><updated>2009-11-05T20:01:39.646+01:00</updated><title type='text'>Scheduler, what to schedule?</title><content type='html'>I am thinking about the scheduler part of my NetworkMonitor. On of the things I want to do in the NetworkMonitor is to use a service layer. A service layer is a thin layer between the actual application (executable / user interface) and the domain. and it provide the supported scenarios. In case of Commands Query Seperation, it also provide the commands and their handlers.&lt;br /&gt;&lt;br /&gt;Back to the scheduler part... I want to have a SchedulingService which provide all the possible operations for the scheduler. Since I want to use the YAGNI (You Aint Gonna Need It) approach. I only have two methods for this service:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Schedule something&lt;/li&gt;&lt;li&gt;Do something with the Scheduled things&lt;/li&gt;&lt;/ul&gt;As you can see this is really vague... What do I need to schedule? Do I schedule Events? Do I schedule Commands? (here commands are a domain specific thing) Do I schedule System.Action?&lt;br /&gt;&lt;br /&gt;At this point I just don't know... I think it really depends on how generic this scheduler should be... Should I be able to schedule tasks that are not domain stuff as well? or do I choose to schedule only domain specific stuff.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;The solution&lt;/span&gt;&lt;br /&gt;Well, since I want to be YAGNI, I think I decide to schedule only domain specific &lt;b&gt;tasks&lt;/b&gt;. When a &lt;b&gt;task&lt;/b&gt; is scheduled and it is time to perform the &lt;b&gt;task&lt;/b&gt; I will fire an &lt;b&gt;event&lt;/b&gt; to let some other class know that it should be performed.&lt;br /&gt;&lt;span style="font-size: large;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;It is a good thing to think out loud... You get some solutions that way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6050876690228581359?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6050876690228581359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/11/scheduler-what-to-schedule.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6050876690228581359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6050876690228581359'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/11/scheduler-what-to-schedule.html' title='Scheduler, what to schedule?'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-3810409297580799535</id><published>2009-10-27T20:30:00.000+01:00</published><updated>2009-10-27T20:30:21.283+01:00</updated><title type='text'>Commands and Events</title><content type='html'>In my last post I ended with talking about sending messages between bounded contexts. In this post I want to describe how to do this, but I also want to talk about a new thing I want to try out. It is called Command and Query Responsibility Segregation (CQRS).&lt;br /&gt;&lt;br /&gt;Please leave a message to tell me if you understand it or not?&lt;br /&gt;&lt;br /&gt;With CQRS you are basically splitting the commands from the queries (Inserts, updates, deletes from the selects :)). This means that we can optimise how we show data on the user interface and how we handle changes.&lt;br /&gt;&lt;br /&gt;From the user interface we send "Commands" to the domain. These commands will modify the aggregate roots and save the changes. These changes are translated into "Events" which are saved. When we want to get our aggregate root, we simple have to playback all the events to get our state. This means we have a nice log of what has happened with the object.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;An example&lt;/h2&gt;"Ok, sounds nice, but how does it work?" you may say.. Lets look at a simplified example:&lt;br /&gt;The user wants to create a new radio program into the system. After clicking on the "New" button, the UI does something like:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;_commandBus.Send(new CreateRadioProgramCommand(Guid.NewGuid(), _programName));&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;In the domain we have a &lt;i&gt;CreateRadioProgramCommandHandler&lt;/i&gt; class which will create a new &lt;i&gt;RadioProgram&lt;/i&gt; object and save it to the Repository.&lt;br /&gt;While creating the RadioProgram a &lt;i&gt;CreateRadioProgramEvent&lt;/i&gt; will be created. This event will be saved in the database and will be published. By publishing the event the event can be used to update the query cache so that the user can find the RadioProgram in the user interface.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Updating the radio&lt;/h2&gt;Now that we have a Radio Program, the user can use the user interface to change details of the Radio Program. So when we have changed things, the UI does something like:&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;_commandBus.Send(new ChangeRadioProgramLanguage(_id, "Dutch"));&lt;/i&gt;&lt;/blockquote&gt;&lt;br /&gt;The &lt;i&gt;ChangeRadioProgramLanguageCommandHandler&lt;/i&gt; will ask the repository for the correct radio program. The repository will get all previous events and use those to construct the Radio Program.&lt;br /&gt;Then the Language will be changed and the Radio Program will be saved.&lt;br /&gt;This causes a new event, &lt;i&gt;LanguageChangedEvent&lt;/i&gt; and this event will be published so that the UI cache will be changed.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Communicating with Bounded Contexts?&lt;/h2&gt;At this point I am not really curtain how the communication between Bounded Contexts can be established. I think it could be both "Events" AND "Commands" or "Events" that are leading to "Commands"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-3810409297580799535?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/3810409297580799535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/commands-and-events.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3810409297580799535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/3810409297580799535'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/commands-and-events.html' title='Commands and Events'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-4307055225841292692</id><published>2009-10-21T09:09:00.000+02:00</published><updated>2009-10-21T09:09:03.381+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='NetworkMonitor'/><title type='text'>NetworkMonitor: my new view of the structure</title><content type='html'>During the last few weeks I have been reading a lot about software architecture and how other people do things. I found out that it is very easy to create a publish/subscribe system that makes it easy to send messages from one place of the system to somewhere else. I see it as an ideal method to communicate between Bounded Contexts.&lt;br /&gt;With this knowledge I was thinking about how I can structure NetworkMonitor in a loosely coupled way.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Scheduler&lt;/li&gt;&lt;li&gt;Command runner&lt;/li&gt;&lt;li&gt;Host/Service state&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Scheduler&lt;/h2&gt;The scheduler has the important task to keep a list of scheduled items, this can domain specific things like running commands to check the state of host/services, but also application things like do a log rotation.. The Scheduler can be very generic so that it supports a lot of different items.&lt;br /&gt;&lt;h2&gt;Command runner&lt;/h2&gt;The command runner will do the actual actions for getting the state of hosts/services. It will run the command and wait for the response, the response will be parsed and the state of the host or service will be set.&lt;br /&gt;&lt;h2&gt;Host/Service state&lt;/h2&gt;The state of hosts or services can be very simple, but when the state changes to an unexpected state, several things should be done. The Host/Service state has the responsibility to schedule new commands based on the current state, and will be used to show the user the state information.&lt;br /&gt;&lt;h2&gt;The missing link&lt;/h2&gt;The three subsystems are very different from each other, but they should still communicate with each other. The problem here is how do they communicate.&lt;br /&gt;Before we can answer that we should know where each part is in the system.&lt;br /&gt;I see three possibilities:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;They are all in the same application&lt;/li&gt;&lt;li&gt;They are in different applications on the same computer&lt;/li&gt;&lt;li&gt;They are on different places in the network/world&lt;/li&gt;&lt;/ul&gt;When we choose for only the first option, it will be easy. We can use simple event (like windows messaging or .net events), but this won't work when we need to support the other solutions.&lt;br /&gt;The other two solutions need some kind of messaging system over the network/memory. The same method we can use when we have all the systems in the same application.&lt;br /&gt;What I am thinking about is a &lt;a href="http://en.wikipedia.org/wiki/Publish/subscribe"&gt;Publish/Subscribe pattern&lt;/a&gt;.&lt;br /&gt;In short the pattern has one class where all publishers post messages to, and everyone that want to respond on a message, adds(subscribes) itself as listener to that same class. When a message is send, the class will go over every listener and post the message.&lt;br /&gt;How this is done over a network I am not sure yet, but I think it should be possible.&lt;br /&gt;&lt;br /&gt;That it for this moment.. I've got a lot of ideas and will try to implement them. But first I have to do some work...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-4307055225841292692?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/4307055225841292692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/networkmonitor-my-new-view-of-structure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4307055225841292692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4307055225841292692'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/networkmonitor-my-new-view-of-structure.html' title='NetworkMonitor: my new view of the structure'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-4847165263594634817</id><published>2009-10-14T20:17:00.000+02:00</published><updated>2009-10-14T20:17:31.783+02:00</updated><title type='text'>Resources I find usefull</title><content type='html'>in the past two or three years, since I am graduated, I am on a constant search for better and new ways of doing things. Most of the information I find in blogs, articles and sometimes in books. (I am not really networking yet, shame on me...)&lt;br /&gt;&lt;br /&gt;Here is a list of resources I found useful in no particular order:&lt;br /&gt;&lt;br /&gt;EBook:&lt;br /&gt;&lt;a href="http://openmymind.net/FoundationsOfProgramming.pdf"&gt;Foundations of programming&lt;/a&gt;: I think this is a collection of blog posts that describe a lot of basic principles.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Books:&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0321125215"&gt;Domain Driven Design by Eric Evans&lt;/a&gt;: this is a complex abstract book, but once you read it a few times, it is a valuable source.&lt;br /&gt;&lt;a href="http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1255543290&amp;amp;sr=1-2"&gt;Applying UML and Patterns by Craig Larman&lt;/a&gt;: a good book to get into "modern" object oriented software development. Sometimes I think there is to much information in the book.&lt;br /&gt;&lt;a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1255543490&amp;amp;sr=1-1"&gt;Patterns of Enterprise Application Architecture by Martin Fowler&lt;/a&gt;: The latest addition in my collection, it describes a lot of patterns that could be used in applications. I like to have a book where I can find the information I need.&lt;br /&gt;&lt;a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1255543632&amp;amp;sr=1-1"&gt;The Pragmatic Programmer&lt;/a&gt;: This book gives a nice view on what programmers are and how to use the tools they have.&lt;br /&gt;&lt;br /&gt;Websites/Blogs:&lt;br /&gt;&lt;a href="http://www.infoq.com/"&gt;http://www.infoq.com/&lt;/a&gt;: News, Articles, Presentations and ebooks about software development. for the ebooks registration is required...&lt;br /&gt;&lt;a href="http://dddstepbystep.com/"&gt;http://dddstepbystep.com/&lt;/a&gt;: information about Domain Driven Design.&lt;br /&gt;&lt;a href="http://codebetter.com/"&gt;http://codebetter.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://devlicious.com/"&gt;http://devlicious.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.lostechies.com/"&gt;http://www.lostechies.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.udidahan.com/?blog=true"&gt;http://www.udidahan.com/?blog=true&lt;/a&gt;&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/"&gt;http://martinfowler.com/bliki/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-4847165263594634817?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/4847165263594634817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/resources-i-find-usefull.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4847165263594634817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/4847165263594634817'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/resources-i-find-usefull.html' title='Resources I find usefull'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6740060104959709273</id><published>2009-10-14T19:36:00.000+02:00</published><updated>2009-10-14T19:36:24.159+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><title type='text'>Bounded Context</title><content type='html'>Sometimes aspects of a domain can have slightly different meanings within different parts of that domain.&lt;br /&gt;When we talk about a radio program this can have different meanings for different people and applications. For one program it means something that a producer makes and that has content like talk and music, in an other part of the organisation it could just mean a file that should be transferred to the right place, yet another part of the organisation sees it as something that should be aired.&lt;br /&gt;Still they are all related.&lt;br /&gt;Of course we could put them all in the same domain, but then people don't understand the software completely. By putting them all in a separate domain, a bounded context, it will become more clear how relations go. This way the people who air the radio program don't have to know that that same radio program has a relationship with a producer.&lt;br /&gt;&lt;br /&gt;Another reason to introduce bounded contexts is when the domain is getting to big and to complex. It will pay of to put split the domain in multiple bounded contexts. &lt;br /&gt;&lt;br /&gt;But there should be a way to connect these bounded contexts. This can be done in several ways. One way is to write a layer between both domains that convert from one domain to an other.&lt;br /&gt;An other way is to use messages and ask for information. This method I will explain in more detail in the next post when I talk about a new idea for the network monitor system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6740060104959709273?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6740060104959709273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/bounded-context.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6740060104959709273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6740060104959709273'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/bounded-context.html' title='Bounded Context'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-2327013001361069832</id><published>2009-10-13T22:18:00.000+02:00</published><updated>2009-10-13T22:18:59.165+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><title type='text'>Domain Driven Design and Time based tasks</title><content type='html'>In one of the projects I worked on, there were a lot of actions that happened at specific times. At midnight the logs would be rotated, an hour past midnight things where rescheduled and checked. at a specific point in the schedule, that item was processed.&lt;br /&gt;&lt;br /&gt;With Domain Driven Design it is not obvious how to implement this. Normally we don't have timers in the domain. First of all it is not easy to test timers and their events and secondly, it is not the responsibility of the domain to get the current time and initiate actions.&lt;br /&gt;So how can we do it then? What I am about to write is something I didn't try, but it basically 'popped up' in my head.&lt;br /&gt;&lt;br /&gt;A timer is in terms of DDD just an external service. Every time it needs to fire an event, or the time is changing, it will send a message to the domain. So basically it is like a heartbeat. (During my graduation we had a program which controlled a robot, and that program also had a heartbeat to let the robot make decisions...)&lt;br /&gt;&lt;br /&gt;In the domain we can have classes like Schedule,which has a method that can receive the current date and time. When this method is called, the schedule will look to the scheduled actions that should be run at that time and will fire events to initiate the actions.&lt;br /&gt;These events can go from one domain to another (bounded contexts, did I already speak about that? if not I will try to do that soon), or from one application to another. We can also store the events that come in and go out, so that we have a history of what happend.&lt;br /&gt;&lt;br /&gt;How do the events look like? I think of them like normal objects that contains information about the actions.&lt;br /&gt;&lt;br /&gt;I understand that the above is a bid abstract, but it came to my while I was reading different articles about &lt;a href="http://martinfowler.com/eaaDev/EventSourcing.html"&gt;Event Sourcing&lt;/a&gt;, Command Query Seperation and other things over the last view days, and now I had the feeling that I should put this in some sort of writing to remember it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-2327013001361069832?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/2327013001361069832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/domain-driven-design-and-time-based.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2327013001361069832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2327013001361069832'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/domain-driven-design-and-time-based.html' title='Domain Driven Design and Time based tasks'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-8594349589412527654</id><published>2009-10-12T22:33:00.000+02:00</published><updated>2009-10-12T22:33:36.662+02:00</updated><title type='text'>Domain / UI speration</title><content type='html'>On the current project the decision was made to use domain objects directly in the user interface. It seemed to be a good idea at first, it made a lot of code unnecessary, but there where some things that were not solved nicely.&lt;br /&gt;&lt;h2&gt;DataBinding&lt;/h2&gt;An option that we have in .NET is databinding. this means that we can bind properties to controls and let the control update it self when a specific property is changed. There are also collections that can be bound to objects and that can react to changes from their items.&lt;br /&gt;&lt;br /&gt;In our domain we basically have items which have a description and a price. Each item can have subitems (but this isn't necessary) and when there are subitems, the price of the item is the total of the subitems.&lt;br /&gt;The way the domain was set up was that the total price was calculated as soon as the list was changed. We responded to the ListChanged event, calculated the total and set the Price property.&lt;br /&gt;&lt;br /&gt;This worked fine, the User interface was getting changed and everybody was happy, but we didn't have any persistence at that moment.&lt;br /&gt;&lt;h2&gt;Persistence&lt;/h2&gt;When I was implementing/configuring the persistence for our domain, I came across a few problems. First of all the BindingList&lt;&gt; object we used for the subitems was not supported by the framework we use (NHibernate), so we had a choice to make: Implement a custom collection or add extra properties for the BindingList (one exposing the BindingList&lt;&gt;, an other exposing a normal IList&lt;&gt; which could be handled by NHibernate). We went for the custom collection. this went fine for a lot of things, except for the price totals.&lt;br /&gt;When an Item is loaded from the database, a few things happen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;an Item object is created&lt;/li&gt;&lt;li&gt;a list with for subitems is created&lt;/li&gt;&lt;li&gt;eventhandlers are coupled to the list&lt;/li&gt;&lt;li&gt;NHibernate sets every property that is mapped, including the list&lt;/li&gt;&lt;/ul&gt;The last step was deadly for our domain logic. at the moment the list of subitems is set, the event handlers still refer to the old list. This means that when a subitem changes or subitems are added/removed the event handler will &lt;b&gt;NOT&lt;/b&gt; pick this up and the total price will not be changed.&lt;br /&gt;&lt;h2&gt;Solution&lt;/h2&gt;The solution is pretty straight forward, but is a change of thinking. Instead of setting the total price, &lt;i&gt;ask&lt;/i&gt; for the total price. So we do "SubItems.Sum(x =&gt; x.Price)" in the getter of Item.Price. This way we eliminate the need of a BindingList and event handlers and we can save and load everything.&lt;br /&gt;This gives us another problem. A grid with SubItems will not automatically refresh. This can be solved by add a special Item to the view, ItemView or ItemPresenter or ItemPresentation or whatever, this class should have the logic to drive the User Interface and tell the user interface to change when something important happend. Because this class needs domain logic I did make a subclass for this and I map all the values from one class  to the other. (in other cases I just change/use the base class directly, so instead of using a subclass it is a gateway)&lt;br /&gt;&lt;br /&gt;This seems to be a lot of extra work, and it is, but I think it is worth the trouble and there are a lot of libraries that can ease the pain. (such as automapper which can map two objects to each other by copying all the values of the properties from one object to the other)&lt;br /&gt;Adding these View classes will make the actual UI code easier to read (and write)&lt;br /&gt;&lt;br /&gt;I will try to investigate more about UI patterns, and hope to write down more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-8594349589412527654?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/8594349589412527654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/10/domain-ui-speration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/8594349589412527654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/8594349589412527654'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/10/domain-ui-speration.html' title='Domain / UI speration'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-1897303830001996212</id><published>2009-09-15T14:18:00.003+02:00</published><updated>2009-09-15T14:38:20.284+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rant'/><title type='text'>Avoid flexibility!</title><content type='html'>On the project I am working on, the software should be able to do anything. It should be possible to make all kind of transactions, it should be possible to ad an unlimited amount of Mortgages (and to pay back an unlimited amount of Mortgages). The whole application should be unlimited.&lt;br /&gt;When I came into the project, there was already a basis for this. The user is able to combine all kind of inputs (Transaction, ToPay, ToReceive, and some other things) all these inputs can have an unlimited number of items.&lt;br /&gt;There is a difference between "design time" and "runtime". Design time is where the administrator can create models, by combining those input-designs and creating default items for them.&lt;br /&gt;The runtime is when the design is used to make an invoice. The input-design becomes an input and the default item an item. I really liked this idea, but after some time things where getting difficult. One of the things is that inputs have dependencies, and different inputs have different behaviour for these dependencies.&lt;br /&gt;&lt;br /&gt;In Holland we have some kind of tax which needs some money from a transaction and money from a Leasehold. But how do you know which transaction belongs to which leasehold? Ok we only take one leasehold and combine all the transactions, that is enough for this tax. But how do other inputs work with dependencies? and how can we make it as flexible as possible?&lt;br /&gt;&lt;br /&gt;This is why I want to say, stop with this stupid flexibility! it only cost valuable time to implement things and make it possible for the user to do everything!&lt;br /&gt;&lt;br /&gt;Flexibility is good and in software development it is very useful to have (without flexible code it gets difficult to add features to the code). But please stop asking for "everthing should be possible"-applications...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-1897303830001996212?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/1897303830001996212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/09/avoid-flexibility.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1897303830001996212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1897303830001996212'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/09/avoid-flexibility.html' title='Avoid flexibility!'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-2128677530388006138</id><published>2009-09-02T16:28:00.002+02:00</published><updated>2009-09-02T16:45:05.830+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><category scheme='http://www.blogger.com/atom/ns#' term='language'/><title type='text'>It's all about the language</title><content type='html'>In software development it is very important to name your classes, methods, properties, etc in the right way, so you can find them quickly. It is also important to name them the way you talk about them, this became very clear to me during my current project.&lt;br /&gt;&lt;br /&gt;The project I am currently working on is a project for solicitors. The project is only focussing an a relative small part, namely invoice creation.&lt;br /&gt;Solicitors are working with cases (at least here in the Netherlands they are). For such a &lt;span style="font-weight:bold;"&gt;case&lt;/span&gt; they create an invoice. In this new software they want to choose from several types of things, when they are involved in selling/buying a house, they want to choose that specific invoice &lt;span style="font-weight:bold;"&gt;model&lt;/span&gt; and when they are involved in setting up a will, they want to choose that invoice &lt;span style="font-weight:bold;"&gt;model&lt;/span&gt;.&lt;br /&gt;Each model has some &lt;span style="font-weight:bold;"&gt;element&lt;/span&gt;s. In case of selling/buying a house there is a transaction, some tax and other important stuff. &lt;br /&gt;&lt;br /&gt;This is really simple, but when I stepped into the project, there where not such types. Instead there where some types called Case, CaseComponent and CaseComponentAspect. Every day there was a discussion between the developers and the domain expert about what the meaning of these types where. At some point the developers made a "conversion list" telling what the domain expert said and how they called it.&lt;br /&gt;According to the domain expert these things where called: Case, InvoiceModel and InvoiceElement. This is exactly how I expected it to be and soon I pushed the other developers to change it. After the refactoring there weren't any discussions about the naming and everything is clear to everyone.&lt;br /&gt;&lt;br /&gt;Therefore, please choose your type names carefully, so that every member of the team knows where you are talking about...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-2128677530388006138?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/2128677530388006138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/09/its-all-about-language.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2128677530388006138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2128677530388006138'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/09/its-all-about-language.html' title='It&apos;s all about the language'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6628110651600237291</id><published>2009-04-08T21:21:00.002+02:00</published><updated>2009-04-08T21:23:01.794+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><title type='text'>Configuring a monitoring system</title><content type='html'>At work I am working on software where the administrator have the possibility to build models using building blocks. These models can be used to build invoices. The way this is done can be used in other projects as well.&lt;br&gt;In my network monitoring system it should be possible to easily configure the network layout.&lt;br&gt;&lt;h2&gt;Definitions&lt;a id="fey9" href="http://docs.google.com/File?id=ddj3k3kn_67hqjwb4fx_b" target="_blank"&gt;&lt;/a&gt;&lt;/h2&gt;The first thing I am thinking about is to make definitions of the building blocks for our system. So we get a definition for host, service, command and probably some others as well.&lt;br&gt;So we will have something like the following layout: &lt;div style="text-align: center;"&gt;&lt;div id="kbid" style="text-align: right;"&gt;&lt;a href="http://docs.google.com/File?id=ddj3k3kn_69f8w9h46d_b" target="_blank"&gt;&lt;/a&gt;&lt;div id="omc9" style="text-align: left;"&gt;&lt;a href="http://docs.google.com/File?id=ddj3k3kn_70gnwhpbc8_b" target="_blank"&gt;&lt;img style="width: 160px; height: 168.867px;" src="http://docs.google.com/File?id=ddj3k3kn_70gnwhpbc8_b"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;It is no really useful to have the definitions when it is not possible to tell the user which definitions are available. This can be solved by creating classes for the definition types. All these classes do is holding a static instance of themselves, hold the name of the type and create a new definition of that type. Since the definition type can not be changed by anyone and we need it to create the real definitions, it is not necessary to construct them our self, that's why we use the singleton pattern here. Another advantage is that we can use this instance to show it to the user as well. &lt;br&gt;&lt;div id="uo.h" style="text-align: left;"&gt;&lt;a href="http://docs.google.com/File?id=ddj3k3kn_68dzc4gmrv_b" target="_blank"&gt;&lt;img style="width: 160px; height: 162.971px;" src="http://docs.google.com/File?id=ddj3k3kn_68dzc4gmrv_b"&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2&gt;Using the definitions&lt;/h2&gt;We can now make a user interface to make it easy to create the definitions and configure them. Therefore we need some extra patterns. Let's say our user interface will look like this:&lt;br&gt;&lt;div id="egz_" style="text-align: left;"&gt;&lt;a id="qfmv" href="http://docs.google.com/File?id=ddj3k3kn_66cc8mjgfc_b" target="_blank"&gt;&lt;img style="width: 320px; height: 224.487px; float: left; margin-left: 0pt; margin-right: 1em;" src="http://docs.google.com/File?id=ddj3k3kn_66cc8mjgfc_b"&gt;&lt;/a&gt;&lt;/div&gt; The buttons at the top are used to select the type of definition. When ever a type is selected a new definition will be created. We use a &lt;i&gt;Factory method&lt;/i&gt; for this. (factory method: a method that has the logic to create an object) The created definition will be added to the listview with definitions.&lt;br&gt;The window on the right is a property grid, which can be used to change the properties of an object, so whenever one clicks on an item in the listview, the property grid will show the properties which can be changed.&lt;br&gt;At this point we don't add the definitions to the repository, because&lt;br /&gt;we want to be able to cancel the changes we made. When we push the Save&lt;br /&gt;button, we register all changes to the &lt;i&gt;Repository&lt;/i&gt; and the data will be persisted.&lt;br&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;Using this method it is pretty easy to configure a whole network. (Why didn't I think of it sooner...) Using this configuration is also pretty simple. But I will leave that for another post :)&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6628110651600237291?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6628110651600237291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/04/configuring-monitoring-system.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6628110651600237291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6628110651600237291'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/04/configuring-monitoring-system.html' title='Configuring a monitoring system'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6893462001130971310</id><published>2009-03-25T23:44:00.002+01:00</published><updated>2009-03-25T23:50:19.923+01:00</updated><title type='text'>Bussy with personel life</title><content type='html'>It has been a while since I have been writing something on this blog. This is mostly due to things that are currently happening in my life. Last month I got the key of my new apartment and there is much to do, besides that I have to prepare for a wedding (my own wedding ;)) and I also have to work.&lt;br /&gt;The good thing is that I am learning very much at work about Domain Driven Design and different programming techniques. At the moment I try to put something in practise that I have learned at work and I am writing a post about it. I hope the post will be ready next week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6893462001130971310?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6893462001130971310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/03/bussy-with-personel-life.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6893462001130971310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6893462001130971310'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/03/bussy-with-personel-life.html' title='Bussy with personel life'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-5065783606904004820</id><published>2009-02-16T12:42:00.002+01:00</published><updated>2009-02-16T12:43:21.625+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><title type='text'>Factories and Repositories</title><content type='html'>In my last post I talked about entities, the domain objects that have an identity and a life. In this post I want to talk about the management of the lifetime of entities. We start at the beginning.&lt;br&gt;&lt;h2&gt;Creation of objects&lt;/h2&gt;Creation of objects could be very simple:&lt;br&gt;&lt;blockquote&gt;new RadioProgram(); // C#&lt;br&gt;or&lt;br&gt;RadioProgram.Create; //Delphi&lt;br&gt;&lt;/blockquote&gt;But what when it is not that simple and there are a lot of extra dependencies and relations that should&amp;nbsp; be connected? We can use the Factory pattern for this purpose. When we use a &lt;b&gt;Factory&lt;/b&gt; we use an object to create another object.&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;class RadioProgram&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public RadioProgram()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public RadioStation { get; set; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;class RadioProgramFactory&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private RadioStation defaultStation = new RadioStation("DutchRadio");&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public RadioProgram CreateProgram()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RadioProgram program = new RadioProgram();&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; program.RadioStation = this.defaultStation;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return program;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;In the code above I create a RadioProgram which is only valid when there is a radio station assigned to it. (actually, normally this is not needed and added later, but I lack the fantasy to think of an original example). So to get a valid RadioProgram we will have to create a RadioProgramFactory and call the CreateProgram method.&lt;br&gt;&lt;h2&gt;Repositories&lt;/h2&gt;Now that we have a nice domain object, we need a place to store it. There are several places where we can store objects. We can store them in databases, in XML files, in binary streams and in a dozen of other places. But why should I (read the domain) should care about storage or persistency? We shouldn't care about it. In Domain Driven Design we create the domain with Persistence Ignorance in mind. The objects in the domain don't have to know when, where, why or even if they get persisted. The only thing we can/should do in the domain is to register the domain objects to &lt;b&gt;Repositories&lt;/b&gt;.&lt;br&gt;A repository can be a big thing. We can use it to store objects, we can use it to find objects (in several ways) and we can use repositories to delete objects. But in the domain we won't actually do these things. Hmm. that is confusing.&lt;br&gt;OK, on one site I say that the domain should be able to talk to the repository. On the other side I say, the domain should not know anything about Persistence. To solve this problem we can say the following: The domain should create the definition (an interface) for the repository, it will tell &lt;b&gt;what&lt;/b&gt; the domain expects from a repository.&lt;br&gt;Outside the domain we can have multiple implementations of a repository interface. With one implementation we talk to a legacy database, with another implementation we talk with a newly created database. During run-time we can say to the application which implementation it should use. This technique can be used for other things as well and is called &lt;b&gt;Dependency Injection&lt;/b&gt; (although it has also some other names).&lt;br&gt;So how does a repository looks like? Here is an example of the interface that is in the domain:&lt;br&gt;&lt;blockquote&gt;public interface RadioProgramRepositoryInterface&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Add(RadioProgram program);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Update(RadioProgram program);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Delete(RadioProgram program);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RadioProgram GetProgram(string programName); // programName is the identifier in this case.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;RadioProgram&amp;gt; All(); // Get a list of all available RadioPrograms.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;RadioProgram&amp;gt; GetProgramQueueForStation(RadioStation aStation); // Get the program queue for a specific station.&lt;br&gt;}&lt;br&gt;&lt;/blockquote&gt;So basically you can do anything in a repository that you can also do with a database, but the different is that you don't know what kind of database it is, it could also be an In-Memory stack or some files somewhere on the Internet. The last method is used to get a specific list of radio programs (programs that are queued for a specific station) This is a pretty easy selection, but it could be possible to get very complicated selections. In that case we can use &lt;b&gt;Specifications&lt;/b&gt; or some kind of &lt;b&gt;Query language&lt;/b&gt;. I will not go further into those topics, because they are to complicated to handle in short and I don't have any experience with them.&lt;br&gt;&lt;h2&gt;Dependency Injection&lt;/h2&gt;Before we can really use the persistent specific repositories we need to be able to find out which repository we need to use. This part of domain driven design can be difficult and it is easier said than done.&lt;br&gt;In my current project we maintain a list of interfaces and implementations that can be injected. (ie. RadioProgramRepositoryInterface - MemoryRadioProgramRepository, where the later is the implementation). The list is created at start-up time by a bootstrapper and this list is stored in a domain object called "World". This World object is a static object so every other object can reach it when necessary.&lt;br&gt;Of course this is not the best solution there is, but it works in our project. For more information about dependency injection you can read the following article: &lt;a title="http://martinfowler.com/articles/injection.html" href="http://martinfowler.com/articles/injection.html" id="k9a5"&gt;http://martinfowler.com/articles/injection.html&lt;/a&gt;&lt;br&gt;Closing words&lt;br&gt;Recently someone else also started a series about the basics of DDD, although is not very organized in the topic order, he is better organized in the topics itself. You can find his articles &lt;a title="here" href="http://devlicio.us/blogs/casey/default.aspx" id="b:j4"&gt;here&lt;/a&gt; (&lt;a title="starting here" href="http://devlicio.us/blogs/casey/archive/2009/02/09/domain-driven-design-a-step-by-step-guide.aspx" id="p6hu"&gt;starting here&lt;/a&gt;)&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-5065783606904004820?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/5065783606904004820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/02/factories-and-repositories.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/5065783606904004820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/5065783606904004820'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/02/factories-and-repositories.html' title='Factories and Repositories'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-2023513590954222005</id><published>2009-02-13T12:05:00.002+01:00</published><updated>2009-02-13T12:06:13.639+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><title type='text'>Domain entities and value objects</title><content type='html'>Three weeks after my last post, it is time to go on with the DDD series.&lt;br&gt;In this short post I will talk about &lt;b&gt;entities&lt;/b&gt; and &lt;b&gt;value objects&lt;/b&gt;. These concepts are not new, but are the very important in DDD.&lt;br&gt;&lt;h2&gt;Value Objects&lt;/h2&gt;Value Objects are very simple objects which are in the domain for convenience. Nobody cares about the lifetime of these objects because they are very simple to build up again. Some examples of value objects are:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Color&lt;/li&gt;&lt;li&gt;Date/time&lt;/li&gt;&lt;li&gt;Money&lt;/li&gt;&lt;/ul&gt;The reason why they don't have a lifetime is because we don't care what instance we have. new Euro(10); and new Euro(10); have the same value, we don't care that they don't have the same reference, as long as we can say "We have both 10 euro" it is fine.&lt;br&gt;&lt;h2&gt;Entities&lt;/h2&gt;Entities are different. Entities have an identity. new Person("Jan"); and new Person("Jan"); are not the same. They have the same name, yes, but they don't have the same age, or the same length, perhaps they don't even have the same nationality.&lt;br&gt;This means an Entity is unique and a lifetime should be maintained (even when the application is closed). This means that we should be able to store the entity somewhere and request it again when we need it. And when we request the same entity twice, we need to get the same object.&lt;br&gt;In my monitoring system &lt;b&gt;Devices&lt;/b&gt; and &lt;b&gt;Services&lt;/b&gt; are entities. One device can only exist at one place and one Service can only be on one device (even though services can look the same, how we can solve this I will explain in another post :))&lt;br&gt;&lt;br&gt;&lt;h2&gt;Lifetime management&lt;/h2&gt;Because entities have a lifetime we need some lifetime management. Although I will explain the following concepts in detail in another topic, I will mention them now to avoid some questions.&lt;br&gt;The lifetime of an entity is as follow:&lt;br&gt;&lt;ul&gt;&lt;li&gt;An entity is created, this can be done by using the constructor, or, when it is more difficult and more than one entity has to be created, a &lt;b&gt;Factory&lt;/b&gt; can be used.&lt;/li&gt;&lt;li&gt;An entity is registered to a &lt;b&gt;Repository&lt;/b&gt;&lt;/li&gt;&lt;li&gt;To get a registered entity, we ask the &lt;b&gt;Repository&lt;/b&gt;. We can also ask for a list of entities or search through entities.&lt;/li&gt;&lt;li&gt;When we want to delete an entity we tell the &lt;b&gt;Repository&lt;/b&gt; to delete the entity.&lt;/li&gt;&lt;/ul&gt;In the next post we will talk more about the &lt;b&gt;Factory&lt;/b&gt; and the &lt;b&gt;Repository&lt;/b&gt;.&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-2023513590954222005?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/2023513590954222005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/02/domain-entities-and-value-objects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2023513590954222005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/2023513590954222005'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/02/domain-entities-and-value-objects.html' title='Domain entities and value objects'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-7594277971277571977</id><published>2009-01-21T10:51:00.004+01:00</published><updated>2009-01-21T10:56:07.942+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDD'/><title type='text'>Domain Driven Design - The basics</title><content type='html'>There are a lot of different design techniques in the software development world. At the moment my favorite one is Domain Driven Design (DDD). At my work I was introduced with it two years ago. During those two years I tried to use it to improve my software development and I think I succeeded, although I can improve a lot.&lt;br&gt;&lt;br /&gt;Ok, let me first explain what it is all about.&lt;br&gt;&lt;br /&gt;Eric Evans describes Domain Driven Design in his book &lt;cite&gt;&lt;a href="http://domaindrivendesign.org/books/" id="c4c4" title="Domain-Driven Design: Tackling Complexity in the Heart of Software"&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/a&gt; &lt;/cite&gt;. He says that the most complex part of software is the business or the domain logic. Software is written to support a business process and the logic that is needed to support this process is called the domain logic. Once this logic is implemented correctly, it is not likely to change very often.&lt;br&gt;&lt;br /&gt;The user interface is more likely to change, especially a web interface like the web site for online banking, therefore it is recommended to separate the domain logic from the user interface and other infrastructure logic (like database or file persistence, logging, etc.).&lt;br&gt;&lt;br /&gt;In DDD the domain logic is designed using a language that is known by the domain experts, and in the implementation (the domain) we will see objects, fields and methods that are using the same language. (Evans calls this the Ubiquitous language) This means the developers and all other people who are working with the domain should know this language.&lt;br&gt;&lt;br /&gt;Ok this can be very abstract, I know, so I will give you an example. For this example I use something everyone is familiar with, a Bank. A bank has &lt;b&gt;clients&lt;/b&gt;. These &lt;b&gt;clients&lt;/b&gt; have &lt;b&gt;accounts &lt;/b&gt;and can do &lt;b&gt;transactions&lt;/b&gt; between &lt;b&gt;accounts&lt;/b&gt;. The words in bold are important for the bank, without these words/things a bank doesn't exist. Therefore we will add them to out Ubiquitous language. In the domain design we can see the following diagram: &lt;div style="padding: 1em 0pt; text-align: center;"&gt;&lt;a target="_blank" href="http://docs.google.com/File?id=ddj3k3kn_48cn8tbgch_b"&gt;&lt;img id="daae" style="width: 320px; height: 171.915px;" src="http://docs.google.com/File?id=ddj3k3kn_48cn8tbgch_b"&gt;&lt;/a&gt;&lt;/div&gt;&lt;br&gt;&lt;br /&gt;&lt;font size="1"&gt;(you can see that I didn't talk about all the details of the classes you see here, but I think they are obvious...)&lt;/font&gt;&lt;br&gt;&lt;br /&gt;Now we have the design, we can implement it in any language we want, but it is important that the ubiquitous language is used in the domain itself.&lt;br&gt;&lt;br /&gt;Domain Driven Design is not only about the language. Separating the domain from technical things like user interface is even more important. The complexity of the software is the domain not how we show the domain, or how we implement the persistent. So we should be able to decouple the domain completely from all other things and to test it with some kind of automatic testing framework. (This is needed to get the proof that the implementation of the domain works correctly, but that will be another topic.)&lt;br&gt;&lt;br /&gt;The question is: How do we decouple the domain from the rest of the application? There are a couple of different possibilities here:&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Layered Architecture&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Sunflower Architecture&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Layered Architecture&lt;/h3&gt;&lt;br /&gt;&lt;a target="_blank" href="http://docs.google.com/File?id=ddj3k3kn_46f9f62kfv_b"&gt;&lt;img style="margin: 1em 1em 0pt 0pt; width: 160px; height: 64.8832px; float: left;" src="http://docs.google.com/File?id=ddj3k3kn_46f9f62kfv_b"&gt;&lt;/a&gt;In a Layered Architecture there are layers. A layer can communicate with all the layers bellow itself by using method calls. To communicate with layers on top of itself, a layer should use some kind of event based system. (See image)&amp;nbsp;&lt;br /&gt;In the diagram you can see that the domain is on top of the infrastructure/platform layer, which means it depends on this layer and we can't easily change from platform. An example: When we use the Win32-API for events (messages) we can't use the domain on other systems than Windows. So we can't easily deploy the domain on a Linux machine and the Testing Framework should understand the same platform/infrastructure. Other technical stuff like the user interface are build on top of the domain layer.&lt;br /&gt;&lt;h3&gt;Sunflower Architecture&lt;/h3&gt;&lt;br /&gt;&lt;a target="_blank" href="http://docs.google.com/File?id=ddj3k3kn_47hhtg2cdr_b"&gt;&lt;img id="ng:i" style="margin: 1em 0pt 0pt 1em; width: 160px; height: 160px; float: right;" src="http://docs.google.com/File?id=ddj3k3kn_47hhtg2cdr_b"&gt;&lt;/a&gt;The sunflower architecture I like the most. It looks like the following image.&lt;br&gt;&lt;br /&gt;The domain is completely decoupled from everything and around the domain we see the other technical stuff like logging, persistence, etc. With this model it is even possible to use a product from an other vendor and couple it via adapters to the domain. (An adapter is just a class that translates message to and from the domain.) This way the domain doesn't have to know anything about the infrastructure layer and can be tested without any problems.&lt;br&gt;&lt;br /&gt;&lt;h3&gt;Software Architecture&lt;/h3&gt;&lt;br /&gt;"Ok, we have those nice architectures, but how to implement that in my projects?" you may think. I would say make a library for every single layer or service. So a library for the domain, a library for the GUI and for the persistence. This way the code is physically decoupled as well, which makes it even easier to test and to replace implementations. Even updating an existing service is easy because the file is not cluttered with other things that has nothing to do with the problem.&lt;br&gt;&lt;br /&gt;This is also in line with the OO-rule "Single responsibility". Which tells that every single object (or module, or service or library) should have one task to do and it should do that well.&lt;br /&gt;&lt;h3&gt;Ending words&lt;/h3&gt;&lt;br /&gt;Besides a ubiquitous language, Evans also describes a lot of design patterns that can be used in domain driven design. I will give you a list with patterns, but I will describe them in some other posts, because I still want to describe where the domain could be placed in the application. First the patterns list:&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Value objects&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Entities&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Services&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Aggregates&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Factories&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Repositories&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Some of these I will combine in one post, but others I need to take separately.&lt;br&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;I realize that I give a very short introduction of Domain Driven Design. For more information you can go to some of the following websites:&lt;br&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;a title="domaindrivendesign.org" href="http://www.domaindrivendesign.org" id="nc26"&gt;domaindrivendesign.org&lt;/a&gt;  The main website of Domain Driven Design.&lt;br&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a title="infoq.com" href="http://www.infoq.com" id="zz3j"&gt;infoq.com&lt;/a&gt; - contains a free book called &lt;a title="Domain Driven Design Quicly" href="http://www.infoq.com/minibooks/domain-driven-design-quickly" id="h4:k"&gt;Domain Driven Design Quicly&lt;/a&gt;, which is basically a summary of the book, as well as a lot of other information about programming techniques and technology.&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a title="codebetter.com" href="http://www.codebetter.com" id="ccpd"&gt;codebetter.com&lt;/a&gt; - collection of blogs that discuss different techniques.&lt;br&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-7594277971277571977?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/7594277971277571977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/01/domain-driven-design-basics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/7594277971277571977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/7594277971277571977'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/01/domain-driven-design-basics.html' title='Domain Driven Design - The basics'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-1438070758526092014</id><published>2009-01-07T10:42:00.002+01:00</published><updated>2009-01-07T10:43:26.582+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><title type='text'>The monitor system</title><content type='html'>In a previous post I described the basic of the project I worked on and how I would implement it now. When starting a project it is good to write down what to expect from the software that is getting developed, this is something that was not really done for the previous version (at least not that I know of). Because I start the project all over again, I will start this new project by writing down that description.&lt;br&gt;&lt;br /&gt;&lt;h2&gt;&lt;br /&gt; The context&lt;br /&gt;&lt;/h2&gt;&lt;br /&gt;The broadcaster I worked for is using a complex computer network for distributing and broadcasting radio programs. The complete network is spread across the world and monitoring the whole network can hardly be done by hand and will be automated. &lt;i&gt;&lt;font size="1"&gt;(Well we did monitor the whole system by hand for some months because we just implemented the system before the software was ready, but that was not funny...)&lt;/font&gt;&lt;/i&gt;&lt;br&gt;On the network there are different kind of devices we have to monitor including: computers, modems (for connecting to the Internet) and UPS-es. All the devices on the network should be monitored (when possible) and it would be nice to keep a history of the state of the devices.&lt;br&gt;The computers are used for several things: first of all programs are played, but before that schedules should be checked as well as the integrity of the files and a lot of other things. All the programs keep a kind of log (of course) but it is useful to hold some of the information on a central place. There are also some OS things that should be monitored like disk-space and memory usage.&lt;br&gt;When there is something going wrong (all devices on a site are turned off, the play-out at a site is terminated, etc.) alarms should go off and a hot-line should be called, things should be corrected as soon as possible. &lt;i&gt;(Ideally when computers are not accessible due to a network connection error, other programs in the system should be informed as well so they don't try to distribute file to those computers)&lt;/i&gt;&lt;br&gt;From the network side of the system, the network traffic that is generated by the system should be as small as possible, especially the traffic between locations. Although this can be solved during deployment of the system (run the application on each location) we still need to include support for this during design time.&lt;br&gt;&lt;h2&gt;The requirements&lt;/h2&gt;Here is a list of the requirements that comes to my mind. This list is not complete, but that is not a problem because I want the system to evolve over time.&lt;br&gt;&lt;ul&gt;&lt;li&gt;The state of device should be monitored&lt;/li&gt;&lt;li&gt;The state of applications (play-out, OS, etc.) should be monitored&lt;/li&gt;&lt;li&gt;Different kind of alarms should be generated&lt;/li&gt;&lt;li&gt;States of devices and applications should be saved&lt;/li&gt;&lt;li&gt;It should be possible to configure what and how to check on the network&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;It should be easy to add new locations, devices and applications&lt;/li&gt;&lt;li&gt;Visual monitoring should be easy and always up to date&lt;/li&gt;&lt;li&gt;Monitoring is critical but less critical then the whole play-out process&lt;/li&gt;&lt;li&gt;Network overhead should be as low as possible&lt;/li&gt;&lt;/ul&gt;These requirements can be split in two areas, architecture requirements and functional requirements. I will mainly focus on the functional requirements because these are the easiest to test automatically and will most likely contain business logic.&lt;br&gt;&lt;h2&gt;Project restrictions&lt;/h2&gt;This project is started for learning purposes and not to write a complete and fully functional application. I will use this project to learn (and explain) the following things:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Object Oriented programming&lt;/li&gt;&lt;li&gt;C# (.NET and Mono)&lt;/li&gt;&lt;li&gt;Multi platform development (Linux and Windows)&lt;/li&gt;&lt;li&gt;Domain Driven Design&lt;/li&gt;&lt;li&gt;Test Driven Development&lt;br&gt;&lt;/li&gt;&lt;li&gt;Perhaps some Service Oriented Architecture (if I see it fit)&lt;/li&gt;&lt;li&gt;Object Relational Mappers for persistence&lt;/li&gt;&lt;li&gt;Agile/Iterative project management&lt;/li&gt;&lt;li&gt;(Design) Patterns&lt;br&gt;&lt;/li&gt;&lt;li&gt;and probably some other techniques that come on my path&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;Well that's all for today, next time I will talk a bit about Domain Driven Development and/or Test Driven Development. (which can go hand in hand :))&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-1438070758526092014?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/1438070758526092014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/01/monitor-system.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1438070758526092014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1438070758526092014'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/01/monitor-system.html' title='The monitor system'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-1562827953966559345</id><published>2009-01-05T15:18:00.002+01:00</published><updated>2009-01-05T15:20:04.949+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='procedural'/><category scheme='http://www.blogger.com/atom/ns#' term='converting'/><category scheme='http://www.blogger.com/atom/ns#' term='Object Oriented'/><title type='text'>From procedural to Object Oriented programming</title><content type='html'>When working with Delphi a while ago, I was in need to format dates and times. As far as I know there is hardly any build-in support for that in Delphi. A colleague pointed me to a unit (Delphi is working with units, they are similar to header files of C/C++ or the source files of Java and C#) where he had created functions to convert different types of date/time combinations.&lt;br&gt;Although they worked very well, inside me everything was screaming. I was working with objects all over the project, and now I needed to use procedural functions in my domain. Today I want to try to convert those functions to a real object, which makes it easy to convert from any date/time format to a specific one that is used in the whole company. Why? to show the power of objects ;)&lt;br&gt;&lt;h2&gt;The procedural interface&lt;/h2&gt;The unit that is used to convert a specific date and/or time format to another one, for example: 23122008 to 20081223 or 2008-12-23 to a TDateTime object. The code is made to handle conversion errors, so in the time this unit was created (years ago) it would have been very useful. Now (as far as I know) the standard Delphi library has some functionality to perform the conversions. There are around the 100 functions to choose from and some of these functions looks very similar. Similar code can lead us to code duplication and that can lead us to bugs in multiple places. But even these 100 functions don't give you all the possibilities you can have. Every function is working on its own and every result should be stored in memory. To be able to do some calculations or comparisons or multiple conversions we are in need for some other "magic". This magic are objects.&lt;br&gt;&lt;h2&gt;The object oriented interface&lt;/h2&gt;Before I describe the interface of the new object, I will describe some requirements for this class.&lt;br&gt;&lt;ul&gt;&lt;li&gt;It should be possible to parse a given date and or time to a TDateTime object.&lt;/li&gt;&lt;li&gt;It should be possible to convert a TDateTime object to a specific date and or time format.&lt;/li&gt;&lt;li&gt;It should be possible to add or remove time to the object.&lt;/li&gt;&lt;/ul&gt;Basically these are the things that are done in the original unit. Lets see how we can put this in an object: &lt;font size="1"&gt;disclaimer, I don't have a Delphi compiler at hand, so I am not sure this is 100% correct.&lt;/font&gt;&lt;br&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;type DateTime = class&lt;br&gt;begin&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;public:&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;procedure ParseDateTime(value, format : string);&lt;br&gt;function ToString(format : string) : string;&lt;br&gt;function Compare(dt : DateTime) : integer;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;font color="#0000ff"&gt;end;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;The method ParseDateTime is used to convert a string to format that is used internally. The method ToString will convert the internal time value to a specific format. Compare will compare the two different values (by using the internal format).&lt;br&gt;&lt;br&gt;OK, now we have a basic interface how do we implement this and what is our internal value? The internal value should be (in my opinion) in a format that the computer understands the best. In Delphi we can use the TDateTime type (if I remember correct) which is just a alias for a Long type which can be found in most programming languages.&lt;br&gt;The parsing of the Date and Time values can be done by using functions that are included in Delphi. We can make sure that errors are caught and we can throw an exception (for example IncorrectFormat exception, or something like that). The same we can do for the ToString function. (I won't show a real implementation, because I don't want to show an example with errors.)&lt;br&gt;To compare two DateTime objects we simply compare the internal values. If I recall correctly Delphi can access private fields of a class instance (an object) from another class instance of the same type, so this shouldn't be a problem. For convenience and to follow standards we return some kind of value depending on the comparison (0 means self equals dt, negative means self is smaller (earlier) than dt and positive means self is greater (later) than dt). There might be a function for this in Delphi as well, but I am not sure.&lt;br&gt;&lt;h2&gt;Time zones&lt;/h2&gt;OK, but what about different time zones you might say. How can a datetime from Europe (GMT +1 and GMT +2) be compared with America (GMT -7)? There are a few solutions for this I think:&lt;br&gt;&lt;ul&gt;&lt;li&gt;We don't mind, so we don't implement&lt;br&gt;&lt;/li&gt;&lt;li&gt;Convert date and time to UTC (GMT 0)&lt;/li&gt;&lt;li&gt;Use region information&lt;/li&gt;&lt;/ul&gt;This list is probably not complete, the first item is unacceptable when you have that above question. The second and third (converting to UTC and region info) are going hand in hand.&lt;br&gt;&lt;br&gt;&lt;font size="1"&gt;&lt;i&gt;&lt;b&gt;*Disclaimer*&lt;/b&gt;&lt;/i&gt; What I write here is pure theoretical, I couldn't test it, but by providing this information, the reader can try it out in his/her preferred programming language.&lt;br&gt;&lt;font size="2"&gt;For converting a date and time format we need to know in which time zone the given time is.&lt;/font&gt;&lt;/font&gt; There we could use for example the TTimeZoneInformation type form Delphi (_TIME_ZONE_INFORMATION structure in Win32 API). To get the UTC time first convert the datetime-value to a long (as before) and then add the TTimeZoneInformation.Bias value. I am not sure if it is possible to get the TTimeZoneInformation type for other time zones, but it is worth trying.&lt;br&gt;&lt;br&gt;When you choose to include the timezone info into the DateTime class, you can use this information for comparison as well.&lt;br&gt;&lt;h2&gt;Default formats&lt;/h2&gt;Of course there are a couple of default formats you can choose from. The easiest way to do this is to create string constants for them, so they can be included easily.&lt;br&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;Although converting programs from procedural to object oriented is very time consuming, it could be done quiet easy when doing it in very small steps. I hope this post gives you a good example of how to approach a typical conversion. When you have questions, please feel free to add a comment :)&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-1562827953966559345?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/1562827953966559345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2009/01/from-procedural-to-object-oriented.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1562827953966559345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/1562827953966559345'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2009/01/from-procedural-to-object-oriented.html' title='From procedural to Object Oriented programming'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-6540288384533252084</id><published>2008-12-21T17:46:00.002+01:00</published><updated>2008-12-21T17:48:12.936+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><title type='text'>Project description</title><content type='html'>One of my first big projects I worked on was a system to detect problems on a play-out network. During this project I learned a lot about software design (I forced myself to use Domain Driven Design) and object oriented programming. But after some time, when the system was already in use, I thought that the design could be better and easier. In this post I want to describe the system, its current design and how I see the new design.&lt;br&gt;I will use the new design in other posts to describe different aspects of software development and techniques.&lt;br&gt;&lt;br /&gt;&lt;h2&gt;&lt;br /&gt; The system&lt;br /&gt;&lt;/h2&gt;When working on this project I worked for a radio broadcaster that uses different transmission site to broadcast their radio programs. On these transmission sites the organisation has a computer network, which are used to automatically play the radio programs. Those little networks are connected to each other and to some distribution sites. The distribution sites take care of sending the radio programs to the right station a few days prior to the scheduled broadcast.&lt;br&gt;&lt;br&gt;Because the organization doesn't have employers on the transmission sites, there was a need for a system that monitors the state of the network and whether the radio programs are playing or not.&lt;br&gt;&lt;h2&gt;The current design&lt;/h2&gt;In the current design I made a separation between "clients" and "servers". The clients were the applications on the transmission site and the servers were the applications on the distribution sites. Both client and server show the state of the network, the client from the transmission site, the server from all transmission sites. The client does the monitoring of the network and devices and send status/change messages via TCP/IP to the servers.&lt;br&gt;&lt;img style="margin: 1em 0pt 0pt 1em; width: 320px; height: 235.172px; float: right;" src="http://docs.google.com/File?id=ddj3k3kn_35g5gd79g3_b"&gt;&lt;br&gt;Internally I made a little domain model. I have a &lt;i&gt;Site&lt;/i&gt;, a &lt;i&gt;SiteRepository&lt;/i&gt; interface to search for a specific site or device. Each site has several &lt;i&gt;CommonDevice&lt;/i&gt;s. A device has a &lt;i&gt;Name&lt;/i&gt;, an &lt;i&gt;Address&lt;/i&gt; and an &lt;i&gt;Online&lt;/i&gt; status.&lt;br&gt;There are some devices that need more information, for example the &lt;i&gt;Computer&lt;/i&gt;. The computer is derived from the CommonDevice and has a &lt;i&gt;PlayQueue&lt;/i&gt; and a &lt;i&gt;PlayStatus&lt;/i&gt;.&lt;br&gt;&lt;br&gt;Checking the status of devices is done in two different ways. Active, the application is running one or more threads that actively check the state of a particular device. Passive, the application get status messages via a TCP message/command server. &lt;br&gt;&lt;br&gt;The problem of this whole design is that it is not really expendable, for every new device that should be checked, a new class should be created. So I think of a completely different design.&lt;br&gt;&lt;h2&gt;The new design&lt;/h2&gt;&lt;img id="xxzk" style="margin: 1em 1em 0pt 0pt; width: 172px; height: 237px; float: left;" src="http://docs.google.com/File?id=ddj3k3kn_36c658bxcg_b"&gt;There is a very easy few for the whole system. Basically there are devices and services. Devices can have multiple services and a service contains the information that should be shown (for example the play queue which lists radio programs that are queue for play-out). This makes the model a lot easier. I now have a &lt;i&gt;Device&lt;/i&gt; which has a status (&lt;i&gt;Online, offline &lt;/i&gt;or &lt;i&gt;unreachable&lt;/i&gt;) and its &lt;i&gt;Name&lt;/i&gt; and &lt;i&gt;Address&lt;/i&gt;. Devices are connected to each other, so every device need to know its &lt;i&gt;Parent&lt;/i&gt; as well. (or its children, or both, I am not sure about that yet.) This way it is possible to tell that a Device is unreachable, because another device between the unreachable device and the device that is checking the status is offline. I will write more about this structure in another post.&lt;br&gt;So now we have Devices, but we still lack functionality, what about the play-out status and the play-queue? This can be solved by adding &lt;i&gt;Service&lt;/i&gt;s to the devices. A Service has a &lt;i&gt;Name&lt;/i&gt;, a &lt;i&gt;Status&lt;/i&gt; and &lt;i&gt;Data&lt;/i&gt;. The Status indicates whether the service is running correctly or not. The data contains information about a specific service, for example the queue items in the play-queue.&lt;br&gt;&lt;br&gt;By using this model it is possible to add a lot of other devices and services. The only problem I still see is how does the application determine the status of the Device or Service? A possibility is to add a &lt;i&gt;Command&lt;/i&gt; class that contains the information about how to check the status. The question is whether this Command class belongs in the domain or not.&lt;br&gt;&lt;br&gt;&lt;h3&gt;&lt;i&gt;Disclaimer&lt;/i&gt;&lt;/h3&gt;It is possible that someone is reading this and thinks "This sounds familiar...". That could be possible. The same concept (except for the object oriented way of working) is already realized by &lt;br&gt;&lt;a title="Nagios" href="http://www.nagios.org" id="t70j"&gt;Nagios&lt;/a&gt;. Nagios is a network monitoring system created by &lt;a title="Nagios Enterprises" href="http://www.nagios.com/" id="i.2s"&gt;Nagios Enterprises&lt;/a&gt;.&amp;nbsp; It is released as Open Source Software under the GNU General Public License, but is only running on a Linux host. Since the organization I worked for is using Windows on it's computers, it was not an option to use it.&lt;br&gt;My project is started as learning project for object oriented programming and other development techniques. Since Nagios is not object oriented (but written in C) I think it will not hurt anybody when I use the concepts of Nagios. This project is started for personal use, and I might decide to release it under an open source license.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-6540288384533252084?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/6540288384533252084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2008/12/project-description.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6540288384533252084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/6540288384533252084'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2008/12/project-description.html' title='Project description'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7289947411527326869.post-657132719137441963</id><published>2008-12-18T11:06:00.004+01:00</published><updated>2008-12-19T13:32:24.135+01:00</updated><title type='text'>Introducing myself</title><content type='html'>Hello, my name is David Perfors. since summer 2007 I am a graduated programmer.&lt;br&gt;&lt;br /&gt;For one year I have worked for a Christian radio broadcaster as a programmer. We were using Delphi and I developed a system to monitor the state of the play-out system. The play-out system is a network of computers that play radio programs on a specific time. Beside computers there were other devices as well that needed to be monitored.&lt;br&gt;&lt;br /&gt;Currently I am working for a software firm using C# .NET and Java. As a personal training project I wanted to rewrite the monitoring system using different techniques I am learning now.&lt;br&gt;&lt;br /&gt;Some techniques are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Domain Driven Design (I was already using this, but I did not make use of all the possibilities)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Test Driven Development&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;NHibernate&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;.NET / Mono&lt;br&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Well, the last two are not really techniques but frameworks, but I need to learn how to use them ;)&lt;br&gt;&lt;br&gt;One of the reasons I start blogging is to write down my findings and experiences. But I will probably not blog only about programming/development, but also about other things I like to do. I am a great fan of Linux and Unix and I like to investigate applications and projects that run on it (like Asterix, mutt and Nagios). Photography is a hobby that I started this year, and I just want to share some of the pictures I took.&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7289947411527326869-657132719137441963?l=dnperfors.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dnperfors.blogspot.com/feeds/657132719137441963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dnperfors.blogspot.com/2008/12/introducing-myself.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/657132719137441963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7289947411527326869/posts/default/657132719137441963'/><link rel='alternate' type='text/html' href='http://dnperfors.blogspot.com/2008/12/introducing-myself.html' title='Introducing myself'/><author><name>David Perfors</name><uri>http://www.blogger.com/profile/09683029463580058197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
