tag:blogger.com,1999:blog-89958781452666676962023-08-10T09:55:57.507+02:00JENNIUS SoftwarePassionate about developing software.Jorghttp://www.blogger.com/profile/07164071822081444920noreply@blogger.comBlogger39125tag:blogger.com,1999:blog-8995878145266667696.post-58253443762068970672017-11-25T09:30:00.000+01:002017-11-25T09:39:26.920+01:00Udacity Lab: Simulated Annealing Lab Results<h2>
Introduction</h2>
I'm currently doing a course at Udacity and I'm using this post to share some results with my peers. We were asked to analyse how changing certain properties of the <a href="https://en.wikipedia.org/wiki/Simulated_annealing">Simulated Annealing Algorithm</a> would change the solutions of the <a href="https://en.wikipedia.org/wiki/Travelling_salesman_problem">Traveling Salesman Problem</a>. I produced some histograms which I found interesting enough to share. My apologies if I don't explain anything further.<br />
<div>
<h2>
Changing the Number of Cities</h2>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-I4-fUjPA_Nc/WhkfYRBn89I/AAAAAAAAFfc/G9iJmoqerl8fidQBREYFqN9DegtN3Jm7QCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2B10_10e6_0.95.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://4.bp.blogspot.com/-I4-fUjPA_Nc/WhkfYRBn89I/AAAAAAAAFfc/G9iJmoqerl8fidQBREYFqN9DegtN3Jm7QCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2B10_10e6_0.95.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2450, Mean 1836, Var 63180, Skewness 0.622</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-SL8RfKmlipY/WhkfYQfba9I/AAAAAAAAFfY/ogMDNRhRfhsy3B79vV4eBi0E4bB9SjEFACLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2B30_10e6_0.95.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="382" height="221" src="https://1.bp.blogspot.com/-SL8RfKmlipY/WhkfYQfba9I/AAAAAAAAFfY/ogMDNRhRfhsy3B79vV4eBi0E4bB9SjEFACLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2B30_10e6_0.95.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 4487, Max 7316, Mean 5840, Var 277449, Skewness 0.0098</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
By increasing the number of cities in the second graph we increase the complexity of the problem and we see that the algorithm most of the time only finds a sub optimal solution. The optimal solution is at the Min-Value to the left and only with 10 cities we see a graph that is skewed to the right. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Changing Temperatur</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-2Z67dD3Pmmk/WhkjalF92-I/AAAAAAAAFfw/Xe1G7ra_L24TLiQUzLTQ0vExG_iuKLzGwCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BTemp%2B1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://2.bp.blogspot.com/-2Z67dD3Pmmk/WhkjalF92-I/AAAAAAAAFfw/Xe1G7ra_L24TLiQUzLTQ0vExG_iuKLzGwCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BTemp%2B1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2501, Mean 1895, Var 86949, Skewness 0.439</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-9-NeaSLS87c/WhkjatZW6dI/AAAAAAAAFf4/tEJKPWIidKk3D2somDHK_YyUK8tLD759gCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BTemp%2B2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://1.bp.blogspot.com/-9-NeaSLS87c/WhkjatZW6dI/AAAAAAAAFf4/tEJKPWIidKk3D2somDHK_YyUK8tLD759gCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BTemp%2B2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2439, Mean 1853, Var 76739, Skewness 0.391</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-56KXm4D-VAI/WhkjaoVYEgI/AAAAAAAAFf0/E8ir34nbxYELC1VlnOvX5qTXK58XMuaiQCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BTemp%2B3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="382" height="221" src="https://3.bp.blogspot.com/-56KXm4D-VAI/WhkjaoVYEgI/AAAAAAAAFf0/E8ir34nbxYELC1VlnOvX5qTXK58XMuaiQCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BTemp%2B3.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2427, Mean 1859, Var 74511, Skewness 0.363</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-30mJCFDQPI4/Whkjbm5Ld9I/AAAAAAAAFf8/nLrJLXuhnx0Ag5yPNQvVEDFUU7HQtaPcQCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BTemp%2B4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://2.bp.blogspot.com/-30mJCFDQPI4/Whkjbm5Ld9I/AAAAAAAAFf8/nLrJLXuhnx0Ag5yPNQvVEDFUU7HQtaPcQCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BTemp%2B4.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2436, Mean 1849, Var 73730, Skewness 0.271</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-h1jnJHA_Uz4/Whkjb6pPX8I/AAAAAAAAFgA/4wSCjI4OxXIt_NUioT32PYLBevlC4os-ACLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BTemp%2B5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="375" height="225" src="https://1.bp.blogspot.com/-h1jnJHA_Uz4/Whkjb6pPX8I/AAAAAAAAFgA/4wSCjI4OxXIt_NUioT32PYLBevlC4os-ACLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BTemp%2B5.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2564, Mean 2040, Var 92452, Skewness -0.450</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We see that choosing a very high temperature has not a huge effect. The first two histograms look the same even though the temperature on the first one was significantly higher. But we see in the last two histograms that choosing a too low temperature is not good as we start to skew to the left.</div>
<div>
<br /></div>
<h2 style="clear: both; text-align: left;">
Changing Alpha</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-QbBjiXFR36o/WhkmeAVP5OI/AAAAAAAAFgM/wsrKnzPMt8cNxejAqZ3UmBTjuo0fTHDIwCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="376" height="224" src="https://1.bp.blogspot.com/-QbBjiXFR36o/WhkmeAVP5OI/AAAAAAAAFgM/wsrKnzPMt8cNxejAqZ3UmBTjuo0fTHDIwCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B1.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2368, Mean 1693, Var 37448, Skewness 0.587</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-9Yqrd6b-avk/WhkmeLvVcJI/AAAAAAAAFgQ/_w42-iSKBfcGPlCcIQfGtTqF-NOtrjbaQCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://3.bp.blogspot.com/-9Yqrd6b-avk/WhkmeLvVcJI/AAAAAAAAFgQ/_w42-iSKBfcGPlCcIQfGtTqF-NOtrjbaQCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1434, Max 2465, Mean 1870, Var 63441, Skewness 0.335</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-6RQs-q0xWYs/WhkmeF49ODI/AAAAAAAAFgU/DWh7nbAGFUIWXCqIl3sWKuzo9YQyAY7swCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="380" height="222" src="https://1.bp.blogspot.com/-6RQs-q0xWYs/WhkmeF49ODI/AAAAAAAAFgU/DWh7nbAGFUIWXCqIl3sWKuzo9YQyAY7swCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B3.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2548, Mean 2007, Var 82375, Skewness -0.379</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-XfPKHBoyGM4/Whkme3h_NKI/AAAAAAAAFgY/Mjwp1VwvgDMt278bQYvr6VzrvZlL8ffwACLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="382" height="221" src="https://3.bp.blogspot.com/-XfPKHBoyGM4/Whkme3h_NKI/AAAAAAAAFgY/Mjwp1VwvgDMt278bQYvr6VzrvZlL8ffwACLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B4.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1426, Max 2608, Mean 2065, Var 75604, Skewness -0.545</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-lIntQD__V8U/WhkmfLQMjhI/AAAAAAAAFgc/SKwCVwmlChY7IY7yatdAnhPnYJSgxiFKwCLcBGAs/s1600/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="264" data-original-width="372" height="227" src="https://2.bp.blogspot.com/-lIntQD__V8U/WhkmfLQMjhI/AAAAAAAAFgc/SKwCVwmlChY7IY7yatdAnhPnYJSgxiFKwCLcBGAs/s320/Histogram%2BSimulated%2BAnnealing%2BAlpha%2B5.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Nobs 100, Min 1676, Max 2729, Mean 2198, Var 60915, Skewness -0.283</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We clearly see that choosing a high alpha value is best as the graph skews to the right while the variance is still the smallest. A high alpha significantly increase the run time therefore alpha and run time have to be carefully balanced.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br /></div>
<div>
<br /></div>
</div>
Anonymousnoreply@blogger.com3tag:blogger.com,1999:blog-8995878145266667696.post-71090295637166634672016-04-01T17:46:00.002+02:002016-04-01T17:47:45.856+02:00Food Hero on wit.aiThe guys at wit.ai list <a href="http://www.thefoodhero.com/">Food Hero</a> on their website now. That's pretty cool.<br />
<br />
Have a look <a href="https://wit.ai/community">here </a>and scroll down to Food Hero.Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-8995878145266667696.post-6448694148210217782015-10-30T13:45:00.000+01:002015-10-30T13:48:27.911+01:00Food Hero is on the Apple App StoreI've been feverishly working on my first App and finally it's there... on the world famous Apple App Store. It arrived in heaven so to speak.<br />
<div>
<br /></div>
<div>
Food Hero is a restaurant guide with which you interact through a conversation. I always found a conversation based approach very interesting since it opens up a lot of new options which traditional guides, for example <a href="http://www.yelp.co.uk/">yelp</a>, <a href="http://www.tripadvisor.co.uk/TravelersChoice-Restaurants-cFineDining-g1">trip advisor</a>, google etc..., don't have. It's an experiment and I have no idea where it goes next. Is it just a curiosity? Is searching for restaurants the right thing to do? Will Siri, Cortana, Google Now & co. do what I envision with Food Hero in future?</div>
<div>
<br /></div>
<div>
Food Hero has been trained with what I imagined people would do with it. I know reality will be much different. And that's my next aim. Learning what people actually do with it.</div>
<div>
<br /></div>
<div>
Download it, try it out and please let Food Hero collect usage data since that is really what I'm after at the moment. If you are concerned about your privacy please check out <a href="http://foodheroweb.herokuapp.com/legal/privacy_policy">Food Hero's privacy policy</a>.</div>
<div>
<br /></div>
<div>
For more information please visit:</div>
<div>
<ul>
<li><a href="http://www.thefoodhero.com/">www.thefoodhero.com</a> </li>
<li><a href="https://itunes.apple.com/us/app/food-hero/id923359371?mt=8">Apple's App Store</a></li>
</ul>
</div>
Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-8995878145266667696.post-46990327691526353812013-06-25T10:36:00.000+02:002013-06-25T10:42:19.867+02:00Why neography-batch is useful to meI'm working on a <a href="http://rubyonrails.org/" target="_blank">ruby on rails</a> project and I decided to use <a href="http://www.neo4j.org/" target="_blank">neo4j</a> as one of the data stores. The software is about writing medial case reports and all reports are internally deconstructed into their syntactical and semantic structure. During that process, words are stored as neo4j-nodes (organised in sentences, chapters and reports). Words are also connected to other words trough neo4j-relations (e.g.: <a href="http://nlp.stanford.edu/software/dependencies_manual.pdf" target="_blank">preposition, adjective-modifier, possession-modifier</a> etc..) and sentences are connected to medical concepts (e.g.: <a href="http://bioportal.bioontology.org/ontologies/46896?p=terms&conceptid=95549001" target="_blank">Retroperitoneal hemorrhage</a>) and concepts can be connected to other concepts.<br />
<br />
This process goes to show that, when saving a report, a considerable amount of nodes and relationships have to be created, updated or delete. I tried following approaches to access the neo4j-server:<br />
<br />
<ol>
<li><a href="http://api.neo4j.org/" target="_blank">Neo4j Java API</a> via <a href="http://rjb.rubyforge.org/" target="_blank">Rjb</a> (Ruby Java Bridge): This approach was too slow since the Java API is fine-grained and each call into the Java API had to be bridged between ruby and java. Because I planned to deploy the software in the cloud (<a href="https://www.heroku.com/" target="_blank">Heroku</a> and the <a href="https://addons.heroku.com/neo4j" target="_blank">neo4j-plugin</a>) this approach wouldn't have worked anyway.</li>
<li><a href="https://github.com/maxdemarzi/neography" target="_blank">Neograpyh</a>: This was a better solution since Neography is a ruby-gem which accesses neo4j trough its <a href="http://docs.neo4j.org/chunked/milestone/rest-api.html" target="_blank">REST API</a>. In order to have a good performance I exclusively used <a href="https://github.com/maxdemarzi/neography/wiki/Scripts-and-queries" target="_blank">Cypher queries</a> and <a href="https://github.com/maxdemarzi/neography/wiki/Batch" target="_blank">Batches</a>. Everything else was too fine-grained for my purposes. Additionally, I used batches to implement <a href="http://en.wikipedia.org/wiki/Database_transaction" target="_blank">transactions</a>. I aggregated all 'commands' into one batch which was sent over the network as a whole and had it executed by the neo4j-server in one transaction. This solution enabled me to define reports as an <a href="http://en.wikipedia.org/wiki/Domain-driven_design" target="_blank">Aggregate</a> and to always modify them in one batch. </li>
</ol>
<div>
However, in the course of creating and/or modifying a report it proved difficult to use Neography's native batch functionality. The results produced by different parts of my software couldn't be easily aggregated into one single batch. Therefore, I wrote a tiny extension to Neography called <a href="https://github.com/Enceradeira/neography-batch" target="_blank">neography-batch</a>. The neography-batch helps composing several batches into larger batches and referencing specific 'commands' in a batch from the same batch or from another batch. If you are interested, please see <a href="https://github.com/Enceradeira/neography-batch" target="_blank">neography-batch on github</a> or <a href="https://rubygems.org/gems/neography-batch">RubyGems.org</a>.</div>
Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-8995878145266667696.post-70127507526027197182011-10-21T13:56:00.001+02:002011-10-21T13:58:38.991+02:00Short abstract of HTML 5I've recently finished reading <a href="http://www.prohtml5.com/">Pro HTML5 Programming</a>. The book includes good examples, it is easy to read, and it's a nice introduction to HTML5. Some examples unfortunately didn't work but I guess they were based on an older version of the HTML5 specifications which wasn't supported by my browsers any more.<br />
<br />
Following a brief summary of the new HTML5 features ordered by my view of their importance:<br />
<ul><li><b><span class="Apple-style-span" style="font-weight: normal;"><b>HTML5 WebSocket: </b>This is a lightweight duplex communication channel between server and websites and it offers a faster way to send small messages back and forth. A WebSocket can just be opened once the http communication has already been established ("Upgrading the http-connection to WebSocket")</span></b></li>
<li><b>HTML5 Web Workers: </b>A WebWorker is setup by a JavaScript and executes another JavaScript in parallel. Communication to and from WebWorkers is preferably implemented using 'Cross Document Messaging' or messaging via the Web Storage.</li>
<li><b>HTML5 Web Storage: </b>Stores key/value-pairs in either a session store or a local store. The stores are isolated by their origin (e.g: www.evil.com can't access values from www.example.com). There are events published by the store which are fired when a value changes. Those events can also be used to implement messaging between websites.</li>
<li><b>HTML5 Canvas: </b>A simple API to render 2D-drawings from within the browser using Java-Script. It's also possible to read and modify parts of the canvas using bitmaps.</li>
<li><b>Communication APIs: </b>'Cross Document Messaging' allows sending messages and events between parts of a website even they are not from the same origin. (which hasn't been possible due to security concerns before). 'XMLHttpRequest Level 2' allows the same for communication to the server. It means a website originating from 'example.net' can send XMLHttpRequests to different origins like 'example.net' and 'example.com' at the same time. The import part is that both sender and receiver of 'cross messages' have to be configured accordingly otherwise the communication is not possible due to security constraints.</li>
<li><b>HTML5 Geolocation:</b> A simple API to access the browser's geographical location. The method of how the location is determined is hidden away by the API. Depending on the kind of browser and hardware the accuracy of the measurement can vary greatly.</li>
<li><b>HTML5 Audio and Video: </b>Embeds audio and video natively in HTML. Defines controls to play audio and video. Audio and video editing is not included.</li>
<li><b>HTML5 Forms API: </b>A bunch of new html tags and attributes that provide us with better semantics and therefore enable the browser to render more advanced or different controls. (e.g a control that just accepts E-mail addresses)</li>
</ul><div>I'm really looking forward seeing where HTML5 will take us and what frameworks and paradigms will evolve around it. Will websites become more like traditional <a href="http://en.wikipedia.org/wiki/Rich_client">rich clients</a> now?</div><div><br />
</div><div><br />
</div><div><br />
</div>Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-8995878145266667696.post-88465082712037824082011-07-30T16:55:00.011+02:002011-08-01T08:42:54.661+02:00Typing effort analyzer in Ruby<span style="font-family: inherit;">I've been working on RePhraser over <span style="font-family: inherit;">the course of the last 6 months. <span style="line-height: 115%; mso-ansi-language: EN-GB; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">RePhraser is a piece of software which aims to help professionals in writing repetitive texts quickly</span>. Unfortunately I haven't been able to make it available to a broader audience yet mainly due to the fact that it only works</span> reliably in Internet Explorer and that there are still some basic features missing. Even so, I've uploaded a short demo </span><a href="http://www.youtube.com/watch?v=qwwFQ6yWG_Q"><span style="font-family: inherit;">here</span></a><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br />
</span><br />
<span style="font-family: inherit;">RePhraser assists you by anticipating and displaying words while you are typing them. Imagine you being a physician who writes the word "immunocytochemically". You would start to type "immu" whereas RePhraser would bring up all the words that start with "immu". There would be simple words like "immune", "immunogen" or more complicated words like the aforementioned "immunocytochemically". In fact there are a lot of words that starts with "immu". RePhraser would be pretty useless if it displayed easy words like "immune" or "immunogen" at this point because professional writers type those words much faster than RePhraser could display them. To solve this problem RePhraser uses a typing effort model. The basic idea is to display words which are harder to type first and to ignore words which are easy to write. To do so RePhraser rates every word based on the </span><a href="http://mkweb.bcgsc.ca/carpalx/?typing_effort"><span style="font-family: inherit;">carpalx typing effort model</span></a><span style="font-family: inherit;">. The</span><a href="http://mkweb.bcgsc.ca/carpalx/?typing_effort"><span style="font-family: inherit;"> carpalx typing effort model</span></a><span style="font-family: inherit;"> takes account of things like weak fingers (like pinky and ring finger), travel distance of fingers, same-finger typing (e.g "uhm"), balanced hand-use vs. right-hand priority etc...</span><br />
<span style="font-family: inherit;"><br />
</span><br />
<span style="font-family: inherit;">I implemented the carpalx typing effort model in ruby and published source code and Gem on </span><a href="https://github.com/Enceradeira/teanalyzer"><span style="font-family: inherit;">https://github.com/Enceradeira/teanalyzer</span></a><span style="font-family: inherit;">. The project is named Teanalyzer, which is an abbreviation of typing effort analyzer.</span><br />
<span style="font-family: inherit;"><br />
</span><br />
<span style="font-family: inherit;">What do you think about Teanalyzer? Or are you interested in RePhraser? Please drop a line or <a href="mailto:info@jennius.co.uk">contact me</a>!</span>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-30783609208428971182010-03-27T20:53:00.005+01:002010-03-27T21:04:45.055+01:00My days at QCon 2010, LondonThis was my first visit at a QCon-conference and I was quite excited to see some of the 'famous' speakers in the world of software development. There were such interesting talks on the schedule that I even missed out on the talks of <a href="http://qconlondon.com/london-2010/speaker/Eric+Evans">Eric Evans</a> and <a href="http://qconlondon.com/london-2010/speaker/Martin+Fowler">Martin Fowler</a>. May be next year!<br />
Generally I jumped between the different tracks but attended more than one talk from the tracks <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=327">Software Craftsmanship</a>, <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=325">Functional programming</a> and <a href="http://qconlondon.com/london-2010/tracks/show_track.jsp?trackOID=329">Irresponsible Architectures and Unusual Architects</a>. <br />
<br />
Following talks were my personal highlights (based on the speaker, importance to me, and what I learned from it):<br />
<br />
<div><a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/RobertC.Martin_BadCodeCraftsmanshipEngineeringAndCertification.pdf"><strong>Bad Code, Craftsmanship, Engineering, and Certification</strong></a> by Robert C.Martin<strong>.</strong> Nothing new, but nethertheless a very entertaining talk. The <a href="http://vimeo.com/9981123">bad code video</a> was phenomenal (especially with the depressing background music). He questioned if bad code is written because of deadlines, laziness, boredom or even job security ('I´m the only guy that can maintain that!'). He also suggested to follow <a href="http://commons.oreilly.com/wiki/index.php/The_Boy_Scout_Rule">The Boy Scout Rule</a>: "Always leave the campground cleaner than you found it". "The only way to go fast is to go well" was another of his wisdoms. And then he 'evangelized' agile practices like TDD, pair programming, CI etc... that leads us to what he calls 'Pride of Workmanship'.</div><div></div><br />
<br />
<a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/DanNorth_SharpeningTheTools.pdf"><strong>Sharpening the Tools</strong></a> by Dan North. Good speaker and motivator. He reflected on the way how we learn things (<a href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition">the Dreyfuss model</a>) and that therefore we are in everything that we learn a 'novice', 'advanced beginner', 'competent', 'proficient' or an 'expert'. He suggested that we have always to renew our skills due to the continuous development of new and more effective techniques in the area of software development:<br />
<ol><li>Practise the basics</li>
<li>Learn from other people</li>
<li>Understand trends</li>
<li>Share knowledge</li>
<li>Maintain your toolbox ('Some tools are timeless, some are disposable')</li>
<li>Learn how to learn</li>
</ol><a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/EmilEifrem_NotOnlySQLAlternativeDataPersistenceAndNeo4J.pdf"><strong>Not Only SQL: Alternative Data Persistence and Neo4J</strong></a> by Emil Eifrém. It was the first time that I attended a talk about this subject and I was very curious about it. I realised soon that it's all about 'scalability'. Like: ´what kind of datastore to you need if you are building a twitter-like-application´. Relational databases are strong with well structured not very complex data (e.g salary-list). NoSQL-datastores are better with more dynamically defined, complex data (e.g: persons and their different relationships to each other). I learned that this is not the end of relational databases but that there are now other techniques available when it comes to storing large amount of complex,dynamic data. I know now that a query like 'all friends of Peter that also know Sarah' can be much more efficient and easier be build with a NoSQL-datastore (especially <a href="http://en.wikipedia.org/wiki/Graph_database">graph-DB's</a>).<br />
<br />
<a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/JohnHughes_TheJoyOfTesting.pdf"><strong>The Joy of Testing</strong></a> by John Hughes. A very refreshing but a little bit academic talk about TDD. The key idea is to abstract test-cases to a set of test-'properties'. Think about a number of test-cases that test a method. Wouldn't it be nice to reduce those test-cases to one unique description that could be run by a test-runner and that this test-runner would find edge-cases that you have never thought about it? I'm not (yet) able to apply this to my daily work but I'm still thinking about it.<br />
<br />
<a href="http://qconlondon.com/london-2010/file?path=/qcon-london-2010/slides/JesperBoeg_KanbanCrossingTheLinePushingTheLimitOrRediscoveringTheAgileVision.pdf"><strong>Kanban - Crossing the line, pushing the limit or rediscovering the agile vision?</strong></a> by Jesper Boeg. A good talk given by a convinced Kanban-evangelist. It was very interesting how deep they integrate product-owner, buisness-analysts and tester into the development process ('developers helps out business-analyst to write down stories if there is a temporary bottleneck'). Sounds like 'extreme scrumming' to me! (very short full development-cycles). I really like the idea of helping out each other so that we can cope with overloaded/under-staffed testers, productowner and business-analysts.<br />
<br />
<a href="http://qconlondon.com/sfile?path=/qcon-london-2010/slides/protected/UdiDahan_CommandQueryResponsibilitySegregation.pdf"><strong>Command-Query Responsibility Segregation</strong></a> by Udi Dahan. Generally he was saying that displayed data (query-part) could completely be decoupled from the persisted data and on the other hand updating the persisted data (command-part) could be done using a much more sophisticated model (e.g: a strong domain-model or a asynchronous event queue etc...). I already knew about this style but new to me was:<br />
<ul><li>It's about how we build the UI and what business-services we offer to a user. I got the impression we should display less raw-data (e.g: less data-grids) and let the software behave more intelligent.</li>
<li>We could deliberately display stale data (e.g: display a account-list with title 'account-balance as it was on 25.4.2010 at 14:34h'). He says that this is usually no problem to a user.</li>
<li>We could try to build much more valuable commands (e.g: a reservation-system that can ´book the best seats for a group of 12 persons were no person must sit alone' instead of letting the user to choose the seats by itself) </li>
</ul><a href="http://qconlondon.com/london-2010/presentation/Scenario-Driven+Development"><strong>Scenario-Driven Development</strong></a> by Ben Butler-Cole (Unfortunately no slides available). In his talk he was suggesting not to do integration/acceptance-testing on a 'per-story' basis. He mentioned that this could lead to brittle tests and to maintenance problems. He suggested to identify a small number of 'key-scenarios' that spam in their final version several stories. A key-scenario for a banking-application could be: 'Poor guy wants to pay a bill´ that includes the stories 'User pays bill' (that is rejected due to insufficient balance), 'User applies for a overdraft', 'Clerk manages overdraft application', 'User pays bill' (that is not anymore rejected). Scenarios are developed incrementally and extended when a story is going to be implemented. He also showed <a href="http://www.thoughtworks-studios.com/agile-test-automation">Twist</a> that was developed by Thoughtworks to support Scenario-Driven Development. An interesting thing is that Twist puts several layer on the top of the application layer, helping to manage reusability and maintainability of the tested UI. These layers are called Scenario-Layer (the scenarios written with Twist, Workflow-Layer (commands like ´go to homepage´) and the Application-model (abstracting the underlying technology with drivers like Selenium). The Workflow-Layer and the Application-model have to be written in Java and enjoy therefore all advantages of a modern programming-language (refactoring,abstraction, object-orientation etc...)<br />
<br />
I also attended following less interesting talks:<br />
<ul><li>Functional Approaches To Parallelism and Concurrency </li>
<li>Demystifying monads </li>
<li>Living and working with aging software </li>
<li>The Counterintuitive Web </li>
<li>Patterns for the People </li>
<li>Transactions: Over Used or Just Misunderstood?</li>
<li>Fighting Layout Bugs </li>
<li>Test-Driven Development of Asynchronous Systems</li>
<li>Data Presentation in a Web App: The Journey of a Startup</li>
<li>Death by accidental complexity </li>
</ul>Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-8995878145266667696.post-23301699720718170122009-10-22T16:43:00.025+02:002011-01-19T20:43:23.574+01:00Sample Application with White,WPF,TDD and DDDI'm currently thinking about what we could do better on a next project avoiding some technical issues that we have had in our latest project. Some of the issues were<br />
<br />
<ol><li>The <a href="http://martinfowler.com/eaaDev/PassiveScreen.html">Passive View</a> implementation for our Win-Form client was too costly. The design of it wasn't intuitive and straight forward at all.</li>
<li>The Passive View implementation didn't allow us to unit-test the <span class="blsp-spelling-error" id="SPELLING_ERROR_0">UI</span>. Even we were able to test the presenters we still couldn't test the event- and data binding automatically . </li>
<li>Our initial plan to do acceptance- and <span class="blsp-spelling-error" id="SPELLING_ERROR_1">integrationtesting</span> with <a href="http://www.automatedqa.com/products/testcomplete/"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">TestComplete</span></a> failed. No tests have ever been written with <span class="blsp-spelling-error" id="SPELLING_ERROR_3">TestComplete</span>.</li>
<li>Our testing-suite runs too slow. The whole suite was too slow and even running one single test took too much time.</li>
<li>We struggled with <a href="http://domaindrivendesign.org/node/88">Aggregates</a> and domain logic leaked sometimes into the presentation layers.</li>
<li>The application is too slow. This was caused due the fact that we couldn't react appropriately when we were forced to move our 2-tier implementation to a 3-tier implementation. </li>
</ol>I've recently written a sample application to find answers to some of those problems. You can download the application from this <a href="http://www.2shared.com/file/vdtAcuva/OrderExploration.html">site</a> (Click 'Save file to your PC' at the end of the site).<br />
<br />
<br />
I'm going to explain my thoughts in detail maybe later, but the most interesting points in the sample application are:<br />
<ul><li><strong><a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation"><span class="blsp-spelling-error" id="SPELLING_ERROR_4">WPF</span></a>+<a href="http://www.codeplex.com/white">White</a>:</strong> White allows testing the <span class="blsp-spelling-error" id="SPELLING_ERROR_5">UI</span> right from inside the unit-test runner. Following some basic principals it allows to script the <span class="blsp-spelling-error" id="SPELLING_ERROR_6">UI</span> right from the c#-code. But I used White just to Unit-Test the <span class="blsp-spelling-error" id="SPELLING_ERROR_7">UI</span> and to write some basic integration tests. I don't believe that one should use White to do more than that otherwise he might get some serious maintenance issues. For details see<strong> <span class="blsp-spelling-error" id="SPELLING_ERROR_8">OrderExploration</span>.Test\<span class="blsp-spelling-error" id="SPELLING_ERROR_9">UnitTest</span>\<span class="blsp-spelling-error" id="SPELLING_ERROR_10">Ui</span> </strong>and <strong><span class="blsp-spelling-error" id="SPELLING_ERROR_11">OrderExploration</span>.Test\Integration</strong></li>
<li><strong><a href="http://en.wikipedia.org/wiki/Acceptance_testing">Acceptance-Testing</a>: </strong>I think acceptance-testing frameworks are a weak point of the .net-world. Either they require a lot of infrastructure (like <span class="blsp-spelling-error" id="SPELLING_ERROR_12">wiki's</span>) or they can't be used by "none <span class="blsp-spelling-error" id="SPELLING_ERROR_13">technical's</span>". <span class="blsp-spelling-error" id="SPELLING_ERROR_14"><a href="http://nbehave.org/">NBehave</a></span> is useless because it can't be used by "none technical's" and it doesn't produce readable code at all (That statement is maybe wrong with Version 0.4, but I didn't check). <span class="blsp-spelling-error" id="SPELLING_ERROR_15">FitNess</span> is far too complicated for a small project like the sample application. I tried <span class="blsp-spelling-error" id="SPELLING_ERROR_16">StoryTeller</span> as well, but there is not a lot of documentation available yet, so I gave up. So why not using pure old <span class="blsp-spelling-error" id="SPELLING_ERROR_17">nunit</span>-tests if there are no "none <span class="blsp-spelling-error" id="SPELLING_ERROR_18">technical's</span>"? For details see <strong><span class="blsp-spelling-error" id="SPELLING_ERROR_19">OrderExploration</span>.Test\Acceptance</strong></li>
<li><strong><a href="http://dddstepbystep.com/wikis/ddd/persistence-ignorance.aspx">Persistence-Ignorance</a>: </strong>There is just one test that hits the database (see <strong><span class="blsp-spelling-error" id="SPELLING_ERROR_20">OrderExploration</span>.Test\Integration</strong>). All other tests (<span class="blsp-spelling-error" id="SPELLING_ERROR_21">UI</span>, unit <span class="blsp-spelling-error" id="SPELLING_ERROR_22">und</span> acceptance) run against stubs. </li>
<li><strong>Test-Setups: </strong>To setup Unit- Acceptance- and <span class="blsp-spelling-error" id="SPELLING_ERROR_23">Integrationtest</span> differently I used <span class="blsp-spelling-error" id="SPELLING_ERROR_24">SetupFixtures</span> (I didn't know them before!). Lookout for classes with name "<a href="http://www.nunit.org/index.php?p=setupFixture&r=2.4"><span class="blsp-spelling-error" id="SPELLING_ERROR_25">SetupFixture</span></a>"</li>
<li><strong><span class="blsp-spelling-error" id="SPELLING_ERROR_26">CQS</span> (Command-Query <span class="blsp-spelling-error" id="SPELLING_ERROR_27">Seperation</span>) </strong><a href="http://codebetter.com/blogs/ian_cooper/archive/2009/10/08/the-catalogue-metaphor-and-command-query-seperation-architectures.aspx"><strong>inspired by a Ian Cooper</strong></a>: I tried to separate querying data (mainly for displaying on view) and commanding (mainly for updating on aggregates). I'm not sure if I really got it right! For an example see method <strong><span class="blsp-spelling-error" id="SPELLING_ERROR_28">DataService</span>.<span class="blsp-spelling-error" id="SPELLING_ERROR_29">GetOrders</span>()</strong> that queries data right from the database and see <strong><span class="blsp-spelling-error" id="SPELLING_ERROR_30">OrderService</span>.Submit()</strong> that writes changes through the aggregate to the database.</li>
<li><strong>Aggregates</strong>: See the class Order that defines an Aggregate-Root. I tried to build an expressive aggregate by separating the aggregate from its persisted structure (see class <span class="blsp-spelling-error" id="SPELLING_ERROR_31">OrderRow</span>) and its displayed structure (see class <span class="blsp-spelling-error" id="SPELLING_ERROR_32">OrderDetailData</span>). If there is an interest I would like to discuss that decision later. For now see method Order.<span class="blsp-spelling-error" id="SPELLING_ERROR_33">AddTag</span>() and think about: 1.) If the class Order were directly bound to the <span class="blsp-spelling-error" id="SPELLING_ERROR_34">UI</span>, how would you handle the fact that the user can add/remove tags several time but just the last state should be persisted and logged in the history. 2.) If the class Order were persisted directly, how would you handle the fact that tags are persisted as strings? (see Order.Tags in the database-scheme)</li>
<li>and <a href="http://structuremap.sourceforge.net/Default.htm"><strong><span class="blsp-spelling-error" id="SPELLING_ERROR_35">StructureMap</span></strong></a> and <strong><a href="http://www.codeplex.com/AutoMapper"><span class="blsp-spelling-error" id="SPELLING_ERROR_36">AutoMapper</span></a></strong> ... of course!</li>
</ul><strong>Summary</strong><br />
<ul><li>White is cool and helps to (Unit)-test <span class="blsp-spelling-error" id="SPELLING_ERROR_37">UI</span></li>
<li>Persistence Ignorance can be implemented and helps to make Unit-/<span class="blsp-spelling-error" id="SPELLING_ERROR_38">UI</span>-/Acceptance tests much faster</li>
<li><span class="blsp-spelling-error" id="SPELLING_ERROR_39">CQS</span> (Command-Query-Separation), <span class="blsp-spelling-error" id="SPELLING_ERROR_40">ViewModels</span>, <span class="blsp-spelling-error" id="SPELLING_ERROR_41">DomainModel</span> and <span class="blsp-spelling-error" id="SPELLING_ERROR_42">PersistenceModel</span> add another layer of indirection that can help to solve tricky problems quite <span class="blsp-spelling-error" id="SPELLING_ERROR_43">easly</span>. However, these indirections can be a huge overkill for simple applications. I have no doubts that it's worth to have <span class="blsp-spelling-error" id="SPELLING_ERROR_44">ViewModels</span> (including all kind of MVP,<span class="blsp-spelling-error" id="SPELLING_ERROR_45">MVC</span>) but I'm not sure when it's worth to separate <span class="blsp-spelling-error" id="SPELLING_ERROR_46">DomainModel</span> and <span class="blsp-spelling-error" id="SPELLING_ERROR_47">PersistenceModel</span>. In the sample application, <span class="blsp-spelling-error" id="SPELLING_ERROR_48">DDD</span> (e.g Repository-Pattern) helped me to answer that question per Aggregate. In the sample application the Aggregate Order has a separated <span class="blsp-spelling-error" id="SPELLING_ERROR_49">DomainModel</span> and <span class="blsp-spelling-error" id="SPELLING_ERROR_50">PersistenceModel</span>. For the other Aggregates <span class="blsp-spelling-error" id="SPELLING_ERROR_51">DomainModel</span> and <span class="blsp-spelling-error" id="SPELLING_ERROR_52">PersistenceModel</span> are the same. Any thoughts about that?</li>
</ul><br />
<br />
<br />
<br />
<br />
<br />
<br />
<ul></ul>Anonymousnoreply@blogger.com9tag:blogger.com,1999:blog-8995878145266667696.post-58478537016357846062009-08-03T21:28:00.003+02:002009-08-03T21:54:58.014+02:00IObservable ... it's so beautifulI've just watched <a href="http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx/">Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx)</a> and it's again a great work of Erik, Wes and their team.<br /><br />It's a petty that I couldn't understand all that formalism but i enjoyed it like art and i'm impressed about the beauty and completness of their solution. That's the first mind-blowing feature of .NET 4.0!Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-8995878145266667696.post-90805635937361439812009-07-26T20:51:00.005+02:002009-07-27T22:12:27.086+02:00Object Role StereotypesI had a short discussions with my college Jürg last week about that classes in object oriented design (especially DDD or <a href="http://www.wirfs-brock.com/PDFs/A%20Brief%20Tour%20of%20RDD%20in%202004.pdf">RDD</a>) can be classified regarding their responsibility and behaviour. Neither could I remember the name for that concept nor any of those classifications. Jürg mentioned that this is like stereotypes in UML. I looked it up now and he wasn't wrong. They are called <a href="http://msdn.microsoft.com/en-us/magazine/cc721605.aspx">'Object Role Stereotypes'</a>. Not that Object Role Stereotypes are defined by the UML specification but one could use stereotypes in UML to classify classes by their Object Role Stereotype<strong>. </strong>Here are the stereotypes that I found:<br /><strong></strong><br /><ul><li><strong>Controller</strong> – Controls application execution. Makes decisions and delegates to other classes. </li><li><strong>Service Provider</strong> – Provides a service to other classes. Performs a calculation, computation, or executes business rules. </li><li><strong>Interfacer</strong> – Communicates actions to other layers or systems. </li><li><strong>Information Holder</strong> – Holds facts. Domain classes. </li><li><strong>Structurer </strong>– Maintains relationships between other classes</li></ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-51744354110969823832009-03-15T17:04:00.006+01:002009-03-15T17:29:09.671+01:00How to get the console output working with NBehave 0.4 and the ReSharper TestrunnerWhen working with the latest build of NBehave 0.4 you may notice that there is no output written to the ReSharper Testrunner Output anymore.<br /><br />Here is how I did workaround the problem. I derived the specs from the following class and every thing was fine again:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>public class SpecBaseWithConsoleOutput: SpecBase<br />{<br /> private EventHandler<EventArgs<MessageEventData>> addedHandler;<br /> private EventHandler<EventArgs<Scenario>> scenarioCreatedHandler;<br /> private EventHandler<EventArgs<Story>> storyCreatedHandler;<br /> public override void MainSetup()<br /> {<br /> base.MainSetup();<br /> addedHandler = (o, a) => Console.WriteLine(a.EventData.Message);<br /> scenarioCreatedHandler = (o, a) => Console.WriteLine(a.EventData.Title);<br /> storyCreatedHandler = (o, a) => Console.WriteLine(a.EventData.Title);<br /> Story.MessageAdded += addedHandler;<br /> Story.ScenarioCreated += scenarioCreatedHandler;<br /> Story.StoryCreated += storyCreatedHandler;<br /> }<br /> public override void MainTeardown()<br /> {<br /> Story.MessageAdded -= addedHandler;<br /> Story.ScenarioCreated -= scenarioCreatedHandler;<br /> Story.StoryCreated -= storyCreatedHandler;<br /> base.MainTeardown();<br /> }<br />}<br /></code></pre>Anonymousnoreply@blogger.com3tag:blogger.com,1999:blog-8995878145266667696.post-84180205103205170682009-01-24T11:27:00.009+01:002009-01-24T12:08:04.868+01:00Implementing and testing mapping code with AutoMapper<a href="http://enceradeira.blogspot.com/2008/07/tdd-design-and-testability.html">I was thinking some months ago</a> that it would be great to have a property mapper that eliminates tedious mapping code . I'm very happy that Jimmy Bogard and his team just have published a framework called <a href="http://www.codeplex.com/AutoMapper">AutoMapper</a> that resolves that issue. I haven't tested it yet but the idea looks promising.<br /><br />Why would I use AutoMapper?<br /><ul><li>In order to implement better encapsulation and layering with less amount of coding</li><li>In order to unit-test mapping code using a simple 'Mapper.AssertConfigurationIsValid()'</li></ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-14771755503449309182009-01-11T09:54:00.002+01:002009-01-13T21:04:55.601+01:00TypeMockAutoMocker on CodePlexI' ve just uploaded the TypeMockAutoMocker to <a href="http://www.codeplex.com/typemockautomocker">http://www.codeplex.com/typemockautomocker</a><br /><br />How to use it:<br />1.) <a href="http://www.codeplex.com/typemockautomocker/Release/ProjectReleases.aspx?ReleaseId=21614">Download</a> TypeMockAutoMocker.dll<br />2.) Copy it to your project and set an assembly reference to it<br />2.) Set 'Copy local = true' on your TypeMock.dll<br />3.) Have fun (see <a href="http://enceradeira.blogspot.com/2009/01/automocking-container-with-typemock.html">Link</a>)<br /><br />StructureMap 2.5.1 and TypeMock 5.1.2 ist the only tested configuration at the moment.Anonymousnoreply@blogger.com1tag:blogger.com,1999:blog-8995878145266667696.post-69648801320478700222009-01-02T08:20:00.031+01:002009-01-03T11:31:36.708+01:00AutoMocking Container with TypeMock IsolatorI have implemented an AutoMocking container for the Isolator inspired by an <a href="http://www.dimecasts.net/Casts/CastDetails/62">Introduction to the AutoMocking container in StructureMap</a>, the fact that our test setups usually are pretty messy and <a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/02/09/automocker-in-structuremap-2-5.aspx">Jeremy's claim that TypeMock users probably don't care about dependency injection</a>. But why do I want to use DI (Dependency Injection) in conjunctions with TypeMock? I don't want to fight a 'religious war' based on that question, but here is what I think:<br /><br /><ul><li>TypeMock without DI lacks an explicit boundary that defines what the class under tests is and which classes are mocks or stubs. This is about <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">solid design</a> and to isolate parts of the software in a structured manner. It’s true that you can mock everything with TypeMock but this is just about mocking and not about software design. </li><br /><li>DI with another mocking framework than TypeMock is like .NET without System.Reflection. I don't like to use System.Reflection but sometimes it's just the right thing. It’s the same with TypeMock. If everything (own code, legacy-code, external libraries etc.) had a <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">solid design</a> you wouldn't need it but sometime it makes the life so much easier.</li></ul><strong>Example without Dependency Injection</strong><br />There is the class under test called ValidationViewPresenter and it has following dependencies:<br /><br /><a href="http://1.bp.blogspot.com/_hcGoxuElMbw/SV80cEzHi8I/AAAAAAAAADY/mN0X7F_HNwM/s1600-h/ClassDiagram1.jpg"><img id="BLOGGER_PHOTO_ID_5287002144485379010" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 236px" alt="" src="http://1.bp.blogspot.com/_hcGoxuElMbw/SV80cEzHi8I/AAAAAAAAADY/mN0X7F_HNwM/s400/ClassDiagram1.jpg" border="0" /></a><br /><br />A a test without DI could look like:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[Test]<br />public void CanValidateCreditCardNumber()<br />{<br /> // Arrange<br /> var viewMock = Isolate.Fake.Instance<ValidationView>();<br /> var customerServiceMock = Isolate.Fake.Instance<CustomerService>();<br /> var creditCardServiceMock = Isolate.Fake.Instance<CreditcardService>();<br /> var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};<br /><br /> // Mock the (hidden) dependencies<br /> Isolate.Swap.NextInstance<ValidationView>().With(viewMock);<br /> Isolate.Swap.NextInstance<CustomerService>().With(customerServiceMock);<br /> Isolate.Swap.NextInstance<CreditcardService>().With(creditCardServiceMock);<br /> // Mock the calls to the dependencies<br /> Isolate.WhenCalled(()=>viewMock.CustomerNr).WillReturn(56);<br /> Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);<br /> Isolate.WhenCalled(()=> creditCardServiceMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);<br /><br /> // Act<br /><pre style="BACKGROUND-COLOR: #a9f5a9"> var presenter = new ValidationViewPresenter();</pre><br /> presenter.ValidateCreditCardOfCustomer();<br /> // Assert<br /> Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);<br />}<br /></code></pre><br /><strong>Example with Dependency Injection</strong><br />After introducing constructor injection it looks like:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[Test]<br />public void CanValidateCreditCardNumber()<br />{<br /> // Arrange<br /> var viewMock = Isolate.Fake.Instance<ValidationView>();<br /> var customerServiceMock = Isolate.Fake.Instance<CustomerService>();<br /> var creditCardServiceMock = Isolate.Fake.Instance<CreditcardService>();<br /> var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};<br /> // Inject dependencies manually<br /><pre style="BACKGROUND-COLOR: #a9f5a9"> var presenter = new ValidationViewPresenter(viewMock, customerServiceMock, creditCardServiceMock);</pre><br /> Isolate.WhenCalled(()=> viewMock.CustomerNr).WillReturn(56);<br /> Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);<br /> Isolate.WhenCalled(() => creditCardServiceMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);<br /><br /> // Act<br /> presenter.ValidateCreditCardOfCustomer();<br /><br /> // Assert<br /> Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);<br />}<br /></code></pre><br /><strong>Example with Automocking Container</strong><br />Let's eliminate the explicit constructor injection by introducing the TypeMockAutoMocker now:<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[Test]<br />public void CanValidateCreditCardNumber()<br />{<br /> // Arrange<br /> var customer56 = new Customer {CreditCardNr = "5500 0001 0001 0001"};<br /><pre style="BACKGROUND-COLOR: #a9f5a9"> var presenterMocker = new TypeMockAutoMocker<ValidationViewPresenter>(MockMode.AAA);</pre><br /> var viewMock = presenterMocker.Get<IValidationView>();<br /> var customerServiceMock = presenterMocker.Get<ICustomerService>();<br /> var creditCardServcieMock = presenterMocker.Get<ICreditCardService>();<br /><br /> Isolate.WhenCalled(() => viewMock.CustomerNr).WillReturn(56);<br /> Isolate.WhenCalled(() => customerServiceMock.GetCustomer(56)).WillReturn(customer56);<br /> Isolate.WhenCalled(() => creditCardServcieMock.ValidateCreditCard("5500 0001 0001 0001")).WillReturn(true);<br /><br /> // Act<br /> presenterMocker.ClassUnderTest.ValidateCreditCardOfCustomer();<br /><br /> // Assert<br /> Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = true);<br />}<br /></code></pre>As you can see the AutoMocking container couldn’t eliminate a lot of complexity. This is due to the fact that the test itself is complex and there are a number of non-default preconditions.<br /><br /><strong>A better example with AutoMocking Container </strong><br />Following code tests the same method but with different preconditions again. But this time we can rely on the default behavior that was setup by the AutoMocking container. This means that all involved and not explicitly mocked interfaces or classes do have a default behavior.<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[Test]<br />public void CanHandleNotExistingCustomer()<br />{<br /> // Arrange<br /><pre style="BACKGROUND-COLOR: #a9f5a9"> var presenterMocker = new TypeMockAutoMocker<ValidationViewPresenter>(MockMode.AAA);</pre><br /> var viewMock = presenterMocker.Get<IValidationView>();<br /> Isolate.WhenCalled(() => viewMock.CustomerNr).WillReturn(56);<br /><br /> // Act<br /> presenterMocker.ClassUnderTest.ValidateCreditCardOfCustomer();<br /><br /> // Assert<br /> Isolate.Verify.WasCalledWithExactArguments(() => viewMock.IsValid = false);<br />}<br /></code></pre><strong>Conclusion</strong><br />There is a big chance that you can get lost using TypeMock and StructureMap in conjunction. The problem is that there are too many ways how they can be combined. However I hope that the TypeMockAutoMocker could help in a way that it's defining a common pattern for how to setup the tests and how to inject the mocks. Remember always:<br /><ul><li>Depended classes are instantiated by the AutoMocker automatically.<br /><li>Depended interfaces and abstract classes are instantiated as mocks. These mocks do have a default behaviour where every method can be called.<br /><li>Depended concrete classes are instantiated by calling its greediest constructor. They are not mocked.<br /><li>To change the default behaviour you can use Inject() to register your own mock to the AutoMocker. It's how you can setup a mock manually.</li></ul><p>Sound’s like ‘<a href="http://en.wikipedia.org/wiki/Convention_over_Configuration">convention over configuration’</a>. And that makes life definitely easier.</p><pre></pre>Anonymousnoreply@blogger.com8tag:blogger.com,1999:blog-8995878145266667696.post-76849994331805648972008-12-14T12:29:00.014+01:002008-12-28T17:49:25.260+01:00A Look Back at Our Scrum implementationI've been working at my current project for one year now and we are 'nearly done' with our first major release. I know that saying 'nearly done' has a little bit of a bad smell in the agile community but we couldn't do everything perfectly. But generally speaking, we did it pretty well and I'm happy how we could eliminate and master the difficulties of the project with <a href="http://en.wikipedia.org/wiki/Scrum_(development)">scrum</a>.<br /><br />We had the following situation at the beginning of the project:<br /><ul><li>A list of requirements in an excel sheet. The list summarized all the thoughts, requirements and promises in an informal way. </li><li>There was a file containing drawings, print-outs from the former legacy system, or other artefacts for each requirement. </li><li>The project was embedded in a much larger project, which was driven by Hermes. Hermes is a heavy weight project management process, commonly used by governmental organisations in Switzerland. </li><li>Our team consisting out of 6 software developers was hired to implement the software. We proposed to implement scrum and the customer agreed on that. </li><li>A contract with a fixed price that was signed a long time before the developers got involved</li></ul><p>It was not easy to push scrum from the development into the larger project organisation. There was a good support for our ideas as long there was no organizational change required. Fortunately we could find a pretty good product owner, but we never have had a scrum master. The role of the scrum master was poorly fulfilled by me as a developer.<br /><br /><strong>What worked well?</strong><br /><br />A lot of things worked great and I'm sure that the project would have failed without an <a href="http://agilemanifesto.org/">agile</a> approach. Here is what has worked well (see <a href="http://www.scrumalliance.org/articles/39-glossary-of-scrum-terms">glossary</a> for details on scrum terminology): </p><ul><li><a href="http://www.extremeprogramming.org/rules/userstories.html">User-Stories</a>: After we had transformed the informal requirement list into user stories it was relatively easy to estimate it without knowing the details of each story. Even they were written by us developers it was better than working with the initial list.</li><li>Productbacklog: It gave us a very important planning tool, helping us to focus on the near future and driving the development sprint by sprint.</li><li>Sprints: The sprints helped us a lot to get the team and the customer focused on the tasks that needs to be done. Without focusing on the sprints and forgetting a little bit about the whole, we could never have done it.</li><li>Sprintplanning: Without this meeting we wouldn't have any chance to know what to implement in detail. The customer was surprised at the beginning that he had do discuss every detail of its initial requirement list again in the sprint planning.</li><li>Sprintreview: It was often the only opportunity to present our achievements and we always have had valuable feedback from the customer and the future users. Customer and users could get used to our development velocity and that took a lot of pressure away.</li><li>Adoption: The product owner discovered during the first two sprints that he needs to be better prepared for the sprint meetings. He started to consolidate the different opinions in additional meetings prior to the sprint planning.</li><li>Team forming: Event just two out of six developers have worked together before we never had major problems.<br /><strong></strong></li></ul><p><strong>What were the problems? </strong></p><ul><li>Scrummaster / Productowner: The roles were never officially assigned to persons, because the customer was confused in relation to the existing roles and responsibilities (project manager, solution architect and so on). There was also no budget available for 'non-programming' tasks.</li><li>Importance of the Productbacklog: The Productbacklog was built by the developers and was never owned by the product owner! Once it was initially built up it was used by the management to plan the whole year front up! Development was driven by the Productbacklog, but not testing, acceptance and fulfilment of the contract.</li><li>Testing: We couldn’t get things DONE. As the customer didn't test we started to do more functional and system testing. But after one year we do not have any story officially accepted by the customer. But due to the sprint-reviews I'm pretty confident that the customers will accept it after some minor changes.</li><li>Sprint-Retrospectives: the meeting was always held by the team but not attended by the product owner, nor attended by another representative of the management. Therefore just team internal impediments could be addressed and resolved. No organizational impediments were resolved.</li><li>Meetings: Due to the fact that the whole process was not coached by a scrum master, the meetings usually were ineffective and lasted too long. I, as developer and interim scrum master, was too involved to act as a coach for both the team and the customer.</li><li>Responsibility: There were few developers in our team that couldn't follow the process at all. They were not able to catch up the information at the sprint planning nor did they take the responsibility to fulfil the tasks they assigned themselves. We lost a lot of our performance here as senior team members had to coach them. Those weaker developers could not catch up as every thing went far too fast for them. </li></ul><p><strong>Conclusion<br /></strong>I'm still saying that agile development is the best practice I know. In my career as a software developer I sat too many times in my office trying to imagine how I could fulfil some requirements that I didn't understand. Today we have a simple process that brings customer and team together and that's much better for everybody. I'm thinking agile development is a process for people that want to take responsibility. If you don't have people that take responsibility you might be better to follow more heavy weight processes were every thing is predetermined and fixed. But everything you can't foresee will cost you a lot of money! It will cost you much more than the salaries of a good scrum master and good developers.<br /></p>Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-8995878145266667696.post-22317310738391473002008-10-16T13:20:00.032+02:002008-10-16T23:20:21.080+02:00Reflecting about how we implement aggregates<strong>How we implement aggregates</strong><br /><br />Since the beginning of my current project we tried to apply the ideas of structuring our business-logic into <a href="http://domaindrivendesign.org/discussion/messageboardarchive/Aggregates.html">aggregates</a>. We started to implement the aggregates using the following guidelines:<br /><br /><ul><li>define an aggregate root and implement it as a public class</li><li>define the internal classes of an aggregate and implement it as a public class</li><li>implement a repository that can query and return aggregate roots of this class</li><li>try to avoid accessing the internals (like traversing from aggregate root to an internal class) from outside the aggregate</li><li>put as much as possible of the business-logic into the aggregate root</li></ul><p>Following this rules we had some sort of guidelines about where to locate the business-logic and when to implement a repository. I think it was worth to have the aggregates. It was a valuable concept when we had to change our application from a 2-tier to a 3-tier architecture.</p><p>Nevertheless we always had following problems with aggregates:</p><ul><li>Most of the time we had code in the presentation-layer that accessed the internals of an aggregate. It appeared often in case where there was an one-to-one data binding. For instance, in a master-detail view, where the master was the aggregate root an the detail an internal entity of the aggregate. (e.g. editing invoice and invoice position)</li><li>There were relations on the data model that do not comply the aggregate rules. In such a case we often had a nice definition of an aggregate, however there was sometimes a nasty dependency. It happend that an internal entity was depending on another entity in another aggregate. We agreed that this is not bad and that it can be abstracted to a dependency between the two involved aggregates. </li></ul>And what happened:<br /><br /><ul><li>Since the internals could be accessed, the business-logic begun to spread out into the presentation layer. It's impossible always to have the discipline to comply the aggregate rules and all of us violated it from time to time.</li><li>We didn't centralize the creational-logic. The test code is often a mess and it deals with setting-up the aggregates as well the internals of an aggregate.</li><li>A <a href="http://www.ndepend.com/">NDepend</a>-analyse revealed that our business-logic assembly will be a serious maintenance problem (<a href="http://www.hanselman.com/blog/content/binary/NDepend%20metrics%20placemats%201.1.pdf">'Zone of pain'</a>)</li></ul><p><strong>Why is our business-logic in the zone of pain?</strong></p><p>We generally get closer to the '<a href="http://www.hanselman.com/blog/content/binary/NDepend%20metrics%20placemats%201.1.pdf">zone of pain</a>' (see link for details), when a high number of types in an assembly:</p><ol><li>are more concrete than abstract (see Abstractness in the formula)</li><li>are used a lot by other assemblies (see Ca in the formula)</li><li>do not depend on other types (see Ce in the formula)</li></ol><p>Since I can't see any value in implementing business-logic abstract (1.) and our business-logic already depends on a small number of types in other assemblies (2.) the only variable would be to reduce the number of types that are used by other assemblies (3.).</p><p><strong>How could we do it different?</strong></p><p>We could try to better encapsulate the internals of an aggregate avoiding the problems described above. That means, not allowing to access any internals by another type than the aggregate root. This increases the afferent coupling of the aggregate root, on the other hand eliminates the afferent coupling of the internals. The afferent coupling of the business logic assembly itself would then decrease.</p><p>Therefore I transformed one of our aggregates from something like that</p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>// File Invoice.cs<br />public class Invoice<br />{<br /> public EntitySet<InvoicePosition> Positions { get; set; }<br />}<br />public class InvoicePosition<br />{<br />}<br /></code></pre><br />to<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>// File Invoice.cs<br />public partial class Invoice<br />{<br /> private EntitySet<Invoice.InvoicePosition> Positions { get; set; }<br />}<br />// File InvoicePosition.cs<br />public partial class Invoice<br />{<br /> private class InvoicePosition<br /> {<br /> }<br />}<br /></code></pre>After completing the refactoring and changing some logic in the presentation layer I got the following code metrics:<br /><br /><ol><li>The assembly containing the business logic moved a little bit away from the zone of pain (from D=0.577 to 0.575). This is still bad, however the refactoring had a positive effect.</li><li>The type-rank for the refactored aggregate root increased from 10.7 to 12. Ca (Afferent coupling) increased from 62 to 66. That means, it got a more important part of the business logic.</li><li>The CC (cyclomatic complexity) for the aggregate root increased from 38 to 77, while CC decreased generally for the presentation layer (e.g. in one case from 26 to 16). That means that we put complexity into the business logic. It's a good thing since the complexity generally is easier to test and therefore to maintain in the business logic. It was also possible to eliminate duplicated business logic found in the presentation layer.<br /><strong></strong></li></ol><p><strong>Testability and Unittests</strong></p>As the internals are completely hidden from outside now I test the refactored aggregate with state-based<a href="http://de.wikipedia.org/wiki/Black-Box-Test"> black-box tests</a>. I think that's a reasonable way to do it since the test setup do not depend anymore on the implementation details of an aggregate. I'm not sure if this should be a general testing strategy for aggregates. I think there are more complex cases, where white-box tests would still be needed. The following pictures shows on the left, the test-code before the refactoring and on the right, the test-code after:<br /><a href="http://2.bp.blogspot.com/_hcGoxuElMbw/SPdKNEXAVpI/AAAAAAAAACg/1R4I7B5-x0I/s1600-h/TestExample.JPG"><img id="BLOGGER_PHOTO_ID_5257752678347331218" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" height="200" alt="" src="http://2.bp.blogspot.com/_hcGoxuElMbw/SPdKNEXAVpI/AAAAAAAAACg/1R4I7B5-x0I/s400/TestExample.JPG" width="600" border="0" /></a>Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-8995878145266667696.post-44607977541451276552008-07-14T21:18:00.007+02:002008-07-20T19:43:18.391+02:00TDD, Design and TestabilityAfter <a href="http://www.youtube.com/watch?v=r5xPEhSGYS4">being on holiday</a> for a while and being pretty busy at work I want to talk about an upcoming issue at my current project. The issues are<br /><ol><li>Presenter-Logic (<a href="http://martinfowler.com/eaaDev/PassiveScreen.html">Passiv View</a>) is hard to test. It costs a lot of effort and it's difficult to be done right.</li><li>There is code that is not worth being tested. We shouldn't test that code just to have the test coverage increased.</li></ol><p>As a <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> advocate I'm trying to find out what's about those two issues above:</p><strong>1.</strong><a href="http://martinfowler.com/eaaDev/PassiveScreen.html"><strong>Passiv View</strong></a><strong> is hard to test. </strong><br />Let see an example:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>public void EditDienstAbwesenheit()<br />{<br /> var abwesenheit = View.SelectedDienstAbwesenheit; // get selected item from view<br /> if (abwesenheit != null) // if user as selected something<br /> {<br /> IModalDialog dialog;<br /> if(abwesenheit is SpitalAufenthalt) // decide what type of item is selected<br /> { // create a modal dialog for this item type<br /> var presenter = _viewBuilder.Create(_unitOfWork,typeof(ISpitalaufenthaltbearbeitenDialog));<br /> dialog = presenter.View;<br /> }<br /> else<br /> { // creat a modal dialog for the other item type<br /> var presenter = _viewBuilder.Create(_unitOfWork,typeof(IAbwesenheitbearbeitenDialog));<br /> dialog = presenter.View;<br /> }<br /> if (Shell.ShowInModalWorkspace(View, dialog) != DialogResult.OK) // display the modal dialog<br /> {<br /> _unitOfWork.Refresh(abwesenheit); // reload data the might have been modified<br /> }<br /> UpdateView(); // show the modification on the view<br /> }<br />}<br /><br /></code></pre><br />We all know that the more dependencies and responsibilities a method has the more is it hard to test. This is like that because each dependency needs a <a href="http://martinfowler.com/articles/mocksArentStubs.html">mock or stub </a>and each responsibility needs a test-assertion to verify it. The example above has following responsibilities:<br /><ol><li>Get the users selection</li><li>Decide about the next dialog to be shown</li><li>Create the dialog </li><li>Open the dialog in the shell</li><li>Reload to rollback modifications of the dialog</li><li>Present the changes to the users</li></ol><p>To accomplish that tasks we need:</p><ul><li>a View to get the users input</li><li>a Model (called 'abwesenheit') that represent the users input</li><li>a ViewBuilder to create a Dialog</li><li>a Shell to display the Dialog</li><li>a UnitOfWork to rollback the modifications</li></ul><p>So what? Is it a test-problem or a design-problem? I strongly believe that code that can't be tested is poorly designed. The most obvious is that we violate the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsiblity Principle </a>(SRP). Could we split the responsibilities to find methods or even classes to separate the different concerns? </p><p>Lets try:</p><ol><li>Get the users selection -> <em>Lets keep it where it is</em></li><li>Decide about the next dialog to be shown -><strong> </strong><em>Lets put it into a separate method</em></li><li>Create the dialog -><strong> </strong><em>Lets delegate it to another object as creation and displaying a dialog is often used in an application (e.g Application controller)</em></li><li>Open the dialog in the shell -> <em>move it to the Application controller</em></li><li>Reload to undo modifications -><strong> </strong><em>That's wrong here. The dialogs are responsible not to modify data in case they are cancelled!</em></li><li>Present the changes to the users -><em> Lets keep it where it is</em></li></ol><p>And after that minor refactoring:</p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>public void EditDienstAbwesenheit()<br />{<br /> var abwesenheit = View.SelectedDienstAbwesenheit;<br /> if (abwesenheit != null)<br /> {<br /> CreateEditDialog(abwesenheit);<br /> UpdateView();<br /> }<br />}<br />public void CreateEditDialog(DienstAbwesenheit abwesenheit)<br />{<br /> if(abwesenheit is SpitalAufenthalt)<br /> {<br /> _applicationController.ShowInModalWorkSpace(_unitOfWork,typeof(ISpitalAufenthaltBearbeitenDialog));<br /> }<br /> else<br /> {<br /> _applicationController.ShowInModalWorkSpace(_unitOfWork,typeof(IAbwesenheitBearbeitenDialog));<br /> }<br />}<br /></code></pre><br />So is that better? I think yes. In terms of Unit-Testing we reduced responsibility and dependency per unit (method) and we got a cleaner more expressive design.<br /><br /><strong>2. There is code that is not worth being tested</strong><br />Lets see following example:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>public class Person<br />{<br /> public string FamilyName { get; set; }<br /> public string Name { get; set; }<br /> public string Age { get; set; }<br />}<br />public class Address<br />{<br /> public string Code { get; set; }<br /> public string Country { get; set; }<br /> public string Street { get; set; }<br />}<br />/// <summary><br />/// Model<br />/// </summary><br />public class PersonRow<br />{<br /> public PersonRow(Address address, Person person)<br /> {<br /> _address = address;<br /> _person = person;<br /> }<br /><br /> private readonly Person _person;<br /> private readonly Address _address;<br /><br /> public string FamilyName<br /> {<br /> get { return _person.FamilyName; }<br /> }<br /><br /> public string Name<br /> {<br /> get { return _person.Name; }<br /> }<br /><br /> public string Age<br /> {<br /> get { return _person.Age; }<br /> }<br /><br /> public string Code<br /> {<br /> get { return _address.Code; }<br /> }<br /><br /> public string Country<br /> {<br /> get { return _address.Country; }<br /> }<br /><br /> public string Street<br /> {<br /> get { return _address.Street; }<br /> }<br />}<br /><br /></code></pre><br />Is it worth to test that each getter returns the right value? When is it worth to test a piece of code? I could think of following answers:<br /><br /><ol><li>It's worth if something can go wrong</li><li>It's worth if I don't need to put a lot of effort to test it</li><li>It's worth if it's likely to be refactored in future</li></ol><p>The problem with the example above is that little can go wrong (except the mapping) and that the effort is too high to test it. On the other hand as a TDD advocate I'm a little bit annoyed that this little stupid class should lower our test coverage. So what is the way out? </p><ul><li>If this class were not necessary there shouldn't go anything wrong</li><li>If we could reduce the lines of code, less could go wrong and less needs to be tested</li></ul><p>So let's try to introduce a mapper to externalize the mapping:</p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>public class Person<br />{<br /> public string FamilyName { get; set; }<br /> public string Name { get; set; }<br /> public string Age { get; set; }<br />}<br />public class Address<br />{<br /> public string Code { get; set; }<br /> public string Country { get; set; }<br /> public string Street { get; set; }<br />}<br />/// <summary><br />/// Model<br />/// </summary><br />public class PersonRow<br />{<br /> public string PersonFamilyName { get; set; }<br /> public string PersonName { get; set; }<br /> public string PersonAge { get; set; }<br /> public string AddressCode { get; set; }<br /> public string AddressCountry { get; set; }<br /> public string AssressStreet { get; set; }<br />}<br /><br />public void DoTheMapping()<br />{<br /> var person = new Person();<br /> var address = new Address();<br /> var row = new PersonRow();<br /> PropertyMapper.To(row).From(person).From(address).Execute();<br />}<br /></code></pre><br />The idea is to eliminate all the boring mappings to a specialized class PropertyMapper. The PropertyMapper would map the values from person and address to the row combining Classname and Propertyname. Furthermore the method Execute() would throw an exception in case any property of the PersonRow was not initialized with a value. My observations are:<br /><ol><li>The PropertyMapper is difficult to implement, but I think after 10 mappings i have already my return on investment</li><li>Execute() is self-validating, therefore this code can also be run under test</li><li>I split the responsibilities into two classes (PersonRow and PropertyMapper) and I got testability</li><li>The example should be extended to support two way mappings</li><li>Is that too much? </li></ol>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-8097020429064025322008-03-21T17:21:00.007+01:002008-03-21T19:07:46.746+01:00Some thoughts about C# 3.0We have been using the new C#3.0-features for two months and its quite interesting that our code looks in some parts like Jeremy describes in <a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/03/14/c-3-is-like-a-moped.aspx">C#3.0 is like a moped</a>. I wouldn't like to miss the new features and I won't stop using them but I'm thinking it's getting too much.<br /><br />It makes me feel that C# already had it's best time and there should be something new. Where is the new microsoft-ruby-language? C# was a better Java (I mean the language not the community) but where is now the better ruby?Anonymousnoreply@blogger.com2tag:blogger.com,1999:blog-8995878145266667696.post-2643664489507788742008-01-13T08:29:00.000+01:002008-01-13T14:28:11.334+01:00Behind the scences of LINQI always knew that <a href="http://en.wikipedia.org/wiki/LINQ"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">LINQ</span></a> was founded on the idea of <a href="http://en.wikipedia.org/wiki/Monad_%28functional_programming%29"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">monads</span></a> but even trying hard I couldn't understand how <span class="blsp-spelling-error" id="SPELLING_ERROR_2">LINQ</span> and <span class="blsp-spelling-error" id="SPELLING_ERROR_3">monads</span> are related to each other.<br /><br />But <span class="blsp-spelling-corrected" id="SPELLING_ERROR_4">fortunately</span> there is Wes <span class="blsp-spelling-error" id="SPELLING_ERROR_5">Deyer</span> and he describes in <a href="http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx">The Marvels of <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Monads</span></a> what I always wanted to know. It's a pity that <span class="blsp-spelling-error" id="SPELLING_ERROR_7">LINQ</span> was always described and documented as query language rather than as a <span class="blsp-spelling-error" id="SPELLING_ERROR_8">monad</span> extensions. When I look to the <span class="blsp-spelling-error" id="SPELLING_ERROR_9">msdn</span>-documentation there is no hint that I could implement <a href="http://msdn2.microsoft.com/en-us/library/bb394939.aspx#standardqueryops_topic4">query operators</a> on other types than <span class="blsp-spelling-error" id="SPELLING_ERROR_10">IEnumerable</span><t> and <span class="blsp-spelling-error" id="SPELLING_ERROR_11">IQueryable</span><t>.<br /><br />But that's exactly what Wes is doing. He sees a more general <span class="blsp-spelling-corrected" id="SPELLING_ERROR_12">concept</span> and he shows a way to implement the query operators on any type. In fact this is for me a huge step and leads us to a new level of abstraction where <span class="blsp-spelling-error" id="SPELLING_ERROR_13">LINQ</span> (as a list-<span class="blsp-spelling-error" id="SPELLING_ERROR_14">monad</span>) seems to be a specific case of a <span class="blsp-spelling-error" id="SPELLING_ERROR_15">monad</span>.<br /><br />My preferred way to use LINQ was the <a href="http://msdn2.microsoft.com/de-de/library/bb397947.aspx">method syntax</a> as I thought this is the more general case. But now, after knowing that the query syntax is something like a monad extension I start to like it.Anonymousnoreply@blogger.com5tag:blogger.com,1999:blog-8995878145266667696.post-42279108353880933822007-12-29T14:46:00.000+01:002007-12-29T16:01:03.353+01:00Playing around with NBehave<a href="http://enceradeira.blogspot.com/2007/12/evaluating-dependency-injection.html">As I said recently</a> I'm still exploring tdd and its capabilities. The next evolutionary step could be <a href="http://en.wikipedia.org/wiki/Behavior_driven_development">bdd</a>. Therefore I downloaded <a href="http://nbehave.org/">NBehave</a> and I tried to write one story with it. <a href="http://martinfowler.com/eaaDev/PassiveScreen.html">Passive View</a> is my preferred playground and thats how it goes with NBehave and <a href="http://www.typemock.com/">TypeMock.NET</a>:<br /><br />First the declaration of the View, the Presenter and a Service-Gateway that is used by the Presenter to retrieve some information.<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>protected IView _view;<br />protected Presenter _presenter;<br />protected EventHandler _updateRequestedEvent;<br />protected IServiceGateway _serviceGatway;<br /></code></pre><p>The setup of the this objects is not showed here. It simples instantiates mocks for the View and the ServiceGateway and injects it into the Presenter using <a href="http://martinfowler.com/articles/injection.html">Constructor-Injection</a>. The _updateRequestedEvent is a mocked event on the view and is also used later in the example.</p><p>First I have to specify a story. This is done like that: </p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[TestFixtureSetUp]<br />public void FixtureSetup()<br />{<br /> _getCurrentTimeStory = new Story("Getting the current service time");<br /> _getCurrentTimeStory.AsA("User").IWant("to update the displayed current time") <br /> .SoThat("I can see what time is on the serivce side");<br />}<br /></code></pre><p></p><p>And that's one scenario that came in my mind:</p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>[Test]<br />public void HelloNTServiceIsNotAvailable()<br />{<br /> using (RecordExpectations recorder = RecorderManager.StartRecording())<br /> {<br /> _view.ShowMessageBox("The Service is currently not available");<br /> recorder.CheckArguments();<br /> }<br /> _getCurrentTimeStory.WithScenario("Service is not available")<br /> .Given("the Service returns an exception", new Exception("Error"), e =><br /> {<br /> using (RecordExpectations recorder = RecorderManager.StartRecording))<br /> {<br /> recorder.ExpectAndThrow(_serviceGatway.GetTime(), e);<br /> }<br /> })<br /> .When("I update the current time", () => _updateRequestedEvent(this, EventArgs.Empty))<br /> .Then("a message box should display", "The Service is currently not available", m =><br /> {<br /> MockManager.Verify();<br /> })<br /> ;<br />}<br /></code></pre><p>Looks quite chaotic and a developer not used to NUnit,TypeMock and NBehave might not understand it at first glance. I also think the combination of NUnit,TypeMock and NBehave is a little bit strange as they do not integrate very well. Maybe there is another way how to combine those frameworks?<br /></p><p>But what I like is the overall structure that it gives to the tests and the readable test output that can be interpreted by a <a href="http://www.scrumforteamsystem.com/ProcessGuidance/Roles/ProductOwner.html">product owner</a>. Here are now the scenario above and another scenario that I could present to him:</p><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>Story: Getting the current service time<br /><br />Narrative:<br />As a User<br />I want to update the displayed current time<br />So that I can see what time is on the serivce side<br /><br />Scenario 1: Service is not available<br />Given the Service returns an exception: System.Exception: Error<br />When I update the current time<br />Then a message box should display: The Service is currently not available<br /><br />Scenario 2: Service is available<br />Given the Service returns the time: 01.01.2000 12:24:23<br />When I update the current time<br />Then the label on the view should display: 12:24<br /></code></pre>Anonymousnoreply@blogger.com4tag:blogger.com,1999:blog-8995878145266667696.post-53674832742760688522007-12-16T18:04:00.000+01:002007-12-29T14:50:38.604+01:00Evaluating a dependency injection frameworkI heard the first time about <a href="http://en.wikipedia.org/wiki/Test-driven_development">tdd</a> in the year 2002 when a colleague of mine introduced me to a tool called 'NUnit'. I found tdd very helpful from the beginning and I was always one of them that pushed that paradigm and mindset. I learned like a lot of the other tdd enthusiasts, that 'test first' is good, that 'test isolation' is really necessary, that a 'mocking framework' helps a lot, and that it's all about a good design. On this journey I'm now at a point where I question: <strong>could a 'dependency injection framework' help?</strong><br /><strong></strong><br />That is what I tried to find out today and what this post is about. I wrote a simple application including: <ul><li>a <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation">wpf client</a> with one window called Window1</li><li>a <a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation">wcf service</a> called Service with one Methode GetDate() that returns the current date and time</li><li>one assembly testing the wpf-presentation and wcf-service (just unit-tests)</li></ul><p><strong>Introducing a DI-Framework</strong></p><p>One trying to write tests in such an environment knows that integrating the real wpf- and wcf-environment into the tests is a bad idea. Instead it's better to <a href="http://martinfowler.com/articles/mocksArentStubs.html">stub and mock</a> those environments to get easier, more stable, and faster tests. This means we usually want a test-configuration where the most external dependencies (like wpf or wcf) are mocks or stubs. On the other hand we want to have a configuration on a deployed system that utilizes the real dependencies. So it's something about configuration and that's where the DI-frameworks come into play. </p><p>I decided to give Jeremy's <a href="http://structuremap.sourceforge.net/Default.htm">StructureMap</a> a try because it doesn't look so overloaded like <a href="http://www.springframework.net/">Sprint.NET</a> or <a href="http://www.castleproject.org/container/index.html">Windsor</a>. </p><p>Following code shows my wcf-service IService that I include in the presentation-layer as a Service-Gateway (see also <a href="http://martinfowler.com/eaaCatalog/serviceStub.html">ServiceStub-Pattern</a>): </p><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code><br /> [ServiceContract]<br /> public interface IService<br /> {<br /> [OperationContract]<br /> DateTime GetTime();<br /> }<br /> /// <summary><br /> /// Gateway to intercept for testing<br /> /// </summary><br /> public interface IServiceGateway : IService<br /> {<br /> void Close();<br /> }<br /> /// <summary><br /> /// Real gateway using the wcf generated ServiceClient class<br /> /// </summary><br /> public class ServiceGateway : IServiceGateway<br /> {<br /> private readonly ServiceClient _service;<br /><br /> public ServiceGateway()<br /> {<br /> _service = new ServiceClient();<br /> }<br /><br /> public void Close()<br /> {<br /> _service.Close();<br /> }<br /><br /> public DateTime GetTime()<br /> {<br /> return _service.GetTime();<br /> }<br /> }<br /> /// <summary><br /> /// Stub for testing<br /> /// </summary><br /> public class ServiceGatewayStub : IServiceGateway<br /> {<br /> public void Close()<br /> {<br /> }<br /><br /> public DateTime GetTime()<br /> {<br /> return new DateTime(2000, 1, 1, 12, 34, 55, 12);<br /> }<br /> }<br /></code></pre><strong>Step 1:</strong><br />Using the following code to resolve the reference to the external wcf-service<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code>IServiceGateway gateway = ObjectFactory.GetInstance<IServiceGateway>()<br /></code></pre>and using the following configuration for the tests<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code><StructureMap><br /> <DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTService.ServiceGatewayStub,HelloNTTests" Scope="Singleton"/><br /></StructureMap><br /></code></pre>I could wire the code during the tests to the ServiceGatewayStub instead of the real ServiceGateway.<br /><br /><strong>Step 2:</strong><br />I didn't like that because it meant that we have to setup a configuration for the real (not test) environment like:<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code><StructureMap><br /> <DefaultInstance PluginType="HelloNTPresentation.IServiceGateway,HelloNTPresentation" PluggedType="HelloNTPresentation.ServiceGateway,HelloNTPresentation" Scope="Singleton"/><br /></StructureMap><br /></code></pre>After I have had read <a href="http://www.ayende.com/Blog/archive/2007/10/20/Building-an-IoC-container-in-15-lines-of-code.aspx">how to build an IoC container in 15 lines of code</a> I thought that DI can't be so difficult and I tried to build my own DI-framework. I liked very much that I could configure the DI in the code now and eliminate the file-based configuration:<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> ObjectFactory.Register<IServiceGateway>(() => new ServiceGatewayStub());<br /> IServiceGateway gateway = ObjectFactory.Create<IServiceGateway>();<br /></code></pre>All tests were green and I was happy to start the refactored sample application first time after. But there was big surprise when it crashed. I had forgotten to configure DI for the wcf-service and wpf-service. But where should I put that configuration? Both of them run in some kind of hosted environment and I wasn't able to find a nice place to put that configuration-code. So I realized that it's a little bit harder than I thought to write an own DI-Framework.<br /><br /><strong>Step 3:</strong><br />Back to StructureMap I found a way to minimize the file-based configuration. The solution was to use the attributes PluginFamily and Pluggable that define default behaviour. In this case the class ServiceGateway is the default implementation of IServiceGateway and there is no need to configure it for the wcf-service and the wpf-client anymore.<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> [ServiceContract]<br /> public interface IService<br /> {<br /> [OperationContract]<br /> DateTime GetTime();<br /> }<br /> [PluginFamily("ServiceGateway")]<br /> public interface IServiceGateway : IService<br /> {<br /> }<br /> [Pluggable("ServiceGateway")]<br /> public class ServiceGateway : IServiceGateway<br /> {<br /> }<br /></code></pre><strong>Step 4: </strong><br />Now let's have a look to following the <a href="http://martinfowler.com/eaaDev/PassiveScreen.html">presenter</a> (presenter is what is responsible for the presentation-logic):<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> public class Presenter: IDisposable<br /> {<br /> readonly IView _view;<br /> readonly IServiceGateway _service;<br /><br /> public Presenter(IView view, IServiceGateway service)<br /> {<br /> _view = view;<br /> _service = service;<br /> }<br /> }<br /></code></pre>That presenter shows all internal dependencies on its constructor. This enables us to use <a href="http://martinfowler.com/articles/injection.html">constructor injection</a> when writing tests with a Mock-Framework (e.g. <a href="http://www.typemock.com/">TypeMock</a>)<br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> _serviceGatway = RecorderManager.CreateMockedObject<IServiceGateway>();<br /> _view = RecorderManager.CreateMockedObject<IView>();<br /> _presenter = new Presenter(_view, _serviceGatway);<br /></code></pre>But what's about the others that don't want to bother about providing those dependencies to the constructor? And that's where the DI-framework gets really valueable because it enables us to instantiate concrete classes without providing the needed arguments to the constructor. Following code is from the wpf-client and shows how this is done:<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> Presenter presenter = ObjectFactory.FillDependencies<Presenter>();<br /></code></pre>Just for completeness, I have to mention how I configured IView:<br /><br /><pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"><code> [PluginFamily("Window1")]<br /> public interface IView<br /> {<br /> }<br /> [Pluggable("Window1")]<br /> public partial class Window1 : Window, IView<br /> {<br /> }<br /></code></pre><strong>Summary</strong><br /><br /><ul><li>I always used constructor injection but with a DI-framework it gets easier because the client code doesn't need to manage the dependencies anymore. </li><li>I like StructureMap because it looks simple and it works.</li></ul>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-70271067825748649862007-12-11T21:07:00.000+01:002007-12-11T21:53:08.544+01:00Offline data synchronizationI wrote a few days before that it looked like I would get involved in a <span class="blsp-spelling-error" id="SPELLING_ERROR_0">SOA</span>-project. Today it looks like I will get involved in another project! This new project could have following technical characteristics:<br /><ul><li>said to be a rich-client-project </li><li>support for offline disconnected scenarios (offline agents)</li><li>distributed application (<span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">Internet</span>, intranet or some kind of private network)</li><li>integration with a <span class="blsp-spelling-corrected" id="SPELLING_ERROR_2">backend</span> system (no idea what kind of interface that would be)</li></ul><p>Sounds interesting .... So I bought yesterday <a href="http://books.google.ch/books?id=fWTHHwAACAAJ&dq=Pro+WPF+in+2008">something about <span class="blsp-spelling-error" id="SPELLING_ERROR_3">WPF</span></a> to update myself with 'state of the art rich client development'.</p><p>Maybe the new <a href="http://msdn2.microsoft.com/en-us/sync/bb736752.aspx">Microsoft <span class="blsp-spelling-error" id="SPELLING_ERROR_4">Synch</span> Framework </a>could be interesting in that context too. I watched <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=347021">this </a>and it looks promising. I have to admit that I hate that kind of presentations but it looks that it's <span class="blsp-spelling-corrected" id="SPELLING_ERROR_5">flexible</span> and can be extended. I'm not yet sure about that but at least the synch-runtime can be instantiated in a object-oriented manner and that's always a good sign. Would be great if it could be connected to a <a href="http://en.wikipedia.org/wiki/Service_%28systems_architecture%29">service </a>instead of a database.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-89021960546465741902007-12-09T17:11:00.000+01:002007-12-09T19:51:06.220+01:00WCF puts all togetherI was supposed to get involved into a <a href="http://en.wikipedia.org/wiki/Service-oriented_architecture">SOA</a>-project therefore I started to read about <a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation">WCF</a>. In the meanwhile it turned out that I might not be involved in that project, however I kept on doing my reading on this issue. I went through the following two books:<br /><br /><ul><br /><li><a href="http://books.google.ch/books?id=fDykmoWpjzEC&dq=pro+wcf&pg=PP1&ots=XV8TVpcdAr&sig=GOpAv6CEJUBusNCHU1iXI-q9i84&prev=http://www.google.ch/search?hl=de&q=PRO+WCF&sa=X&oi=print&ct=title&cad=one-book-with-thumbnail">Pro WCF Practical Microsoft SOA Implementation</a> was a good introduction with a lot of code and examples. I liked it as a brief introduction into how WCF 'feels like'. But I switched to the other book soon after since I got more interested in the overall concepts than in the details.</li><br /><li>I liked <a href="http://books.google.ch/books?id=DW2ldput788C&printsec=frontcover&dq=Programming+WCF+Services&sig=hfwpB4MTqSOLYTl4FAviSh_RFZo">Programming WCF Services</a> because it talks in more details about advanced stuff like Instance Management, Faults, Transactions, Concurrency and Security.<br /></li></ul><p>Below is what I think about WCF: I think theres is nothing new but that all comes together in a nice consistent way. WCF helps much if an application is more than a monolithic web or rich-client application. I'd like to mention two personal highlights:</p><ul><br /><li><strong>Hosting:</strong> An WCF service can be hosted inprocess, as a <a href="http://en.wikipedia.org/wiki/Windows_service">windows-service</a>, as a console-application or on the <a href="http://en.wikipedia.org/wiki/Internet_Information_Services">IIS</a>.</li><br /><li><strong>.NET Integration: </strong>Full integration with standard .NET mechanisms like the <a href="http://msdn2.microsoft.com/de-de/library/system.security.aspx">System.Security</a>, <a href="http://msdn2.microsoft.com/de-de/library/system.transactions(VS.80).aspx">System.Transaction</a>, <a href="http://msdn2.microsoft.com/en-gb/library/system.threading(VS.80).aspx">System.Threading</a>-Namespaces. </li></ul><br /><p></p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-25989926760483079932007-12-01T17:30:00.000+01:002007-12-02T09:07:00.847+01:00excpetion handling could be easyWe have been doing a major <span class="blsp-spelling-error" id="SPELLING_ERROR_0">refactoring</span> in our project trying to get rid of the legacy exception handling. As we went through our code we had some good laughs (we shouldn't have <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">laughed</span> as we still have to maintain that for a long time) and it was <span class="blsp-spelling-corrected" id="SPELLING_ERROR_2">obvious</span> that some developers had no clue about how to deal with exceptions or were too lazy to implement a more sophisticated handling. It seemed that some developers didn't miss any <span class="blsp-spelling-corrected" id="SPELLING_ERROR_3">opportunity</span> to get rid of that nasty exceptions. It <span class="blsp-spelling-corrected" id="SPELLING_ERROR_4">seemed</span> that we were fighting a .NET-bug called 'Exception'.<br /><br />We also had a lot of discussons about exceptions, especially because we wanted to eliminate <a href="http://grabbagoft.blogspot.com/2007/06/swallowing-exceptions-is-hazardous-to.html">exception swallowing</a> but not to change the user experience! Our product manager stated that it's better to have an obscure behaviour that the users knows than a new fancy error dialog that indicates problems at the root. (Users don't like <a href="http://en.wikipedia.org/wiki/Fail-fast">fail fast</a>!)<br /><br />I didn't want to talk about that stuff but I have just come across some similar thoughts:<br /><br /><a href="http://grabbagoft.blogspot.com/2007/11/stop-madness.html">http://grabbagoft.blogspot.com/2007/11/stop-madness.html</a> (see Try Catch Publish Swallow)<br /><a href="http://grabbagoft.blogspot.com/2007/06/swallowing-exceptions-is-hazardous-to.html">http://grabbagoft.blogspot.com/2007/06/swallowing-exceptions-is-hazardous-to.html</a><br /><a href="http://grabbagoft.blogspot.com/2007/06/re-throwing-exceptions.html">http://grabbagoft.blogspot.com/2007/06/re-throwing-exceptions.html</a>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-8995878145266667696.post-62323581224225352162007-11-27T21:41:00.000+01:002007-12-09T18:20:29.527+01:00consistency, integrity and exceptionsI was blaming myself today talking about consistency and integrity without remembering the exact definitions of it. I just remembered that there are some interesting differences between them. What I meant was a definition like <a href="http://en.wikipedia.org/wiki/Data_consistency">Consistency</a> and <a href="http://en.wikipedia.org/wiki/Data_integrity">Integrity</a>.<br /><br />My point was that exception handling and especially the concept of <a href="http://en.wikipedia.org/wiki/Design_by_contract">design by contract</a> could be seen in a similar context. I tried to argue that violating a <a href="http://en.wikipedia.org/wiki/Design_by_contract">design by contract</a>-rule(<span class="blsp-spelling-error" id="SPELLING_ERROR_0">pre</span>/post/invariance) is like violating the 'programs internal consistency'.<br /><br />But as <a href="http://en.wikipedia.org/wiki/Data_consistency">Consistency</a> and <a href="http://en.wikipedia.org/wiki/Data_integrity">Integrity</a> is just clearly defined in the context of data it seems that my <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">derivation</span> doesn't make sense.<br /><br />In personally would say a 'program consistency' is maintained as long it's internal state doesn't contain any contradictions. Furthermore a 'program integrity' is maintained as long as the programs internal state does reproduce all related external state correctly.<br /><br />Following that definition one could say that 'program consistency' can be checked by the <a href="http://en.wikipedia.org/wiki/Design_by_contract">design by contract</a>-technique but 'program integrity' cannot. 'program integrity' cannot be checked at all by a program.Anonymousnoreply@blogger.com0