<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkEAR3Y9eCp7ImA9WhRSFUg.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798</id><updated>2011-11-17T21:37:26.860+02:00</updated><category term="Personal" /><category term="Anti-Patterns" /><category term="Software Craftsmanship" /><category term="C++/CLI" /><category term="Peopleware" /><category term="Development" /><category term="Agile" /><category term="Design Patterns" /><category term="Refactoring" /><category term=".NET" /><title>Uri Lavi</title><subtitle type="html">On Software using Refactoring, Design &amp;amp; Agile methods.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://urilavi.blogspot.com/" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/BloggerUriLavi" /><feedburner:info uri="bloggerurilavi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;C0ICSHY5eCp7ImA9WhZQGUo.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3161916454690460749</id><published>2011-04-28T09:19:00.001+03:00</published><updated>2011-04-28T09:19:29.820+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T09:19:29.820+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Personal" /><title>Good Values Pay Off</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
To simply put, we have been acquired!&lt;br /&gt;
For the past couple of years we have been working hard to enhance our technological solutions, the de facto: scalable, near exact match,&amp;nbsp;visual search engine.&amp;nbsp;Using this visual search engine as a backbone, allowed us to envision and to develop many of our great products.&lt;br /&gt;
&lt;br /&gt;
Not surprisingly, &lt;a href="http://www.picscout.com/" target="_blank" title="PicScout"&gt;PicScout&lt;/a&gt; not only became the market leader in&amp;nbsp;the image copyright solutions, but also provided unique solutions in the terms of crediting every image on the web.&lt;br /&gt;
&lt;br /&gt;
On a personal note; Serving as a VP R&amp;amp;D during this time, building the architecture, driving the technology and working with the&amp;nbsp;greatest team ever - was remarkable and enjoyable. I am happy to be a part of a great team where professionalism matters and which&amp;nbsp;employs many of the &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/tags/Software+Craftsmanship/default.aspx" target="_blank" title="Software Craftsmanship"&gt;Software Craftsmanship&lt;/a&gt; values, I so deeply encourage!&lt;br /&gt;
&lt;br /&gt;
A few moments ago, we have &lt;a href="http://blog.picscout.com/2011/04/27/picscout-acquired-by-getty-images/" target="_blank" title="PicScout acquired by Getty Images"&gt;officially announced&lt;/a&gt; that we (&lt;a href="http://www.picscout.com/" target="_blank" title="PicScout"&gt;PicScout&lt;/a&gt;) have been acquired by &lt;a href="http://www.gettyimages.com/" target="_blank" title="Getty Images"&gt;Getty&lt;br /&gt;
Images&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I am sure that our unique technological value will continue to benefit to the world of images.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3161916454690460749?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/IU5Gkc30OHg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3161916454690460749/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2011/04/good-values-pay-off.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3161916454690460749?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3161916454690460749?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/IU5Gkc30OHg/good-values-pay-off.html" title="Good Values Pay Off" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2011/04/good-values-pay-off.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMDSHY8eip7ImA9Wx9bFUo.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-4930591470321237410</id><published>2011-02-24T20:51:00.000+02:00</published><updated>2011-02-24T20:51:19.872+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-24T20:51:19.872+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><title>One small step for a man, one giant leap for mankind</title><content type="html">&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 15px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: small; line-height: normal;"&gt;(Cross post from&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: small; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: small; line-height: normal;"&gt;&lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;Lately I had a lot of thoughts about how to introduce a change within an organization.&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;For a while now I am giving some talks about leading a software development team, focusing each time on a different facet, such as: Quality, Architecture, Recruitment Process and etc...&lt;br /&gt;
(I have combined some of those thoughts into a short lecture, which I entitled&amp;nbsp;&lt;a href="http://www.iltechtalks.org.il/home/talks/fosteringsoftwarecraftsmanship" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Fostering Software Craftsmanship (or How to Build Successful Teams)"&gt;Fostering Software Craftsmanship (Building Successful Teams)&lt;/a&gt;&amp;nbsp;and it is given as a part of the&amp;nbsp;&lt;a href="http://www.iltechtalks.org.il/" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="IL Tech Talks"&gt;IL Tech Talks&lt;/a&gt;).&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;But here is a&amp;nbsp;&lt;strong&gt;phenomena&lt;/strong&gt;, I encounter each time.&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;Most of the audience understand the importance of the concepts,&amp;nbsp;&lt;strong&gt;but really struggle with introducing them to their organization&lt;/strong&gt;.&lt;/div&gt;&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://farm4.static.flickr.com/3247/2896848546_1379570780_m.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://farm4.static.flickr.com/3247/2896848546_1379570780_m.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #666666; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 14px;"&gt;&lt;strong class="username" id="yui_3_3_0_1_1298572687689759" style="color: #222222; display: block; font-size: 13px; font-style: normal; font-weight: normal; line-height: 13px; margin-top: 0px;"&gt;&lt;a href="http://www.flickr.com/photos/teflon/" style="color: #0063dc; text-decoration: none;"&gt;Martin Deutsch&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;ul&gt;&lt;li&gt;Writing Unit Tests will lengthen my development time!&lt;/li&gt;
&lt;li&gt;How much time should I "reserve" for doing Refactoring?&lt;/li&gt;
&lt;li&gt;How do I explain to my manager that Refactoring is important?&lt;/li&gt;
&lt;li&gt;Code Reviews are difficult, because people have different tastes!&lt;/li&gt;
&lt;li&gt;Code Reviews are taking too long! We will not be given the time to do it, ever!&lt;/li&gt;
&lt;li&gt;Continuous Integration will take a few weeks to accomplish. I won't be given any time to do it in the near feature!&lt;/li&gt;
&lt;li&gt;Those concepts are great, but the time to do them should be allocated by the management.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;I am sure we all heard those sayings. Heck, we even have given those once! (No... Not really :) )&lt;br /&gt;
&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;Though I have a lot to say and comment about each and every one of the above statements - there are some broader aspects I must cover first.&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;We all hate changes, don't we? Doing Unit Tests, investing our time in Refactoring (or Builds) - those are just an extra activities that we have never done (or done correctly).&lt;br /&gt;
One should really invest his own time in order to polish those activities and doing so is just recognizing that we need to change. As humans, we find it extremely difficult to accept changes.&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Jack_Welch" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Jack Welch"&gt;Jack Welch&lt;/a&gt;&amp;nbsp;understood it perfectly, but nevertheless he succeeded to introduce a lot of changes to GE.&amp;nbsp;&lt;a href="http://books.google.com/books?id=mhxTakHN--4C&amp;amp;pg=PA17&amp;amp;lpg=PA17&amp;amp;dq=jack+welch+embrace+the+change&amp;amp;source=bl&amp;amp;ots=PswysecCuq&amp;amp;sig=jfnCsdEelw3niIuXREopftC7viw&amp;amp;hl=en&amp;amp;ei=TR4iTYWHD5KL4gaOmrCGAg&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=2&amp;amp;sqi=2&amp;amp;ved=0CBwQ6AEwAQ#v=onepage&amp;amp;q=jack%20welch%20embrace%20the%20change&amp;amp;f=false" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Jack Welch and the GE Way"&gt;Jack Welch found the change to be exciting, daring and imaginative&lt;/a&gt;.&lt;br /&gt;
GE success can be rooted to its ability to change and to change fast.&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;However, applying change in the simplest way doesn't work.&lt;br /&gt;
We cannot accept the change all at once.&amp;nbsp;&lt;strong style="color: #009500; font-size: 14px;"&gt;Evolution takes its time&lt;/strong&gt;; Therefore, in order to accept the change we also should adapt&amp;nbsp;&lt;strong&gt;one step after another&lt;/strong&gt;.&lt;br /&gt;
(It's really like Refactoring Steps: One small change at a time, compile and test).&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;Sometimes it takes&amp;nbsp;&lt;strong&gt;&lt;span style="font-size: 14px;"&gt;&lt;span style="color: #d90000;"&gt;&lt;strong&gt;&lt;span style="font-size: 17px;"&gt;years&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&amp;nbsp;to introduce all those concepts to your teams:&lt;br /&gt;
Start by a simple task, like code conventions or source control layout, then teach unit tests and invest in teaching&amp;nbsp;&lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2011/01/03/code-smells.aspx" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Code Smells"&gt;code smells&lt;/a&gt;, continue by applying rigor&lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2010/09/30/effective-code-review-a-presentation.aspx" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Effective Code Reviews"&gt;Code Reviews&lt;/a&gt;&amp;nbsp;and etc... and etc...&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;Doing everything in one big bang just doesn't work. I have seen several teams that got introduced to Scrum or TDD in a matter of weeks. Those are big changes to somebody who didn't evolve to the "right" point. Needless to say that the failures that those teams experienced were so discouraging that till now some of those Software Engineers hate TDD and claim that Unit Tests (even not TDD) are plain waste of their time.&lt;/div&gt;&lt;div style="margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;You shouldn't be surprised that applying all the great concepts to your organization will take years.&lt;br /&gt;
One step after another; One small step for a Software Engineer, one giant leap for an Organization.&lt;/div&gt;&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://www.nasaimages.org/download.php?mid=nasaNAS~9~9~59354~163200&amp;amp;file=6900947.jpg&amp;amp;src=http%3A%2F%2Fmm04.nasaimages.org%2FMediaManager%2Fsrvr%3Fmediafile%3D%2FSize3%2FnasaNAS-9-NA%2F61325%2F6900947.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="314" src="http://www.nasaimages.org/download.php?mid=nasaNAS~9~9~59354~163200&amp;amp;file=6900947.jpg&amp;amp;src=http%3A%2F%2Fmm04.nasaimages.org%2FMediaManager%2Fsrvr%3Fmediafile%3D%2FSize3%2FnasaNAS-9-NA%2F61325%2F6900947.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #474b45; font-family: Verdana, Tahoma, Arial, Helvetica; font-size: 10px;"&gt;&lt;a href="http://www.nasaimages.org/luna/servlet/detail/nasaNAS~9~9~59354~163200:"&gt;Close-up of Astronaut?s Foot on Lunar Surface - NASA Images&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-4930591470321237410?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/FlRicMIone0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/4930591470321237410/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2011/02/one-small-step-for-man-one-giant-leap.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4930591470321237410?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4930591470321237410?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/FlRicMIone0/one-small-step-for-man-one-giant-leap.html" title="One small step for a man, one giant leap for mankind" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm4.static.flickr.com/3247/2896848546_1379570780_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2011/02/one-small-step-for-man-one-giant-leap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUADSHk6cCp7ImA9Wx9XEEo.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-5743707846883570185</id><published>2011-01-03T16:09:00.001+02:00</published><updated>2011-01-03T20:02:59.718+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-03T20:02:59.718+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Craftsmanship" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Anti-Patterns" /><title>Code Smells</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
If you like practicing in identifying code smells, then you can find below a short &lt;span style="color: blue;"&gt;class&lt;/span&gt; called&lt;br /&gt;
&lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper" style="background: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; color: black; font-family: Courier New; font-size: 12pt; max-height: 600px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; width: 97.5%;"&gt;&lt;pre class="csharpcode" id="codeSnippet" xml:space="preserve"&gt;&lt;span style="color: blue;"&gt;public class&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt;
{
    &lt;span style="color: blue;"&gt;public delegate void&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt;(&lt;span style="color: blue;"&gt;object&lt;/span&gt; data);
    &lt;span style="color: blue;"&gt;private static readonly object&lt;/span&gt; _sync = new &lt;span style="color: blue;"&gt;object&lt;/span&gt;();
    &lt;span style="color: blue;"&gt;private readonly&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;, &lt;span style="color: #338c7e;"&gt;Timer&lt;/span&gt;&amp;gt; timers = new &lt;span style="color: #338c7e;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;, &lt;span style="color: #338c7e;"&gt;Timer&lt;/span&gt;&amp;gt;();
    &lt;span style="color: blue;"&gt;private readonly&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;, &lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt;&amp;gt; callbacks = new &lt;span style="color: #338c7e;"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;, &lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt;&amp;gt;();

     public void SetTimeout(&lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt; timerCallback, &lt;span style="color: blue;"&gt;int&lt;/span&gt; snooze)
     {
            &lt;span style="color: blue;"&gt;var&lt;/span&gt; timer = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;Timer&lt;/span&gt;(snooze);
            &lt;span style="color: blue;"&gt;lock&lt;/span&gt; (_sync)
            {
               timers.Add(timer.GetHashCode(), timer);
               callbacks.Add(timer.GetHashCode(),
               x =&amp;gt;
               {
                  &lt;span style="color: blue;"&gt;lock&lt;/span&gt; (_sync)
                  {
                     &lt;span style="color: blue;"&gt;var&lt;/span&gt; t = timers[x.GetHashCode()];
                     t.Stop();
                     t.Close();
                     timers.Remove(x.GetHashCode());
                     callbacks.Remove(x.GetHashCode());
                  }
                  &lt;span style="color: green;"&gt;// invoke function provided by caller&lt;/span&gt;
                  timerCallback(null);
                });
            }
            timer.Elapsed += timer_Elapsed;
            timer.AutoReset = false;
            timer.Start();
      }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
Here are some Code Smells, that can be identified:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt; (a weak smell) - Everything that is called a manager alerts me a great deal.&lt;br /&gt;
Usually managers are &lt;a href="http://en.wikipedia.org/wiki/God_object" target="_blank" title="God Objects"&gt;God objects&lt;/a&gt;, have low&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank" title="Cohesion"&gt;cohesion&lt;/a&gt; and high &lt;a href="http://en.wikipedia.org/wiki/Coupling_(computer_programming)" target="_blank" title="Coupling"&gt;coupling&lt;/a&gt; and violating too much&lt;br /&gt;
OO principles...&lt;br /&gt;
It doesn't necessary mean that the same happens here, but it should be noted and then verified in the code.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt; should be generic or restricted by a Data Type.&lt;br /&gt;
It's better to specialize the &lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt; with more concrete type parameter. Having said&lt;br /&gt;
that, it might be that the author wanted to use the built in &lt;span style="color: #338c7e;"&gt;TimerCallback&lt;/span&gt; in .NET.&lt;br /&gt;
In such a case the declaration is redundant.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt; _sync object.&lt;br /&gt;
The class has only instance members, besides that _sync object; Will it make sense to do the following?&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; color: black; font-family: Courier New; font-size: 12pt; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; width: 97.5%;"&gt;&lt;pre class="csharpcode" id="codeSnippet" xml:space="preserve"&gt;&lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt; timerManager1 = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt;();
timerManager1.SetTimeout(...);
... 
&lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt; timerManager2 = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #338c7e;"&gt;TimerManager&lt;/span&gt;();
&lt;span style="color: green;"&gt;// here timerManager2 will block on the same object as the timerManager1&lt;/span&gt;
timerManager2.SetTimeout(...);
&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Both Dictionaries are just plain procedural programming definitions; It is the same like having 2 arrays aligned by their indexes as&amp;nbsp;both the dictionaries will be accessed by the same index (an &lt;span style="color: blue;"&gt;int&lt;/span&gt;).&amp;nbsp;Behold, as one mistake (accessing the wrong index) can lead this code to an undefined behavior.&lt;/li&gt;
&lt;li&gt;GetHashCode shouldn't be used to identify uniquely an object.&lt;br /&gt;
Let me repeat again... GetHashCode &lt;strong&gt;mustn't&lt;/strong&gt; be used &lt;strong&gt;to identify uniquely&lt;/strong&gt; an object...&lt;br /&gt;
GetHashCode's implementation is needed for collections (and Equals, see below).&lt;br /&gt;
Sometimes the same result of the hash code will put two different objects in the same hush bucket - which means those are not unique&amp;nbsp;identifiers!!!&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Once implementing &lt;a href="http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx" target="_blank" title="GetHashCode and Equals"&gt;GetHashCode, the Equals method&lt;/a&gt; should be implemented as well.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Consider the follwoing code:&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; color: black; font-family: Courier New; font-size: 12pt; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; width: 97.5%;"&gt;&lt;pre class="csharpcode" id="codeSnippet" xml:space="preserve"&gt;t.Stop();
t.Close();
&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;One should be familiar with the tools at the hand.&lt;br /&gt;
Close() does what Stop() do and more... Calling Stop() and then Close() just makes the method a little bit longer without any effect.&lt;br /&gt;
When in doubt, consider to take a few moments just to review the provided API.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Redundant Remark.&lt;br /&gt;
The remark repeats the code, doesn't bring anything informative enough and affects the length of the method.&lt;br /&gt;
It can be safely removed.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; color: black; font-family: Courier New; font-size: 12pt; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; width: 97.5%;"&gt;&lt;pre class="csharpcode" id="codeSnippet" xml:space="preserve"&gt;&lt;span style="color: green;"&gt;// invoke function provided by caller&lt;/span&gt;
timerCallback(null);
&lt;/pre&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;div style="text-align: -webkit-auto;"&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: normal; line-height: 15px;"&gt;Thanks to&amp;nbsp;&lt;a href="http://www.codelord.net/" style="color: #006bad; font-weight: bold; text-decoration: none;" target="_blank" title="Aviv Ben-Yosef"&gt;Aviv&lt;/a&gt;&amp;nbsp;the following is of course another smell: passing&amp;nbsp;&lt;span style="color: blue;"&gt;null&lt;/span&gt;&amp;nbsp;to the callback function (i.e. declaring the parameter in the callback and eventually passing&amp;nbsp;&lt;span style="color: blue;"&gt;null&lt;/span&gt;).&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper" style="background-color: #f4f4f4; border-bottom: silver 1px solid; border-left: silver 1px solid; border-right: silver 1px solid; border-top: silver 1px solid; color: black; font-family: Courier New; font-size: 12pt; max-height: 200px; overflow: auto; padding-bottom: 4px; padding-left: 4px; padding-right: 4px; padding-top: 4px; width: 97.5%;"&gt;&lt;pre class="csharpcode" id="codeSnippet" xml:space="preserve"&gt;timerCallback(&lt;span style="color: blue;"&gt;null&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;blockqoute&gt; &lt;/blockqoute&gt;  &lt;a href="http://technorati.com/tag/[tagname]+[tagname]" rel="tag" style="display: none;"&gt;[tagname tagname]&lt;/a&gt;  &lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag" style="display: none;"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-5743707846883570185?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/hhcGmmf-Qko" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/5743707846883570185/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2011/01/code-smells.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5743707846883570185?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5743707846883570185?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/hhcGmmf-Qko/code-smells.html" title="Code Smells" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2011/01/code-smells.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUDRn4zfSp7ImA9Wx5VEEk.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-5521796949816386758</id><published>2010-10-02T21:04:00.000+02:00</published><updated>2010-10-02T21:04:37.085+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-02T21:04:37.085+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Craftsmanship" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>The Importance of Mentorship</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
It's hard to become a professional. It's even harder to become a &lt;strong&gt;professional Software Engineer&lt;/strong&gt;.&lt;br /&gt;
Last week, during a small management conference I bumped into an old friend of mine, who I didn't see for a couple of years. Being a leader of a software engineering group, he was frustrated and worried:&lt;br /&gt;
&lt;blockquote dir="ltr" style="margin-right: 0px;"&gt;"I have a group of 20 people, working hard to meet harsh deadlines. The project has just started, but most of the software engineers are already not pleased. There are junior developers that consider themselves as senior developers, there are senior developers that consider themselves as team leaders and there is &lt;span style="text-decoration: none;"&gt;no&lt;/span&gt; uniform professional knowledge. All of these are affecting the product's quality and really hurting our work."&lt;/blockquote&gt;Although there are many &lt;span style="text-decoration: none;"&gt;ways&lt;/span&gt; to shape &lt;a href="http://www.amazon.com/gp/product/0932633439?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0932633439" mce_href="http://www.amazon.com/gp/product/0932633439?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0932633439" target="_blank" title="Peopleware"&gt;cohesive and gelled teams&lt;/a&gt;, there is one important notion that just lately received its attention: &lt;strong&gt;Mentoring&lt;/strong&gt;.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/dirkhansen/3235465927/" mce_href="http://www.flickr.com/photos/dirkhansen/3235465927/" target="_blank" title="Mentoring a Team"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/TKeBJLJI1DI/AAAAAAAAAH8/A6cKagYwP9Y/s1600/Mentoring.CoachAndTeam.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The &lt;strong&gt;professional life&lt;/strong&gt; of a &lt;strong&gt;Software Engineer&lt;/strong&gt; is rather &lt;strong&gt;sporadic&lt;/strong&gt;. &lt;br /&gt;
Most of us are &lt;strong&gt;drifted with the stream&lt;/strong&gt;. The lifecycle is pretty much the same; You find a job, &lt;a href="http://www.youtube.com/watch?v=Eq3CuMDXaPs" mce_href="http://www.youtube.com/watch?v=Eq3CuMDXaPs" target="_blank" title="Keyboard\Code Monkeys"&gt;you receive features or requirements to implement, you code, you debug and then you move on&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
But, have you ever felt that &lt;strong&gt;if mentored by a true professional&lt;/strong&gt; you would succeed more? &lt;br /&gt;
You would know deeper. You would decide better. You would have better choices of your career paths. &lt;br /&gt;
I reckon that most of us did feel the same...&lt;br /&gt;
&lt;br /&gt;
Moreover, good mentors, not only promote individuals, but usually create &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2009/12/19/how-will-you-find-your-next-job.aspx" mce_href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2009/12/19/how-will-you-find-your-next-job.aspx" target="_blank" title="How will you find your next job"&gt;around themselves a great environment&lt;/a&gt; (and therefore great teams). &lt;br /&gt;
&lt;strong&gt;Excellence drives excellence&lt;/strong&gt; and professional excellence usually directs all the team members to &lt;strong&gt;shared ownership, partnership and targets&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
However, it is hard to find a true professional and it is even harder to find a true professional that knows &lt;strong&gt;how to mentor&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
There are a lot of parameters that shape a mentor, but no doubt the first virtue will be experience: &lt;strong&gt;Experience of successes, experience of failures and experience of crisis-es&lt;/strong&gt;.&lt;br /&gt;
Those are true &lt;a href="http://www.linkedin.com/groups?gid=2578449" mce_href="http://www.linkedin.com/groups?gid=2578449" target="_blank" title="Software Craftsmanship in Israel Group"&gt;Software Craftsman&lt;/a&gt;, that &lt;a href="http://www.infoq.com/presentations/poppendieck-deliberate-practice-in-software-development" mce_href="http://www.infoq.com/presentations/poppendieck-deliberate-practice-in-software-development" target="_blank" title="Deliberate Practice"&gt;spent their days and nights in polishing their skills&lt;/a&gt;. &lt;br /&gt;
And being &lt;a href="http://manifesto.softwarecraftsmanship.org/" mce_href="http://manifesto.softwarecraftsmanship.org/" target="_blank" title="Software Craftsmanship Manifesto"&gt;masters in building and managing software&lt;/a&gt;, they can teach you a lot: &lt;a href="http://www.joelonsoftware.com/articles/fog0000000036.html" mce_href="http://www.joelonsoftware.com/articles/fog0000000036.html" target="_blank" title="Painless Functional Specifications"&gt;How to write good requirements&lt;/a&gt;, how to architect, how to design, &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2009/06/12/Cult-Programmer.aspx" mce_href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2009/06/12/Cult-Programmer.aspx" target="_blank" title="The Cult Programmer"&gt;how to produce clean code&lt;/a&gt;, how to build software, how to ship software, &lt;a href="http://www.iltechtalks.org.il/home/talks/fosteringsoftwarecraftsmanship" mce_href="http://www.iltechtalks.org.il/home/talks/fosteringsoftwarecraftsmanship" target="_blank" title="Fostering Software Craftsmanship"&gt;how to manage technological teams&lt;/a&gt;, how to receive better technological decisions and etc... and etc...&lt;br /&gt;
&lt;br /&gt;
There is much more to say about mentoring. I will dedicate a few posts in the future, to describe what are, in my opinion, the virtues and the ways to do it well.&lt;br /&gt;
However in the meanwhile, I would like to take up the glove I have thrown in this post... On our next &lt;a href="http://www.linkedin.com/groups?gid=2578449" mce_href="http://www.linkedin.com/groups?gid=2578449" target="_blank" title="Software Craftsmanship in Israel Group"&gt;Software Craftsmanship Meetup&lt;/a&gt;, I will enroll a &lt;strong&gt;Mentorship program&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
A Mentorship program will allow &lt;strong&gt;Mentees to find an appropriate Mentors&lt;/strong&gt;. &lt;br /&gt;
The mentorship period will be for at least &lt;strong&gt;4 months&lt;/strong&gt; (IMHO, it should be more than 4 months, but let's start with that period). &lt;br /&gt;
During the mentorship period both the Mentees and the Mentors are committed to each other. &lt;br /&gt;
They will meet for at least 2 hours each week in order to:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Provide Technical Guidance and Feedback.&lt;/li&gt;
&lt;li&gt;Provide Reading Sources.&lt;/li&gt;
&lt;li&gt;Review and Build Carree Paths.&lt;/li&gt;
&lt;li&gt;Hold Code Reads, Code Reviews and Pairing.&lt;/li&gt;
&lt;li&gt;Do Architecture and Design Reviews.&lt;/li&gt;
&lt;li&gt;Review Management Decisions and Advise Management Dilemmas&lt;/li&gt;
&lt;li&gt;Etc. . .&lt;/li&gt;
&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/roberto8080/3852496552/" mce_href="http://www.flickr.com/photos/roberto8080/3852496552/" target="_blank" title="Samurai - A total Devotion to the Occupation"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/TKeBF8hWVRI/AAAAAAAAAH4/X6A_iYKCUfs/s1600/Mentorship.Samurai.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
If you are not coming to the 4th Software Craftsmanship meetup, but still want to participate you are most welcome to &lt;strong&gt;contact me via the blog&lt;/strong&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-5521796949816386758?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/pI_o02ZtB5c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/5521796949816386758/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/10/importance-of-mentorship.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5521796949816386758?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5521796949816386758?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/pI_o02ZtB5c/importance-of-mentorship.html" title="The Importance of Mentorship" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_6qKL-Tf2QeM/TKeBJLJI1DI/AAAAAAAAAH8/A6cKagYwP9Y/s72-c/Mentoring.CoachAndTeam.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/10/importance-of-mentorship.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIHSHw6fip7ImA9Wx5WGEs.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-1904325196381126896</id><published>2010-09-30T18:02:00.000+02:00</published><updated>2010-09-30T18:02:19.216+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-30T18:02:19.216+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Software Craftsmanship" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>Effective Code Review - A Presentation</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)  &lt;br /&gt;
&lt;br /&gt;
Here is a short presentation I did a while ago on a Code Review process.&lt;br /&gt;
&lt;br /&gt;
I am sure, there are a lot of different ways to do code review, but the following served me well in the past.&lt;br /&gt;
&lt;br /&gt;
One important note to bare in mind is that a Code Review cannot take more than a few hours.&lt;br /&gt;
People get tired easily; It's difficult to read somebody else's logic (code) and even more: to understand and to pinpoint the&amp;nbsp;problems.&lt;br /&gt;
&lt;br /&gt;
Therefore the Code Review process should be effective and highly cohesive as much as possible; I like the following metrics:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="color: green;"&gt;Summary&lt;/span&gt;: Ask a Software Engineer you are reviewing to explain in bullets what are the purposes of&lt;br /&gt;
the application, the module or the feature you are going to review.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: green;"&gt;Top-Down&lt;/span&gt;: Require to review high level components; High Level Design (Class Diagram, Component&lt;br /&gt;
Diagram, Some other Sketch and etc...)&lt;br /&gt;
Understand in general what are the main components / classes in the solution.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: green;"&gt;Focus&lt;/span&gt;: Ask the Software Engineer to point you towards the most problematic sections of the code.&lt;br /&gt;
He is the one who knows best what was hard to design or to implement.&lt;br /&gt;
Ask him to explain what was the problem and how he tried to resolve it.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: green;"&gt;Bottom-Up&lt;/span&gt;: Now start from the code you focused on (You can also review the Unit Tests in order to&lt;br /&gt;
understand better the code's behavior).&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: green;"&gt;Read and Communicate&lt;/span&gt;: Take an ownership on the keyboard and observe the code. Try to see whether&amp;nbsp;it is easy to understand the code and to navigate through it.&lt;br /&gt;
During your drive you should communicate loudly what are you doing; Where you are going next (e.g. "I'm opening class&amp;nbsp;X"), what you think of a piece of code you are reviewing and etc... You should ask questions in order to understand why it was&amp;nbsp;implemented the way it was and also to verify that other alternatives were considered by the Software Engineer.&lt;br /&gt;
You should spot the following:&lt;br /&gt;
&lt;/li&gt;
&lt;li style="list-style-type: none;"&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="color: maroon;"&gt;Bad naming&lt;/span&gt; (classes, methods, properties and etc...)&lt;br /&gt;
&lt;/li&gt;
&lt;li style="color: maroon;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Code_smell" target="_blank" title="Code Smells"&gt;Code Smells&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="color: maroon;"&gt;Design Violations&lt;/span&gt; (SOLID, GoF and etc...)&lt;br /&gt;
&lt;/li&gt;
&lt;li style="color: maroon;"&gt;Architectural Flows&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;And many others (I won't discuss here currently)...&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Your mutual notes should be written by the reviewed Software Engineer (navigator) and &lt;strong&gt;fixed later on&lt;/strong&gt;. Don't&amp;nbsp;waste your precious time to tackle immediately the problems.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div id="__ss_3831884" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0px 4px;"&gt;&lt;a href="http://www.slideshare.net/urilavi/effective-code-review-3831884" title="Effective Code Review"&gt;Effective Code Review&lt;/a&gt;&lt;/strong&gt; &lt;object height="355" width="425" xmlns=""&gt;       &lt;param name="movie" value=
      "http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=effectivecodereview-100423111548-phpapp02&amp;amp;stripped_title=effective-code-review-3831884" /&gt;      &lt;param name="wmode" /&gt;      &lt;embed xmlns="http://www.w3.org/1999/xhtml" src=
      "http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=effectivecodereview-100423111548-phpapp02&amp;amp;stripped_title=effective-code-review-3831884"
      name="__sse3831884" allowscriptaccess="always" height="355" width="425" allowfullscreen="true" type=
      "application/x-shockwave-flash"&gt;&lt;/embed&gt;    &lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-1904325196381126896?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/Hp7MptUxPM8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/1904325196381126896/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/09/effective-code-review-presentation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/1904325196381126896?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/1904325196381126896?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/Hp7MptUxPM8/effective-code-review-presentation.html" title="Effective Code Review - A Presentation" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/09/effective-code-review-presentation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEENRXszcSp7ImA9Wx5WFko.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-220101329783704228</id><published>2010-09-28T14:24:00.000+02:00</published><updated>2010-09-28T14:24:54.589+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-28T14:24:54.589+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><title>A Round Table</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Here is an interesting thing about &lt;strong&gt;Partnership and Shared Ownership&lt;/strong&gt;.&lt;br /&gt;
Once creating such an atmosphere within your team (company) you are &lt;strong&gt;on the road to success&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Everybody works together in order to accomplish the shared targets: Product Managers, Engineering, QA, Market Managers and etc...&lt;br /&gt;
Usually, small teams and small companies are characterized by the "Partnership and Shared Ownership" DNA.&lt;br /&gt;
But when they grow, rest assure that slowly but surely the Partnership and the Shared Ownership notion will dissipate.&lt;br /&gt;
&lt;br /&gt;
Once reaching &lt;a href="http://www.commonsenseadvice.com/human_cortex_dunbar.html" target="_blank" title="Human Cortex - 150 rule"&gt;~150&lt;/a&gt; people it is almost impossible to share the same values as you did before. (And in my humble opinion, it happens much much before 150)&lt;br /&gt;
Ah, but then a miracle happens...&lt;br /&gt;
Some "smart" manager gets a wonderful idea how to revive the sense of Partnership and Shared Ownership.&lt;br /&gt;
He suggests to have a "&lt;a href="http://en.wikipedia.org/wiki/Round_Table" target="_blank" title="A Round Table"&gt;round table&lt;/a&gt;" with the President\CEO\Group Manager.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://en.wikipedia.org/wiki/File:King_Arthur_and_the_Knights_of_the_Round_Table.jpg" target="_blank" title="King Arthur and the Knights of the Round Table"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/TKHVz7nPZ-I/AAAAAAAAAHw/CJ97--cY1uY/s1600/RoundTable.KingArthur.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Indeed, the President cannot meet each and every employee, but he can share a sense of equality as the King Arthur did with his knights.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;Let's have a bunch of employees sitting together, discussing their important values, tasks and views with his majesty.&lt;br /&gt;
Alas, I have been there; Allow me, then, to elaborate regarding what really happens around this table:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Either most of the employees are not familiar with each other or are not familiar enough in order to speak from the heart.&lt;/li&gt;
&lt;li&gt;Therefore, most of the time, the employees will introduce themselves and their projects/tasks without touching the really painful issues.&lt;/li&gt;
&lt;li&gt;The rest of the time, the President will summarize &lt;strong&gt;his&lt;/strong&gt; activities and &lt;strong&gt;his&lt;/strong&gt; "successful decisions and directions".&lt;/li&gt;
&lt;li&gt;And then... Well, then the meeting will be over. (But at least the President will be happy. After all, such a "convenient" audience is very hard to find...)&lt;/li&gt;
&lt;/ul&gt;There are only two recipes to succeed in creating the Partnership and Shared Ownership atmosphere.&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Involve &amp;amp; Trust&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/shivaj/2079666354/" target="_blank" title="Involvement &amp;amp; Trust"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/TKHWm2zHnII/AAAAAAAAAH0/SPA9DBJSMu4/s1600/RoundTable.Trust.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
You &lt;strong&gt;involve your employees&lt;/strong&gt;, &lt;strong&gt;they involve their employees&lt;/strong&gt; and so on... and so on... You spend your time &lt;strong&gt;explaining the roadmap&lt;/strong&gt;, &lt;strong&gt;emphasizing values&lt;/strong&gt;, &lt;strong&gt;motivating&lt;/strong&gt; and &lt;strong&gt;also hearing&lt;/strong&gt; what your people have to say. &lt;strong&gt;You verify that you follow what you preach&lt;/strong&gt;; You incorporate your employees suggestions and opinions. You also give an attribution as your employees should be acknowledged if they have provided a good idea. And you &lt;strong&gt;provide a "safety net"&lt;/strong&gt;. Your employees should know that they have a strong figure standing behind them; &lt;strong&gt;You don't blame, you don't share your disappointments - you support and foster&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
But sometimes, the round table idea sneaks into the small companies.&lt;br /&gt;
&lt;br /&gt;
When it happens, it signals that the problem is even worse; If a manager feels that there is a need to have a round table in a small company, it means that he &lt;strong&gt;doesn't have the time&lt;/strong&gt; to bestow the values on his employees. His hope is to do the &lt;strong&gt;minimal&lt;/strong&gt; effort, bringing everybody in "one take" to the table, in order to "motivate". Though the employees will feel more comfortable with each other in a small company, it just emphasizes the miscommunication and the mistrust that is going on. Clearly, this is not a best management...&lt;br /&gt;
&lt;br /&gt;
Dear manager: Involve &amp;amp; Trust... And do it &lt;strong style="color: green;"&gt;personally&lt;/strong&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-220101329783704228?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/2WDEY-BXR9k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/220101329783704228/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/09/round-table.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/220101329783704228?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/220101329783704228?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/2WDEY-BXR9k/round-table.html" title="A Round Table" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_6qKL-Tf2QeM/TKHVz7nPZ-I/AAAAAAAAAHw/CJ97--cY1uY/s72-c/RoundTable.KingArthur.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/09/round-table.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAFQHo-eip7ImA9Wx5REE4.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3342158187637876810</id><published>2010-08-16T09:27:00.001+03:00</published><updated>2010-08-17T11:11:51.452+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-17T11:11:51.452+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Craftsmanship" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>Short Roman Numeral Kata</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
For our &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2010/07/25/who-cares-software-craftsmanship-meeting-2.aspx" target="_blank" title="2nd Software Craftsmanship Meeting"&gt;second Software Craftsmanship Coding Dojo&lt;/a&gt;, I have prepared a "Short Roman&lt;br /&gt;
Numeral" Kata.&lt;br /&gt;
&lt;br /&gt;
In essence, a Short Roman Numeral is a number between 0 to 3999 that has a ToString() method which returns its roman presentation.&lt;br /&gt;
The rules of roman presentation construction can be found &lt;a href="http://en.wikipedia.org/wiki/Roman_numerals" target="_blank" title="Roman Numerals"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
After the meeting, I took some time in order to record the Code Kata.&lt;br /&gt;
&lt;br /&gt;
As you probably know it is &lt;a href="http://urilavi.blogspot.com/2010/03/primes-kata.html" target="_blank" title="Prime Factors Kata"&gt;extremely difficult to produce a well synchronized recording&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Hence, after a few sleepless nights I have finished the recording with great satisfaction, only to discover (thank you my&amp;nbsp;"dear" friend) that I made a typo during the exercise.&lt;br /&gt;
&lt;br /&gt;
Despite that, I have decided to share with you the current recording and to fix the typo later on...&lt;br /&gt;
&lt;br /&gt;
You can watch the High Definition version on Vimeo &lt;a href="http://vimeo.com/14155146"&gt;directly&lt;/a&gt; (or by pressing on "Vimeo" below) &lt;br /&gt;
&lt;br /&gt;
&lt;object height="400" width="711"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=14155146&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=00ADEF&amp;amp;fullscreen=1&amp;amp;autoplay=0&amp;amp;loop=0" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=14155146&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=1&amp;amp;color=00ADEF&amp;amp;fullscreen=1&amp;amp;autoplay=0&amp;amp;loop=0" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="711" height="400"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;br /&gt;
The (complete) source code can be found &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2010/07/25/who-cares-software-craftsmanship-meeting-2.aspx" target="_blank" title="Short Roman Numeral Source Code - C#"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3342158187637876810?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/i-cdSot0Al4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3342158187637876810/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/08/short-roman-numeral-kata.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3342158187637876810?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3342158187637876810?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/i-cdSot0Al4/short-roman-numeral-kata.html" title="Short Roman Numeral Kata" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/08/short-roman-numeral-kata.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IASHw7eSp7ImA9WxFSFEk.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3161809069422131107</id><published>2010-04-16T21:08:00.013+03:00</published><updated>2010-04-16T22:19:09.201+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-16T22:19:09.201+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Anti-Patterns" /><title>Writing Readable Code - Complex Object Construction</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Once upon a time, there was a class called &lt;span style="color: #338c7e;"&gt;Invoice.&lt;/span&gt; Its responsibility was to calculate a final&lt;br /&gt;
price being presented to the customer.&lt;br /&gt;
&lt;br /&gt;
Time went on; The autumn passed, the winter fade out and the spring was already at the door and our class started to &lt;b&gt;rust&lt;/b&gt;.&lt;br /&gt;
Each time a developer found a new set of relevant parameters (that should have been passed to the Invoice class) he added a new constructor, to support them.&lt;br /&gt;
&lt;br /&gt;
And so it happened, that after a while, two fellows stumbled on the class:&lt;br /&gt;
&lt;br /&gt;
"What's that rusty thing, my dear?" said G.Ollum "I don't understand; &lt;b&gt;What constructor&lt;/b&gt; should I invoke on the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt; class? Does it matter how should I create the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt; object? The class has more than 20 constructors; How in the world, somebody would understand what to do?"&lt;br /&gt;
&lt;br /&gt;
"Let me see, what's the problem" said D.Eagol&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
.cf { font-family: Courier New; font-size: 12pt; color: black; background-color: rgb(244, 244, 244); WIDTH: 97.5%; MAX-HEIGHT: 200px; FONT-FAMILY: Courier New; FONT-SIZE: 12pt; OVERFLOW: auto; BORDER-TOP: silver 1px solid; BORDER-BOTTOM: silver 1px solid; BORDER-RIGHT: silver 1px solid; BORDER-LEFT: silver 1px solid; PADDING-TOP: 4px; PADDING-BOTTOM: 4px; PADDING-RIGHT: 4px; PADDING-LEFT: 4px; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
.cb3 { color: green; }
&lt;/style&gt;&lt;br /&gt;
&lt;div class="cf"&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt; public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Invoice&lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Customer&lt;/span&gt; Customer { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;DateTime&lt;/span&gt; ContractDate { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;TimeSpan&lt;/span&gt; ServiceContinuum { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; BaseFee { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; ServiceFee { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;//... a lot of other members ...&lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; Invoice(&lt;span class="cb2"&gt;Customer&lt;/span&gt; customer)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Customer = customer;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; Invoice(&lt;span class="cb2"&gt;Customer&lt;/span&gt; customer, &lt;span class="cb2"&gt;DateTime&lt;/span&gt; contractDate)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span class="cb1"&gt;this&lt;/span&gt;(customer)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; Invoice(&lt;span class="cb2"&gt;Customer&lt;/span&gt; customer, &lt;span class="cb2"&gt;DateTime&lt;/span&gt; contractDate, &lt;span class="cb1"&gt;double&lt;/span&gt; baseFee)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span class="cb1"&gt;this&lt;/span&gt;(customer, contractDate)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; Invoice(&lt;span class="cb2"&gt;Customer&lt;/span&gt; customer, &lt;span class="cb2"&gt;TimeSpan&lt;/span&gt; serviceContinuum, &lt;span class="cb1"&gt;double&lt;/span&gt; serviceFee)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span class="cb1"&gt;this&lt;/span&gt;(customer)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb3"&gt;//... a lot of other constructors ...&lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
"It seems that you are right G.Olum", said D.Eagol after looking at the code, "You have a lot of&lt;br /&gt;
&lt;b&gt;different&lt;/b&gt; constructors, each instantiates a slightly different type of &lt;span style="color: #338c7e;"&gt;Invoice &lt;/span&gt;object, mainly because &lt;b&gt;there are&lt;/b&gt; a lot of &lt;b&gt;optional parameters&lt;/b&gt; to the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt; class. &lt;b&gt;There are&lt;/b&gt; also &lt;b&gt;required ones&lt;/b&gt;; Look at the Customer parameter being accepted in each and every constructor."&lt;br /&gt;
&lt;br /&gt;
"Moreover", continued D.Eagol, "The world has changed and something that shouldn't have been forgotten, was lost."&lt;br /&gt;
&lt;br /&gt;
"What's that, my dear?", inquired G.Olum&lt;br /&gt;
&lt;br /&gt;
"Well, you &lt;b&gt;cannot name your constructors&lt;/b&gt;. That's why it is so difficult for you to find how to instantiate&lt;br /&gt;
the class. If you were supplied methods with meaningful, intention revealing names then you would be able to create a required object", explained D.Eagol&lt;br /&gt;
&lt;br /&gt;
"So, what can I do?", cried G.Olum&lt;br /&gt;
&lt;br /&gt;
"Let's summarise what you &lt;b&gt;really want&lt;/b&gt; to do and then see how to accomplish it", said D.Eagol&lt;br /&gt;
&lt;br /&gt;
&lt;h5&gt;You want to:&lt;br /&gt;
&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Create a complex object, with:&lt;br /&gt;
&lt;/li&gt;
&lt;li style="list-style-type: none;"&gt;             &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A few required parameters&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;A few (or many) optional parameters&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h5&gt;You don't want to:&lt;br /&gt;
&lt;/h5&gt;&lt;ul&gt;&lt;li&gt;Use constructors - they are nameless and we fear of them&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;So, let's create an &lt;b&gt;internal class&lt;/b&gt; whose sole responsibility will be to &lt;b&gt;shadow that complex&lt;br /&gt;
creation&lt;/b&gt;.&lt;br /&gt;
Our inner class will provide a &lt;b&gt;meaningful method name for each optional parameter&lt;/b&gt; of the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt; class.&lt;br /&gt;
The required parameters will be passed to &lt;b&gt;one&lt;/b&gt;(and only one) inner's class constructor. Since, that inner class&lt;br /&gt;
deals with construction, let's call him a &lt;span style="color: #338c7e;"&gt;Builder&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Here is, how it should look:&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
.cf { font-family: Courier New; font-size: 12pt; color: black; background-color: rgb(244, 244, 244); WIDTH: 97.5%; MAX-HEIGHT: 200px; FONT-FAMILY: Courier New; FONT-SIZE: 12pt; OVERFLOW: auto; BORDER-TOP: silver 1px solid; BORDER-BOTTOM: silver 1px solid; BORDER-RIGHT: silver 1px solid; BORDER-LEFT: silver 1px solid; PADDING-TOP: 4px; PADDING-BOTTOM: 4px; PADDING-RIGHT: 4px; PADDING-LEFT: 4px; }
.cl { margin: 0px; }
.cb1 { color: blue; }
.cb2 { color: #2b91af; }
&lt;/style&gt;&lt;br /&gt;
&lt;div class="cf"&gt;&lt;pre class="cl"&gt;&lt;span class="cb1"&gt;    public&lt;/span&gt; &lt;span class="cb1"&gt;sealed&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Invoice&lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Customer&lt;/span&gt; Customer { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;DateTime&lt;/span&gt; ContractDate { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;TimeSpan&lt;/span&gt; ServiceContinuum { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; BaseFee { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; ServiceFee { &lt;span class="cb1"&gt;get&lt;/span&gt;; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;set&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; Invoice()&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb1"&gt;class&lt;/span&gt; &lt;span class="cb2"&gt;Builder&lt;/span&gt;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;Customer&lt;/span&gt; customer;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;DateTime&lt;/span&gt; contractDate;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb2"&gt;TimeSpan&lt;/span&gt; serviceContinuum;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; baseFee;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;private&lt;/span&gt; &lt;span class="cb1"&gt;double&lt;/span&gt; serviceFee;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; Builder(&lt;span class="cb2"&gt;Customer&lt;/span&gt; customer)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;this&lt;/span&gt;.customer = customer;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Builder&lt;/span&gt; SignedOn(&lt;span class="cb2"&gt;DateTime&lt;/span&gt; signDate)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;this&lt;/span&gt;.contractDate = signDate;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; &lt;span class="cb1"&gt;this&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Builder&lt;/span&gt; ServiceAgreementForPeriodOf(&lt;span class="cb2"&gt;TimeSpan&lt;/span&gt; serviceContinuum)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;this&lt;/span&gt;.serviceContinuum = serviceContinuum;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; &lt;span class="cb1"&gt;this&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Builder&lt;/span&gt; ServiceBaseFee(&lt;span class="cb1"&gt;double&lt;/span&gt; baseFee)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;this&lt;/span&gt;.baseFee = baseFee;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; &lt;span class="cb1"&gt;this&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Builder&lt;/span&gt; ServiceFee(&lt;span class="cb1"&gt;double&lt;/span&gt; serviceFee)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;this&lt;/span&gt;.serviceFee = serviceFee;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; &lt;span class="cb1"&gt;this&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;public&lt;/span&gt; &lt;span class="cb2"&gt;Invoice&lt;/span&gt; Build()&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb2"&gt;Invoice&lt;/span&gt; invoice = &lt;span class="cb1"&gt;new&lt;/span&gt; &lt;span class="cb2"&gt;Invoice&lt;/span&gt; &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Customer = &lt;span class="cb1"&gt;this&lt;/span&gt;.customer, &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ContractDate = &lt;span class="cb1"&gt;this&lt;/span&gt;.contractDate, &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ServiceContinuum = &lt;span class="cb1"&gt;this&lt;/span&gt;.serviceContinuum, &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BaseFee = &lt;span class="cb1"&gt;this&lt;/span&gt;.baseFee, &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ServiceFee = &lt;span class="cb1"&gt;this&lt;/span&gt;.serviceFee &lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;return&lt;/span&gt; invoice;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
"You see", continued D.Eagol, "That's what you have accomplished:"&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt;'s &lt;b&gt;constructor is private&lt;/b&gt; - only the &lt;span style="color: #338c7e;"&gt;Builder&lt;/span&gt; can return an &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt;, through its &lt;b&gt;Build method&lt;/b&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;span style="color: #338c7e;"&gt;Builder&lt;/span&gt;'s constructor receives the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt;'s required parameter: Customer&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;span style="color: #338c7e;"&gt;Builder&lt;/span&gt; &lt;b&gt;provides meaningful method names&lt;/b&gt; for eachof the &lt;span style="color: #338c7e;"&gt;Invoice&lt;/span&gt;'s optional parameters and utilizes &lt;a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank" title="Fluint Interface"&gt;&lt;b&gt;Fluent interface&lt;/b&gt;&lt;/a&gt; in order to provide a more readable form of setting those parameters&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;"And here, how the instantiation looks like:"&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
.cf { font-family: Courier New; font-size: 12pt; color: black; background-color: rgb(244, 244, 244); WIDTH: 97.5%; MAX-HEIGHT: 200px; FONT-FAMILY: Courier New; FONT-SIZE: 12pt; OVERFLOW: auto; BORDER-TOP: silver 1px solid; BORDER-BOTTOM: silver 1px solid; BORDER-RIGHT: silver 1px solid; BORDER-LEFT: silver 1px solid; PADDING-TOP: 4px; PADDING-BOTTOM: 4px; PADDING-RIGHT: 4px; PADDING-LEFT: 4px; }
.cl { margin: 0px; }
.cb1 { color: #2b91af; }
.cb2 { color: blue; }
.cb3 { color: #a31515; }
&lt;/style&gt;&lt;br /&gt;
&lt;div class="cf"&gt;&lt;pre class="cl"&gt;&amp;nbsp;&lt;span class="cb1"&gt;Invoice&lt;/span&gt;.&lt;span class="cb1"&gt;Builder&lt;/span&gt; invoiceBuilder = &lt;span class="cb2"&gt;new&lt;/span&gt; &lt;span class="cb1"&gt;Invoice&lt;/span&gt;.&lt;span class="cb1"&gt;Builder&lt;/span&gt;(&lt;span class="cb1"&gt;Customer&lt;/span&gt;.CustomerA);&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="cb1"&gt;Invoice&lt;/span&gt; invoice = invoiceBuilder&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .SignedOn(Date(&lt;span class="cb3"&gt;"4/7/2010 08:00:00 PM"&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .ServiceAgreementForPeriodOf(Days(30))&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .ServiceBaseFee(1000)&lt;/pre&gt;&lt;pre class="cl"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; .Build();&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
"Now it really &lt;b&gt;shines&lt;/b&gt;!", finished D.Eagol, "What do you say G.Olum?"&lt;br /&gt;
&lt;br /&gt;
"Give us that, D.eagol, my love... It's my birthday...and I wants it!", gurgled G.Olum.&lt;br /&gt;
&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag" style="display: none;"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3161809069422131107?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/DElgSeohckw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3161809069422131107/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/04/writing-readable-code-complex-object_8201.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3161809069422131107?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3161809069422131107?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/DElgSeohckw/writing-readable-code-complex-object_8201.html" title="Writing Readable Code - Complex Object Construction" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/04/writing-readable-code-complex-object_8201.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AEQnk_eCp7ImA9WxBbE0U.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-4801405333616742113</id><published>2010-03-12T12:28:00.000+02:00</published><updated>2010-03-12T12:28:23.740+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-12T12:28:23.740+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Refactoring Tools Review - part II</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Oh, my God!&lt;br /&gt;
I am definitely in love!&lt;br /&gt;
I finally had the time to play with the latest &lt;a href="http://www.devexpress.com/" target="_blank" title="DevExpress"&gt;DevExpress&lt;/a&gt;'s &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Refactoring/index.xml" target="_blank" title="Refactor! Pro"&gt;Refactor&lt;/a&gt;! Pro and &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/index.xml" target="_blank" title="Code Rush and Refactor! Pro"&gt;Code Rush&lt;/a&gt;.&lt;br /&gt;
Two distinct main features capture my eyes immediately:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The ability to highlight the changes/code smells and refactorings &lt;b&gt;inside the Visual Studio's Editor&lt;/b&gt;.&lt;br /&gt;
It seems that the team invested a lot of effort in order to enable painting on the Visual Studio's editor and canvas.&lt;br /&gt;
This enables a smooth user experience, without prompting and stalling with unnecessary dialogs.&lt;br /&gt;
The changes are visualized directly on the source code.&lt;br /&gt;
Below is one of my favorite refactoring steps: "&lt;b&gt;Extract Method&lt;/b&gt;" visualized in Visual Studio 2008.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_6qKL-Tf2QeM/S5oRDxP5spI/AAAAAAAAAHA/3T0cER7LOwg/s1600-h/RefactoringReview.1.RefactorPro.ExtractMethod.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/S5oRDxP5spI/AAAAAAAAAHA/3T0cER7LOwg/s320/RefactoringReview.1.RefactorPro.ExtractMethod.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;A &lt;b&gt;huge&lt;/b&gt; amount of automated tasks: navigations, refactoring steps and code improvements.&lt;br /&gt;
Refactor! Pro has more than 150 refactoring steps to automate the burden of the day to day refactoring.&lt;br /&gt;
Code Rush brings smooth navigation within the code, markers (like the bookmarks in VS, but they work across different files/projects), templates to enhance the development and "on the fly" static code analysis.&lt;br /&gt;
Below is a partial list of the &lt;b&gt;Refactoring Catalog&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oRsZKZmHI/AAAAAAAAAHI/QGzyuM1qn0Q/s1600-h/RefactoringReview.2.RefactorPro.RefactoringsCatalog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oRsZKZmHI/AAAAAAAAAHI/QGzyuM1qn0Q/s320/RefactoringReview.2.RefactorPro.RefactoringsCatalog.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Here is a screenshot of a &lt;b&gt;Code Issue&lt;/b&gt; found in the code, by the &lt;b&gt;"on the fly" code analysis&lt;/b&gt;. Pay attention to the blue indicator being painted on the editor's scroll bar: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oSAZQtGeI/AAAAAAAAAHQ/3z0Zf2JkIw0/s1600-h/RefactoringReview.3.CodeRush.CodeIssue.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oSAZQtGeI/AAAAAAAAAHQ/3z0Zf2JkIw0/s320/RefactoringReview.3.CodeRush.CodeIssue.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Navigation&lt;/b&gt; features and &lt;b&gt;Templates&lt;/b&gt; allow a very fast development experience.&lt;br /&gt;
The &lt;b&gt;CodeRush&lt;/b&gt; window trains and suggests interactively, templates or other actions that are applicable at the current position.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oSSlb06vI/AAAAAAAAAHY/SfXqE1p9o7Q/s1600-h/RefactoringReview.4.CodeRush.Templates.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/S5oSSlb06vI/AAAAAAAAAHY/SfXqE1p9o7Q/s320/RefactoringReview.4.CodeRush.Templates.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
However those are the small things that make these tools so great. It's unbelievably easy to develop clean code in the first place and to refactor it later. Meet your new friend; Hit "&lt;b&gt;Ctrl+`&lt;/b&gt;" and all your dreams will come true :)&lt;br /&gt;
&lt;br /&gt;
The tools allow you to develop fast and smoothly: you will double your productivity, you will find that it is easier to navigate through the code and finally you will find that you can &lt;b&gt;give up the mouse&lt;/b&gt;. Being a &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2010/03/07/prime-factors-kata.aspx" target="_blank" title="Prime Factors Kata"&gt;Software Craftsman&lt;/a&gt; it's very important to know the tools of the trade (IDE commands/shortcuts). CodeRush and Refactor! Pro can help you to achieve that. Moreover, these tools provide a good sense of living in one place. Everything is achievable through the Visual Studio Editor and accessible through one keyboard combination or another.&lt;br /&gt;
&lt;br /&gt;
If you have seen my previous &lt;a href="http://urilavi.blogspot.com/2009/09/refactoring-tools-review-part-i.html" target="_blank" title="Refactoring Tools Review - Part I"&gt;post&lt;/a&gt;, you have probably noticed the Editor layout I used in the past. &lt;b&gt;Code Metrics Window&lt;/b&gt;, &lt;b&gt;Code Definition Window&lt;/b&gt; and &lt;b&gt;Source Length Guides&lt;/b&gt; hack (in the registry) were combined together to enhance the IDE. The combination, using default Visual Studio's windows, was to say the least, a bit unnatural.&lt;br /&gt;
&lt;br /&gt;
Here is my Editor's layout that utilizes the CodeRush's features:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/S5oS_xgCTBI/AAAAAAAAAHg/Oq8MUGuV_AI/s1600-h/RefactoringReview.5.CodeRush.Editor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="235" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/S5oS_xgCTBI/AAAAAAAAAHg/Oq8MUGuV_AI/s400/RefactoringReview.5.CodeRush.Editor.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can easily see that the code metrics are placed very conveniently adjusted to a method. The source length guides is configurable and can be easily modified (without hacking the registry) and the references window is awesome as it allows colored Code Definition Window's experience.&lt;br /&gt;
&lt;br /&gt;
Notwithstanding; Though CodeRush and Refactor! Pro are great tools, there will be &lt;b&gt;quite a learning curve&lt;/b&gt; in order to master all (or at least a great deal) of it's features. There are so many that each day I discover new and exciting ones. Therefore, in order to maximize your experience you will need to invest time learning the features. For that purpose DevExpress provides a descent help (coming installed with the tools) and also maintains a good &lt;b&gt;training video series&lt;/b&gt;, &lt;a href="http://www.devexpress.com/Products%20/Visual_Studio_Add-in/Coding_Assistance/training.xml" target="_blank" title="Training Videos"&gt;here&lt;/a&gt;. In addition, as stated above, the CodeRush Window provides an interactive learning experience while you are working on your code base.&lt;br /&gt;
&lt;br /&gt;
I would also suggest adding the following to the refactoring catalog:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;"&lt;b&gt;Move Method&lt;/b&gt;" - an ability to move a method to a different class/file.&lt;br /&gt;
Refactor! Pro provides a very close feature, called "&lt;b&gt;Extract Method To Type&lt;/b&gt;", but there are several issues with the later:&lt;/li&gt;

&lt;ul&gt;&lt;li&gt;Sometimes the method is already given, but should be moved to a different location.&lt;/li&gt;
&lt;li&gt;Extracting a method to a different type is a combination of two basic steps: Extract Method and Move Method. Refactoring usually preaches to do small changes followed by compilation and unit tests execution. Combining those two steps can affect beginners; They can either premature utilizing the refactoring or can fail, to correctly interpret the right location for the method.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;"&lt;b&gt;Remove Parameter&lt;/b&gt;" - an ability to remove a parameter from a method's declaration.&lt;br /&gt;
Also here, Refactor! Pro provides a close feature, called "&lt;b&gt;Remove Unused Parameter&lt;/b&gt;". Though, I easily can degenerate the use of the parameter inside the method and then use the "Remove Unused Parameter" step, I still find it useful to remove first the parameter from the method itself.&lt;/li&gt;
&lt;/ul&gt;CodeRush comes with &lt;a href="http://community.devexpress.com/blogs/aspnet/archive/2009/09/02/coderush-upcoming-testrunner-preview.aspx?Newsletter10" target="_blank" title="TestRunner"&gt;TestRunner&lt;/a&gt; and supports now several xUnit Test Frameworks. &lt;br /&gt;
A nice to have feature is also:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A support for a parametrized Unit Test Attribute, such as &lt;b&gt;TestCaseSource&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;From performance perspective, I have found CodeRush and Refactor! Pro satisfying. I didn't feel any unnecessary pauses or delays during my work, while utilizing the tools.&lt;br /&gt;
&lt;br /&gt;
Finally, the most important note :). Would I consider to purchase these tools?&lt;br /&gt;
My answer is, it depends: As a corporate that wants to boost its developers performance, buying the whole package of &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/index.xml" target="_blank" title="CodeRush and Refactor! Pro License"&gt;CodeRush and Refactor! Pro&lt;/a&gt; for 249.99$ makes sense. As an individual developer, the only less expensive option is to consider a purchase of just the &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Refactoring/" target="_blank" title="Refactor! Pro License"&gt;Refactor! Pro&lt;/a&gt; license for 99$. I will add, that if DevExpress will cut of the number of features in CodeRush and Refactor! Pro, but will provide a license from 50$ - 120$ it will make the individual developer's life easier.&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;A disclaimer: I have received a fully functional copy of the CodeRush and Refactor! Pro in order to allow the investigation of the features over the time.&lt;/small&gt;&lt;br /&gt;
&lt;a href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag" style="display: none;"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-4801405333616742113?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/oHvin9l2GoA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/4801405333616742113/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/03/refactoring-tools-review-part-ii.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4801405333616742113?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4801405333616742113?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/oHvin9l2GoA/refactoring-tools-review-part-ii.html" title="Refactoring Tools Review - part II" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6qKL-Tf2QeM/S5oRDxP5spI/AAAAAAAAAHA/3T0cER7LOwg/s72-c/RefactoringReview.1.RefactorPro.ExtractMethod.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/03/refactoring-tools-review-part-ii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08EQH8zfyp7ImA9WxBUGEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3033405310405927589</id><published>2010-03-03T23:33:00.011+02:00</published><updated>2010-03-06T20:23:21.187+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-06T20:23:21.187+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Software Craftsmanship" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>Prime Factors Kata</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
One of the key aspects of a Software Craftsmanship is constant practice.&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Kata" target="_blank" title="Kata"&gt;Kata&lt;/a&gt; (from Martial Arts) is one form of such practice. The notion of a Code Kata was first introduced by &lt;a href="http://www.codekata.com/" target="_blank" title="Code Kata - Dave Thomas"&gt;Dave Thomas&lt;/a&gt; and can be viewed as:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Practice of the same methods, solutions and activities to a perfection.&lt;/li&gt;
&lt;li&gt;Practice of the same problem, tackling it each time from a different angle or with a different solution.&lt;/li&gt;
&lt;/ul&gt;Solving a known problem multiple times utilizing the same methods, enhances the understanding of the specific steps; It especially enhances the understanding of unit tests, refactoring steps or "Design" approaches. Moreover, striving to do better each time motivates one to learn the keyboard shortcuts and IDE commands in order to perform smoothly. Knowing the tools of the trade (or the tools of the Martial Arts :) ) is essential for the Software Craftsman's success.&lt;br /&gt;
&lt;br /&gt;
Solving a problem in different methods helps to identify solutions that work better in the right context (requirements).&lt;br /&gt;
&lt;br /&gt;
Below (also &lt;a href="http://www.vimeo.com/9859547"&gt;here&lt;/a&gt;) is one of my Prime Factors Kata's sessions recorded late at night :).&lt;br /&gt;
The Kata demonstrates finding a number's prime factors using TDD (C#, NUnit, VS 2008).&lt;br /&gt;
(Don't forget to turn on the speakers)&lt;br /&gt;
&lt;br /&gt;
I must admit, that it is super difficult to record a completely clean demonstration, especially while synchronizing the music and the moves. Moreover, one of the real obstacles is statically typed languages (C#) that slow a bit the moves. Exercising the Kata with &lt;a href="http://www.viddler.com/explore/unclebobmartin/videos/2/" target="_blank" title="Robert C. Martin - Primes Kata"&gt;dynamically typed languages&lt;/a&gt; can ease and speed the performance.&lt;br /&gt;
&lt;br /&gt;
&lt;object height="265" width="400" xmlns=""&gt;       &lt;param name="movie" value=
      "http://vimeo.com/moogaloop.swf?clip_id=9859547&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" /&gt;&lt;param name="wmode" /&gt;&lt;embed xmlns="http://www.w3.org/1999/xhtml" src="http://vimeo.com/moogaloop.swf?clip_id=9859547&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" allowscriptaccess="always" height="265" width="400" allowfullscreen="true" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;    &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3033405310405927589?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/oYqqLksJlhw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3033405310405927589/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2010/03/primes-kata.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3033405310405927589?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3033405310405927589?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/oYqqLksJlhw/primes-kata.html" title="Prime Factors Kata" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2010/03/primes-kata.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQARHo-eip7ImA9WxBSEkg.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-5622984872916190268</id><published>2009-12-19T21:52:00.000+02:00</published><updated>2009-12-19T21:52:25.452+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-19T21:52:25.452+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><title>How will you find your next job?</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So, &lt;i&gt;you have decided to move on&lt;/i&gt;...&lt;br /&gt;
&lt;br /&gt;
You have updated your CV and sent it to your friends... Then you sent it to a couple of recruitment companies... Then you sent it to all known recruitment companies...&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;After a while&lt;/i&gt;...&lt;br /&gt;
You have been called to an interview...and another one... and another one...&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Weeks later&lt;/i&gt;...&lt;br /&gt;
You got a proposal(s) and you have decided to accept the job: The compensations are a little bit better than the existing ones. The issues are the same; After all you are paid to develop more or less according to your experience. Yet, you are pretty much excited about the change; You are going to work with new people and make new collaborations. Though minor, it cannot be dismissed, after all we are social "animals" and changing groups/places has its effect.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Hey&lt;/b&gt;, but did you stop to think for a moment &lt;b&gt;whether the next place is going to be a better one&lt;/b&gt;? After all, that's the purpose of you moving on, isn't it?&lt;br /&gt;
&lt;br /&gt;
Many posts are dealing with how to hire the best of the bests Software Engineers (and I am not an &lt;a href="http://urilavi.blogspot.com/2009/04/hunt-for-software-engineer.html" target="_blank" title="The Hunt for a Software Engineer"&gt;exception&lt;/a&gt;), but this post is dedicated to the searchers themselves.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="text-decoration: underline;"&gt;Here, how you will find your next job:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style="font-size: smaller;"&gt;A disclaimer:&lt;br /&gt;
-There are many ways to evaluate a company; I am focusing on more technological/professional evaluations using social media.&lt;br /&gt;
-Below is a short list of criteria, followed by my explanations of why those criteria identify a better company.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;span style="text-decoration: underline;"&gt;Learn the company's executives bio:&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Who are its managers (Company's Web Site)?&lt;/li&gt;
&lt;li&gt;Were are they mentioned (&lt;a href="http://www.google.com/" target="_blank" title="Google"&gt;Google&lt;/a&gt;, &lt;a href="http://www.techcrunch.com/" target="_blank" title="Techcrunch"&gt;Techcrunch&lt;/a&gt;)?&lt;/li&gt;
&lt;li style="list-style-type: none;"&gt; &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;How often are they mentioned?&lt;/li&gt;
&lt;li&gt;Do they mention their technologies/products vision in a clear way?&lt;/li&gt;
&lt;li&gt;Can you identify a company's future roadmap?&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="text-decoration: underline;"&gt;Search for the company's profile (If not available, search for employees profiles):&lt;/span&gt; (&lt;a href="http://www.linkedin.com/" target="_blank" title="Linkedin"&gt;Linkedin&lt;/a&gt;, &lt;a href="http://www.facebook.com/" target="_blank" title="Facebook"&gt;Facebook&lt;/a&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Look for the current and former employees, are you familiar with any?   &lt;/li&gt;
&lt;li&gt;Look for the current employees profiles:&lt;/li&gt;
&lt;li style="list-style-type: none;"&gt; &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;What is their average experience?&lt;/li&gt;
&lt;li&gt;Do they have any professional blogs? If yes, then:&lt;/li&gt;
&lt;li style="list-style-type: none;"&gt;             &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Do they deal with Software Architecture and/or Design?&lt;/li&gt;
&lt;li&gt;Do they discuss innovative ideas in terms of Software Engineering or Software Management?&lt;/li&gt;
&lt;li&gt;Do they contain any posts explaining company's software application development decisions?&lt;/li&gt;
&lt;li&gt;Do they emphasize/teach how things are being done inside their company?&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Does any of the employees lecture (occasionally or regularly) on Software Engineering topics? (Given that the company isn't a professional training company)&lt;/li&gt;
&lt;li&gt;Does any of the employees contribute to an open source? ( &lt;a href="http://www.linkedin.com/" target="_blank" title="Linkedin"&gt;Linkedin&lt;/a&gt;, &lt;a href="http://www.google.com/" target="_blank" title="Google"&gt;Google&lt;/a&gt;, &lt;a href="http://www.codeproject.com/" target="_blank" title="The Code Project"&gt;Codeproject&lt;/a&gt;, &lt;a href="http://www.codeplex.com/" target="_blank" title="CodePlex"&gt;Codeplex&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Does any of the employees attend (occasionally or regularly) any professional conventions (&lt;a href="http://www.linkedin.com/static?key=application_directory&amp;amp;trk=hb_side_apps" target="_blank" title="Linked Events"&gt;Linkedin Events&lt;/a&gt;, &lt;a href="http://www.linkedin.com/" target="_blank" title="Linked Groups"&gt;Linkedin Groups&lt;/a&gt;, &lt;a href="http://groups.google.com/" target="_blank" title="Google Groups"&gt;Google Groups&lt;/a&gt;, &lt;a href="http://twitter.com/" target="_blank" title="Twitter"&gt;Twitter&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;span style="text-decoration: underline;"&gt;Search for the company's additional activities:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Does the company support an open source? (&lt;a href="http://www.blogger.com/post-create.g?blogID=5286282305278386798" ref="http://www.linkedin.com/" target="_blank" title="Linkedin"&gt;Linkedin&lt;/a&gt;,&lt;a href="http://www.google.com/" target="_blank" title="Google"&gt;Google&lt;/a&gt;, &lt;a href="http://www.codeproject.com/" target="_blank" title="Code Project"&gt;Codeproject&lt;/a&gt;, &lt;a href="http://www.codeplex.com/" target="_blank" title="Codeplex"&gt;Codeplex&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Does the company contribute to an open source? (&lt;a href="http://www.linkedin.com/" target="_blank" title="Linkedin"&gt;Linkedin&lt;/a&gt;,&lt;a href="http://www.google.com/" target="_blank" title="Google"&gt;Google&lt;/a&gt;, &lt;a href="http://www.codeproject.com/" target="_blank" title="Code Project"&gt;Codeproject&lt;/a&gt;, &lt;a href="http://www.codeplex.com/" target="_blank" title="Codeplex"&gt;Codeplex&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Does the company support any professional event?&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
And here is why, in my opinion, the above criteria will help you to identify the better companies:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Good executives will create a lot of buzz around their company, either by being cited by others or by expressing themselves through press, articles, blogs or tweets (A good example is: Joel Spolsky and his columns here: &lt;a href="http://www.joelonsoftware.com/" target="_blank" title="JoelOnSoftware"&gt;joelonsoftware&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Though this is expected, clear definition of the technologies/products with consistent and proven history of achievements, symbolizes higher success of the company's roadmap (and future).&lt;/li&gt;
&lt;li&gt;Moreover, such executives, usually create a supportive climate where Software Engineers thrive. In such a climate, Software Engineers are driven by mutual success in terms of products and technologies.&lt;/li&gt;
&lt;li&gt;Good Engineers, in their turn, usually blog or tweet about their professional experience.&lt;/li&gt;
&lt;li&gt;Real good Engineers not only discuss a specific technology, but also discuss much wider aspects like Architecture, Design and Software Management. You will have a lot of fun learning and working with such, especially if you spot the following concepts in their posts: &lt;a href="http://www.amazon.com/gp/product/0131857258?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0131857258" target="_blank" title="Agile Principles, Patterns, and Practices in C#"&gt;S.O.L.I.D&lt;/a&gt; principles, &lt;a href="http://www.amazon.com/gp/product/0321146530?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321146530" target="_blank" title="Test Driven Development: By Example"&gt;Test Driven Development&lt;/a&gt; (TDD), &lt;a href="http://www.amazon.com/gp/product/1933988274?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1933988274" target="_blank" title="The Art of Unit Testing: With Examples in .Net"&gt;Unit Testing&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/0974514047?ie=UTF8&amp;amp;tag=urilavblo-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0974514047" target="_blank" title="Ship it! A Practical Guide to Successful Software Projects"&gt;Continuous Integration&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis" target="_blank" title="Static Code Analysis Tools"&gt;Static Code Analysis&lt;/a&gt; (also &lt;a href="http://urilavi.blogspot.com/2009/06/cult-programmer.html" target="_blank" title="A Cult Programmer"&gt;here&lt;/a&gt;). Those are the signs of people who care about high quality products!&lt;/li&gt;
&lt;li&gt;The best Engineers contribute to an open source. They spend their spare time coding and &lt;a href="http://manifesto.softwarecraftsmanship.org/" target="_blank" title="Software Craftsmanship Manifesto"&gt;refining their professional knowledge&lt;/a&gt; (also &lt;a href="http://www.linkedin.com/groups?gid=2578449" target="_blank" title="Software Craftsmanship in Israel"&gt;here&lt;/a&gt;). Not only they enhance themselves, but they also contribute a great deal to others (that's the beauty of the open source). Be sure, they will also contribute to your knowledge and skills when working with them.&lt;/li&gt;
&lt;li&gt;Thus, being technologically thirsty, those Engineers will attend professional conventions and events and eventually will drive their companies to support such activities.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Remember, it may seem like a long and tedious investigation, but it pays back, if you really aim to find a great place to work in.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-5622984872916190268?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/zgzPClqizdw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/5622984872916190268/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/12/how-will-you-find-your-next-job.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5622984872916190268?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5622984872916190268?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/zgzPClqizdw/how-will-you-find-your-next-job.html" title="How will you find your next job?" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/12/how-will-you-find-your-next-job.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYNQn8_fip7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-9160867726703288123</id><published>2009-10-24T21:49:00.017+02:00</published><updated>2009-10-25T20:59:53.146+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:59:53.146+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>DTOs, Business Entities and Persistency</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;When designing an application, one can easily confuse DTOs, Business Entities and Persistency.&lt;br /&gt;&lt;br /&gt;Using the following simple examples I will demonstrate design considerations and thoughts that will dispel some mists.&lt;br /&gt;&lt;br /&gt;Consider that you want to represent an audio or a movie located on a web page.&lt;br /&gt;When you visualize such an object, the first thing you probably see is the data that characterizes it. No surprise here. You applied, without knowing it, an "&lt;a href="http://urilavi.blogspot.com/2009/07/one-pattern-to-rule-them-all.html" target="_blank" title="One Pattern To Rule Them All"&gt;Information Expert&lt;/a&gt;" pattern when you visualized the object's &lt;strong&gt;knowledge responsibilities&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;So, what are they? Clearly such an object will have:&lt;ul&gt;&lt;li&gt;Uri - object's URL&lt;/li&gt;&lt;li&gt;Content - object's content&lt;/li&gt;&lt;li&gt;DateCreated - object's creation date&lt;/li&gt;&lt;li&gt;Etc...&lt;/li&gt;&lt;/ul&gt;I will name this object a "Resource", since it represents a resource being located on a web page (be it a movie or an audio).&lt;br /&gt;&lt;br /&gt;But wait... here you go; Meet the &lt;a href="http://en.wikipedia.org/wiki/Data_transfer_object" target="_blank" title="DTO"&gt;DTO&lt;/a&gt; object. A DTO is a simple container for a set of aggregated data that needs to be transferred across a process or network boundary. It &lt;strong&gt;should contain no business logic&lt;/strong&gt; and limit its behavior to activities such as internal consistency checking and basic validation.&lt;br /&gt;&lt;br /&gt;The Resource object is rather simple, it's a mere placeholder for the object's attributes and as such represents a DTO.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SuNbt2BTLRI/AAAAAAAAAFw/REKE4h6hw9E/s1600-h/Resource.ResourceDTO.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 143px; height: 96px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SuNbt2BTLRI/AAAAAAAAAFw/REKE4h6hw9E/s400/Resource.ResourceDTO.PNG" alt="" id="BLOGGER_PHOTO_ID_5396257621673192722" border="0" /&gt;&lt;/a&gt;Now, let's say that a Resource object should be persisted to some store.&lt;br /&gt;&lt;br /&gt;Basically, we would like to introduce a "Save" functionality that will persist a Resource object. The question is: Who's responsibility should it be? Using the &lt;strong&gt;Information Expert pattern&lt;/strong&gt; again will reveal that &lt;strong&gt;functional responsibility&lt;/strong&gt; (as a "Save" operation) is a &lt;strong&gt;sole responsibility of a class with the most information required to fulfill it&lt;/strong&gt;. Hmmm... Isn't it a Resource class? As a Resource class "knows" exactly the information it wants to persist, it implies that the Resource class should have the "Save" responsibility.&lt;br /&gt;&lt;br /&gt;I know... I know... Didn't we say a minute ago that a DTO shouldn't contain any business logic? By adding a Save responsibility to the resource class we turned it into something else. We turned the Resource into &lt;a href="http://en.wikipedia.org/wiki/Business_object_%28computer_science%29" target="_blank" title="Business Object"&gt;Business Entity&lt;/a&gt;. A business entity is an object that is responsible to solve domain requirements by collaborating with additional business entities.&lt;br /&gt;&lt;br /&gt;Let's see what are our design options for creating a Resource business entity.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Option I:&lt;/span&gt;&lt;/strong&gt; A Resource business entity inherits a ResourceDTO.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SuNcrqpRF4I/AAAAAAAAAF4/ngh14TuRnNs/s1600-h/Resource.ResourceEntity.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 144px; height: 195px;" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SuNcrqpRF4I/AAAAAAAAAF4/ngh14TuRnNs/s400/Resource.ResourceEntity.PNG" alt="" id="BLOGGER_PHOTO_ID_5396258683771492226" border="0" /&gt;&lt;/a&gt;Though it's tempting to select the above solution, you shouldn't take the path (unless the requirements are very very simple). Remember; &lt;a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1255958679&amp;amp;sr=8-1-spell" target="_blank" title="Design Patterns - GoF"&gt;One of the principles of object oriented design&lt;/a&gt; is to &lt;strong&gt;favor object composition over class inheritance.&lt;/strong&gt; There are many reasons for which the principle holds, but I am not going to discuss all of them here.&lt;br /&gt;&lt;br /&gt;It does not make sense that Resource "is-a" type of ResourceDTO; You are not going to transfer the Resource object across boundaries. Moreover, such a design may violate the &lt;a href="http://urilavi.blogspot.com/2009/06/cult-programmer.html" target="_blank" title="SOLID"&gt;Single Responsibility and Open Closed Principles&lt;/a&gt;. The "Save" method is going to be bloated with a specific logic of how to connect to a certain store - which is clearly not Resource's responsibility. Changing a store, having more than one store or changing &lt;strong&gt;what to store&lt;/strong&gt; will require Resource modifications - which violates the OC principle.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Option II:&lt;/span&gt;&lt;/strong&gt; A Resource business entity passes a Resource DTO to a specialized Resource data access entity.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SuNdqjLwrVI/AAAAAAAAAGA/fLWlcHyHJrs/s1600-h/Resource.ResourceEntity.DTO.DAL.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 295px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SuNdqjLwrVI/AAAAAAAAAGA/fLWlcHyHJrs/s400/Resource.ResourceEntity.DTO.DAL.PNG" alt="" id="BLOGGER_PHOTO_ID_5396259764100443474" border="0" /&gt;&lt;/a&gt;All the specific logic of data access is captured in a specialized ResourceDal object. Any change in store, will change only the specialized object. The ResourceDal object will receive a Persistent Resource DTO object, thus decoupling the Resource entity from the persistent information (which can vary easily later on). Such a design is superior as it allows to &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank" title="Dependency Injection"&gt;inject&lt;/a&gt; the correct data access object to the Resource entity (and it also means that it will be much more testable). Also, it allows to have &lt;strong&gt;multiple    DTOs&lt;/strong&gt;, for example: &lt;strong&gt;one for persistency and one for visualization&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;In order to derive a &lt;span style="color: rgb(51, 140, 126);"&gt;PersistentResourceDTO&lt;/span&gt; from a Resource entity I will use an &lt;a href="http://automapper.codeplex.com/" target="_blank" title="AutoMapper"&gt;AutoMapper&lt;/a&gt; library.&lt;br /&gt;&lt;br /&gt;AutoMapper uses a fluent configuration API to define an object to object mapping strategy, thus allowing easy transformations.&lt;br /&gt;Here is the &lt;span style="color: rgb(51, 140, 126);"&gt;PersistentResourceDTO&lt;/span&gt; declaration:&lt;br /&gt;&lt;div   style="border: 1px solid silver; margin: 20px 0px 10px; padding: 4px; overflow: auto; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 97.5%; direction: ltr; max-height: 200px; cursor: text;font-family:'Courier New',Courier,Monospace;font-size:8pt;" id="codeSnippetWrapper"&gt;&lt;pre class="code"&gt;&lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PersistedResourceDTO&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt; public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Uri &lt;/span&gt;Uri { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color:blue;"&gt; public byte&lt;/span&gt;[] Content { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color:blue;"&gt; public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;DateTime &lt;/span&gt;DateCreated { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Using AutoMapper library is especially easy when the properties and methods of the source type match to the properties of the destination type - this is called &lt;strong&gt;flattening&lt;/strong&gt;.&lt;br /&gt;Thus ExtractPersistentDTO method's implementation is simple and coherent.&lt;br /&gt;&lt;div   style="border: 1px solid silver; margin: 20px 0px 10px; padding: 4px; overflow: auto; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 97.5%; direction: ltr; max-height: 200px; cursor: text;font-family:'Courier New',Courier,Monospace;font-size:8pt;" id="codeSnippetWrapper"&gt;&lt;pre class="csharpcode" id="codeSnippet"&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PersistedResourceDTO &lt;/span&gt;ExtractPersistentDTO()&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:green;"&gt;// creates a mapping between Resource and persistent Resource DTO.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mapper&lt;/span&gt;.CreateMap&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Resource&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;PersistedResourceDTO&lt;/span&gt;&gt;();&lt;br /&gt;&lt;span style="color:green;"&gt;// flattens the current Resource object into PersistedResourceDTO.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PersistedResourceDTO &lt;/span&gt;dto = &lt;span style="color: rgb(43, 145, 175);"&gt;Mapper&lt;/span&gt;.Map&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Resource&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;PersistedResourceDTO&gt;&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;dto;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;AutoMapper library also allows to &lt;strong&gt;project&lt;/strong&gt; a mapping. Projection - transforms a source to a destination beyond flattening the object model. Consider that a Resource also has a collection of keywords. In order to visualize the Resource we want to use the following &lt;span style="color: rgb(51, 140, 126);"&gt;VisualResourceDTO&lt;/span&gt; where the title will be a combination of all the keywords.&lt;br /&gt;&lt;div   style="border: 1px solid silver; margin: 20px 0px 10px; padding: 4px; overflow: auto; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 97.5%; direction: ltr; max-height: 200px; cursor: text;font-family:'Courier New',Courier,Monospace;font-size:8pt;" id="codeSnippetWrapper"&gt;&lt;pre class="csharpcode" id="codeSnippet"&gt;&lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;VisualResourceDTO&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Uri &lt;/span&gt;Uri { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color:blue;"&gt;public string &lt;/span&gt;Title { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;private set&lt;/span&gt;; }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Here is how to do it using the AutoMapper:&lt;br /&gt;&lt;div   style="border: 1px solid silver; margin: 20px 0px 10px; padding: 4px; overflow: auto; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 97.5%; direction: ltr; max-height: 200px; cursor: text;font-family:'Courier New',Courier,Monospace;font-size:8pt;" id="codeSnippetWrapper"&gt;&lt;br /&gt;&lt;pre class="csharpcode" id="codeSnippet"&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;VisualResourceDTO &lt;/span&gt;ExtractVisualDTO()&lt;br /&gt;{&lt;br /&gt;&lt;span style="color:green;"&gt;// creates a mapping between Resource and Resource DTO&lt;/span&gt;        &lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Mapper&lt;/span&gt;.CreateMap&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Resource&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;VisualResourceDTO&lt;/span&gt;&gt;()&lt;br /&gt;      .ForMember( d =&gt; d.Title,&lt;br /&gt;                  op =&gt; op.MapFrom(resource =&gt; &lt;span style="color:blue;"&gt;&lt;br /&gt;                            string&lt;/span&gt;.Join(&lt;span style="color: rgb(163, 21, 21);"&gt;" "&lt;/span&gt;, resource.Keywords.ToArray()))&lt;br /&gt;                );&lt;br /&gt;&lt;span style="color:green;"&gt;// projects the current resource object into VisualResourceDTO&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;VisualResourceDTO &lt;/span&gt;dto = &lt;span style="color: rgb(43, 145, 175);"&gt;Mapper&lt;/span&gt;.Map&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Resource&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;VisualResourceDTO&gt;&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;return &lt;/span&gt;dto;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;(Remark: In the post above I didn't discuss other approaches, like ORM solutions).&lt;br /&gt;&lt;br /&gt;&lt;a style="display: none;" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag"&gt;codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-9160867726703288123?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/EcAlvWmmOEs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/9160867726703288123/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/10/dtos-business-entities-and-persistency.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/9160867726703288123?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/9160867726703288123?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/EcAlvWmmOEs/dtos-business-entities-and-persistency.html" title="DTOs, Business Entities and Persistency" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SuNbt2BTLRI/AAAAAAAAAFw/REKE4h6hw9E/s72-c/Resource.ResourceDTO.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/10/dtos-business-entities-and-persistency.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eip7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-6188650891174262239</id><published>2009-10-04T22:18:00.020+02:00</published><updated>2009-10-25T20:58:11.222+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.222+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++/CLI" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Notes on C++/CLI</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;If you asked for my opinion whether to develop an application using (unmanaged) C++, I would strongly advise you to reconsider.&lt;br /&gt;&lt;br /&gt;Unless you deal with real time applications (or near real time applications), you should better utilize the managed world. Sure, there are times for old good C++; especially when the application's memory footprint is an issue, but needless to say, you have better chances in productivity, ease of development and maintainability in the managed applications (C#, Java and etc...) than in the unmanaged world.&lt;br /&gt;&lt;br /&gt;Sometimes, obviously, the above advice is impractical. When dealing with complex algorithmic issues, which already have pretty sound support in various unmanaged C++ toolkits and frameworks, you are forced to choose what exists over reinventing the wheel.&lt;br /&gt;&lt;br /&gt;C++/CLI can bridge the gap.&lt;br /&gt;The common practice is to wrap the unmanaged libraries with the C++/CLI, thus exposing the unmanaged functionality through the managed C++ layer. In the example below, Taxes project contains various algorithms for tax calculations written in (unmanaged) C++. The Taxes project is wrapped with TaxesMixed project which is a C++/CLI project. Finally, TaxesApp project, which is written in C#, uses the TaxesMixed wrapper to utilize the complex unmanaged tax calculations.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskEH-NtI1I/AAAAAAAAAFQ/5RvPrbaAK-g/s1600-h/C%2B%2B.CLI.Projects.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 179px; DISPLAY: block; HEIGHT: 69px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5388842964131586898" border="0" alt="Tipical Solution" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskEH-NtI1I/AAAAAAAAAFQ/5RvPrbaAK-g/s320/C%2B%2B.CLI.Projects.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When dealing with unmanaged, mixed (C++/CLI) and managed projects, there are some notes to keep in mind:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="TEXT-DECORATION: underline"&gt;Debugging&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you want to debug the unmanaged code (e.g.Taxes above) from the managed (e.g. TaxesApp above), don't forget to mark the option &lt;strong&gt;enable unmanaged code debugging&lt;/strong&gt; on the debug tab of the managed project's settings.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskFAHu8xkI/AAAAAAAAAFY/dF7EbhM7qTo/s1600-h/C%2B%2B.CLI.DebugTab.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 254px; DISPLAY: block; HEIGHT: 98px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5388843928759617090" border="0" alt="Enable unmanaged debugging tab" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskFAHu8xkI/AAAAAAAAAFY/dF7EbhM7qTo/s320/C%2B%2B.CLI.DebugTab.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="TEXT-DECORATION: underline"&gt;Implementing Destructor/Finalizer&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;C++/CLI classes that use unmanaged C++ classes should implement &lt;a title="Dispose\Finalize Pattern" href="http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=5&amp;amp;tabid=11" target="_blank"&gt;Dispose\Finalize pattern&lt;/a&gt; (look for: "Deterministic finalization template" title). Apparently, implementing the pattern is much easier using C++/CLI than C#. &lt;strong&gt;All you need,&lt;/strong&gt; is to provide a deterministic destructor (~ syntax) and a finalize method (! syntax) and everything else will be generated by the C++/CLI.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippet"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;TaxesMixed::TaxCalculatorWrapper::~TaxCalculatorWrapper()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;-&gt;!TaxCalculatorWrapper();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;TaxesMixed::TaxCalculatorWrapper::!TaxCalculatorWrapper()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;nullptr&lt;/span&gt; != m_Calculator)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;delete&lt;/span&gt; m_Calculator;&lt;br /&gt;    }&lt;br /&gt;} &lt;/pre&gt;&lt;/div&gt;C++/CLI will generate all the additional Dispose, Dispose(&lt;span style="color:#338c7e;"&gt;bool&lt;/span&gt;) and Finalize methods in order to complete the pattern.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskFApkikOI/AAAAAAAAAFg/xxwTvlutyyo/s1600-h/C%2B%2B.CLI+Destructor-Finalize.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 308px; DISPLAY: block; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5388843937842761954" border="0" alt="" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskFApkikOI/AAAAAAAAAFg/xxwTvlutyyo/s320/C%2B%2B.CLI+Destructor-Finalize.png" /&gt;&lt;/a&gt;&lt;/div&gt;Here is a quick peek into the Dispose(&lt;span style="color:#338c7e;"&gt;bool&lt;/span&gt;) method, using &lt;a title=".NET Reflector" href="http://www.red-gate.com/products/reflector/index.htm" target="_blank"&gt;Reflector&lt;/a&gt;.&lt;br /&gt;As you can see, the method calls the deterministic Dispose method (~) when the TaxWrapper.Dispose() method is called and calls the Finalize method (!) when the TaxWrapper is garbage collected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SskFBuoAHzI/AAAAAAAAAFo/jEuK0glqVuw/s1600-h/C%2B%2B.CLI+Dispose.bool.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 221px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5388843956379328306" border="0" alt="" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SskFBuoAHzI/AAAAAAAAAFo/jEuK0glqVuw/s320/C%2B%2B.CLI+Dispose.bool.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="TEXT-DECORATION: underline"&gt;To pin or not to pin?&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When a pointer to a managed object (or its part) needs to be passed to the unmanaged code, there is one important issue to be aware of:&lt;br /&gt;Managed objects (on CLR Small Object Heap) don't remain at the same location for their lifetime as they are moved during the GC heap compaction cycles.&lt;br /&gt;As a consequence,a native pointer that points to a CLI object becomes garbage once the object has been relocated. In order to ensure a correct behavior, C++/CLI introduces a &lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt; &lt;a title="msdn: pin_ptr" href="http://msdn.microsoft.com/en-us/library/1dz8byfh.aspx" target="_blank"&gt;pointer&lt;/a&gt; which &lt;strong&gt;pins&lt;/strong&gt; a CLI object in order to prevent its relocation while a garbage collection cycle occurs.&lt;br /&gt;&lt;br /&gt;(If you need a pointer semantic in C++/CLI you can use an &lt;span style="color:#0000ff;"&gt;interior_ptr&lt;/span&gt; &lt;a title="msdn: interior_ptr" href="http://msdn.microsoft.com/en-us/library/y0fh545k.aspx" target="_blank"&gt;pointer&lt;/a&gt; which is updated automatically when a garbage collection cycle occurs and remains a &lt;a title="C++/CLI in Action" href="http://www.codeproject.com/KB/books/CppCliInActionCh4Ex1.aspx" target="_blank"&gt;valid pointer even after the compaction&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;You declare a &lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt; as follows:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt;&lt;&lt;span style="color:#0000ff;"&gt;type&lt;/span&gt;&gt; = &amp;initializer;&lt;/pre&gt;&lt;/div&gt;Example:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippet"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Person&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Id {&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;protected set&lt;/span&gt;;}&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;[] Taxes { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;protected set&lt;/span&gt;;}&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Person()&lt;br /&gt;    {&lt;br /&gt;        Id = &lt;span style="color:#006080;"&gt;"SSN:12345"&lt;/span&gt;&lt;br /&gt;        Taxes = taxesDal.Load(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Id);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippet"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; TaxesMixed::TaxCalculatorWrapper::CalculateAnnualTaxes(&lt;span style="color:#338c7e;"&gt;Person&lt;/span&gt;^ person)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Pinning a whole object. &lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt;&lt;&lt;span style="color:#338c7e;"&gt;Person&lt;/span&gt;^&gt; ptr = &amp;person;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Passing the object or one of its value members to a native code.&lt;/span&gt;&lt;br /&gt;    . . .&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Pinning an array (by pinning the first element). &lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt;&lt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&gt; arrPtr = &amp;amp;person-&gt;Taxes[0];&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Assigning to a native pointer &lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;* arr = arrPtr;&lt;br /&gt;    . . .&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;When dealing with &lt;span style="color:#0000ff;"&gt;pin_ptr&lt;/span&gt; you should remember:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pinning a sub-object defined in a managed object has the effect of pinning the entire object.&lt;/li&gt;&lt;li&gt;Pinning an object also pins its value fields (that is, fields of primitive or value type). However, &lt;strong&gt;fields declared by tracking handle are not pinned&lt;/strong&gt;.&lt;br /&gt;(To avoid redundant mistakes, my suggestion is to always pin the required reference type member, thus pinning the whole object.) &lt;/li&gt;&lt;li&gt;A pinning pointer can point to a reference handle, value type or boxed type handle, member of a managed type or to an element of a managed array. &lt;strong&gt;It cannot point to a reference type&lt;/strong&gt;. &lt;/li&gt;&lt;/ul&gt;In any case, if you are interested in reading more about C++/CLI, you can find &lt;a title="C++/CLI Tutorials" href="http://www.functionx.com/cppcli/index.htm" target="_blank"&gt;here&lt;/a&gt; very good tutorials on the topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-6188650891174262239?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/4ayLkkj8MgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/6188650891174262239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/10/notes-on-ccli.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6188650891174262239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6188650891174262239?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/4ayLkkj8MgM/notes-on-ccli.html" title="Notes on C++/CLI" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SskEH-NtI1I/AAAAAAAAAFQ/5RvPrbaAK-g/s72-c/C%2B%2B.CLI.Projects.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/10/notes-on-ccli.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eip7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-6969180732815357346</id><published>2009-09-05T23:06:00.019+03:00</published><updated>2009-10-25T20:58:11.222+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.222+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Refactoring Tools Review - Part I</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Don Roberts and John Brant stated in the book &lt;a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672" target="_blank" title="Refactoring Book"&gt;Refactoring - Improving the Design of Existing Code&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;      "Refactoring with automated tool support feels different from manual refactoring".&lt;br /&gt;&lt;/blockquote&gt;&lt;strong&gt;Indeed - It is!&lt;/strong&gt;&lt;br /&gt;Having an &lt;strong&gt;automated tool&lt;/strong&gt; that helps you to &lt;strong&gt;change the code without the fear of breaking it&lt;/strong&gt; - is    invaluable.&lt;br /&gt;&lt;br /&gt;That's why, I wanted to summarize several available options for .NET developers.&lt;br /&gt;&lt;br /&gt;Let's start with the obvious one: Visual Studio Refactoring Tool.&lt;br /&gt;As usual Microsoft concentrates on the core business, leaving the field to other players.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Visual Studio Refactoring Tool&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Visual Studio comes with a very simple &lt;strong&gt;Refactoring Tool&lt;/strong&gt;, available from the &lt;strong&gt;Refactor&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;toolbar&lt;/strong&gt; or from the &lt;strong&gt;Refactor context menu.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLGe5TrlxI/AAAAAAAAADg/Nt4-Zyb8xrI/s1600-h/RefactoringTools.VS.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 319px; height: 168px;" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLGe5TrlxI/AAAAAAAAADg/Nt4-Zyb8xrI/s320/RefactoringTools.VS.png" alt="" id="BLOGGER_PHOTO_ID_5378079139115538194" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As you can see, all the refactoring steps have keyboard shortcuts.&lt;br /&gt;In addition, Visual Studio triggers some of the aforementioned refactoring steps behind the scene, when a certain change is detected.&lt;br /&gt;Those changes are mostly underlined with a double red line, as here:&lt;br /&gt;&lt;div align="left"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLHPBWO9eI/AAAAAAAAADo/3V5InfDiltw/s1600-h/RefactoringTools.Rename.png"&gt;&lt;img style="cursor: pointer; width: 165px; height: 18px;" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLHPBWO9eI/AAAAAAAAADo/3V5InfDiltw/s320/RefactoringTools.Rename.png" alt="" id="BLOGGER_PHOTO_ID_5378079965907449314" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;Using the combination &lt;strong&gt;Shift-Alt-F10&lt;/strong&gt; will fire the correct refactoring step menu, allowing smooth and quick refactoring.&lt;br /&gt;(In the case above - &lt;strong&gt;Rename&lt;/strong&gt; refactoring step).&lt;br /&gt;&lt;br /&gt;The Refactoring Tool provides pretty basic refactring steps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Rename&lt;/strong&gt; -&lt;br /&gt;The tool effectively changes the names (variables, methods, types and etc...) across projects in the same solution.&lt;br /&gt;The changes can be easily reviewed (checked/unchecked) prior the modification through the &lt;strong&gt;Preview Changes&lt;/strong&gt; menu.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLH-1b8d_I/AAAAAAAAADw/zh3_CK8tOgs/s1600-h/RefactoringTools.RenamePreviewChanges.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 259px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLH-1b8d_I/AAAAAAAAADw/zh3_CK8tOgs/s320/RefactoringTools.RenamePreviewChanges.png" alt="" id="BLOGGER_PHOTO_ID_5378080787343898610" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Extract Method&lt;/strong&gt; -&lt;br /&gt;Visual Studio provides a basic method extraction mechanism. &lt;strong&gt;Extract Method&lt;/strong&gt; generates a new method with correctly inferred parameters (from the extracted scope) and substitutes the extracted block code with a call to the method. In addition, &lt;strong&gt;Extract Method&lt;/strong&gt; identifies whether a method uses local class members and if not, suggests marking the extracted method as &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt;.&lt;br /&gt;In the Refactoring process this often indicates that the method should &lt;strong&gt;Move&lt;/strong&gt; to a different class, but Visual Studio Refactoring Tool doesn't provide any suggestions to where such a move is possible.&lt;br /&gt;(There are other tools that do provide the suggestions - patience, patience...).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Encapsulate Field&lt;/strong&gt; -&lt;br /&gt;Creates properties for existing members.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Extract Interface&lt;/strong&gt; -&lt;br /&gt;Enables extraction of an &lt;span style="color: rgb(0, 0, 255);"&gt;interface&lt;/span&gt; from a type.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Promote Local Variables to Parameter&lt;/strong&gt; -&lt;br /&gt;Promotes a local variable to a method's parameter.&lt;br /&gt;When a local variable declaration isn't selected correctly, the tool will prompt with an explanatory menu (first screenshot).&lt;br /&gt;Also, the tool will alert when it cannot guarantee that all the callers pass a legal value to the newly promoted parameter (second screenshot).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SqLJJ9hm3UI/AAAAAAAAAD4/OHtY9EVjpC4/s1600-h/RefactoringTools.PromoteLocalVariable1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 136px;" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SqLJJ9hm3UI/AAAAAAAAAD4/OHtY9EVjpC4/s320/RefactoringTools.PromoteLocalVariable1.png" alt="" id="BLOGGER_PHOTO_ID_5378082078005321026" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLJSlj5_yI/AAAAAAAAAEA/45H6mxc1jY0/s1600-h/RefactoringTools.PromoteLocalVariable2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 79px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLJSlj5_yI/AAAAAAAAAEA/45H6mxc1jY0/s320/RefactoringTools.PromoteLocalVariable2.png" alt="" id="BLOGGER_PHOTO_ID_5378082226191335202" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Remove Parameters/Reorder Parameters&lt;/strong&gt; -&lt;br /&gt;Adjusts a method's parameters.&lt;/li&gt;&lt;/ul&gt;Clearly, as stated above, this is a very simplistic refactoring tool, especially when comparing to &lt;a href="http://www.eclipse.org/" target="_blank" title="Eclipse"&gt;Eclipse&lt;/a&gt;. As you can see below, Eclipse comes with much more refactoring steps available out of the box.&lt;br /&gt;There are more than 20 refactoring steps in the Refactor menu.&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLJ83OIhcI/AAAAAAAAAEI/hSsZK3tAXac/s1600-h/RefactoringTools.Eclipse.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 150px; height: 320px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLJ83OIhcI/AAAAAAAAAEI/hSsZK3tAXac/s320/RefactoringTools.Eclipse.PNG" alt="" id="BLOGGER_PHOTO_ID_5378082952486356418" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In addition, one can utilize additional Visual Studio "Refactoring" features.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Visual Studio Additional "Refactoring" Features&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Source Code Length&lt;/strong&gt; -&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLKyiBsDtI/AAAAAAAAAEQ/icsRNFVL_Ig/s1600-h/RefactoringTools.Guides.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 62px;" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLKyiBsDtI/AAAAAAAAAEQ/icsRNFVL_Ig/s320/RefactoringTools.Guides.png" alt="" id="BLOGGER_PHOTO_ID_5378083874509950674" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Adding &lt;strong&gt;Guides&lt;/strong&gt; to the Vusial Studio IDE will allow to visually emphasis the length of the source code line.&lt;br /&gt;In order to add &lt;strong&gt;Guides&lt;/strong&gt;, you should edit the "&lt;strong&gt;HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\X.X\Text     Editor&lt;/strong&gt;" key in the registry (where X.X is the VS version).&lt;br /&gt;Create a string key called "&lt;strong&gt;Guides&lt;/strong&gt;" with the value "&lt;strong&gt;RGB(255,0,0), 80&lt;/strong&gt;" in order to have a &lt;strong&gt;red line&lt;/strong&gt; at column &lt;strong&gt;80&lt;/strong&gt; in the text editor.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Code Definition&lt;/strong&gt; -&lt;br /&gt;Using the &lt;strong&gt;Go To Definition&lt;/strong&gt; each time you want to examine the referenced method or type is very tedious. That's why the &lt;strong&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/f5yx24a6%28VS.80%29.aspx" target="_blank" title="Code Definition Window"&gt;&lt;strong&gt;Code Definition Window&lt;/strong&gt;&lt;/a&gt;&lt;/strong&gt; is handy! As you move the insertion point in the editor, or change the selection in &lt;strong&gt;Class View,&lt;/strong&gt; the &lt;strong&gt;Object Browser&lt;/strong&gt;, or &lt;strong&gt;Call Browser&lt;/strong&gt;, the content of the &lt;strong&gt;Code Definition&lt;/strong&gt; window is updated and displays the definition of a symbol referenced by the selection.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLLa-lI49I/AAAAAAAAAEY/1QR9lwze7KI/s1600-h/RefactoringTools.CodeDefinitionWindow.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 245px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLLa-lI49I/AAAAAAAAAEY/1QR9lwze7KI/s320/RefactoringTools.CodeDefinitionWindow.png" alt="" id="BLOGGER_PHOTO_ID_5378084569369600978" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Code Metrics&lt;/strong&gt; -&lt;br /&gt;Knowing the code complexity can help writing a more clean and refactored code. Visual Studio provides the &lt;a href="http://msdn.microsoft.com/en-us/library/bb385914.aspx" target="_blank" title="Code Metrics Window"&gt;&lt;strong&gt;Code Metrics Window&lt;/strong&gt;&lt;/a&gt; that provides a better insight into the developed code. I would suggest to pay attention especially on the following metrics:&lt;/li&gt;&lt;li style="list-style-type: none;"&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Cyclomatic Complexity&lt;/strong&gt; - Measures the structural complexity of the code.&lt;br /&gt;A program that has complex control flow (and thus a high cyclomatic score) will require more unit tests to achieve good code coverage and will be less maintainable.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Class Coupling&lt;/strong&gt; - Measures the coupling to unique classes through parameters, local variables, return types, method calls and etc...&lt;br /&gt;High coupling (and thus a high class coupling score) indicates a design that is difficult to reuse and maintain because of its many interdependencies on other types.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLMfcM6W2I/AAAAAAAAAEg/8AH1bQxi4ls/s1600-h/RefactoringTools.CodeMetricsWindow.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 193px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLMfcM6W2I/AAAAAAAAAEg/8AH1bQxi4ls/s320/RefactoringTools.CodeMetricsWindow.png" alt="" id="BLOGGER_PHOTO_ID_5378085745552153442" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Here is the combined IDE view with all the additional "refactoring" features:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLM3_M4vWI/AAAAAAAAAEo/bqPQznvh-ig/s1600-h/RefactoringTools.CombinedView.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 227px;" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SqLM3_M4vWI/AAAAAAAAAEo/bqPQznvh-ig/s400/RefactoringTools.CombinedView.png" alt="" id="BLOGGER_PHOTO_ID_5378086167264148834" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Of course, an experienced Software Engineer can create a clean and refactored code, even with the skim Visual Studio Refactoring Tool and additional "Refactroing" features. The experience though isn't going to be smooth and easy. The refactoring features are scattered and as overall not so user friendly.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;Summary:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The &lt;strong&gt;Visual Studio Refactoring Tool&lt;/strong&gt; is rather simplistic.&lt;/li&gt;&lt;li&gt;Most used refactoring steps are: &lt;strong&gt;Rename&lt;/strong&gt; and &lt;strong&gt;Extract Method.&lt;/strong&gt; Those steps provide fairly good functionality (though extra behavior is possible when extracting a method).&lt;/li&gt;&lt;li&gt;Other significant refactoring steps don't exist; Microsoft leaves the stage to other players.&lt;/li&gt;&lt;li&gt;Additional refactoring features, as: &lt;strong&gt;Source Code Length&lt;/strong&gt;, &lt;strong&gt;Code Definition&lt;/strong&gt; and &lt;strong&gt;Code   Metrics&lt;/strong&gt; exist and provide complementary ways to understand and refine your code. The features, though, scattered across different places which makes it hard to simultaneously work with all of them.&lt;/li&gt;&lt;/ul&gt;In the next post we will examine additional automatic refactoring tools.&lt;!-- codeproject --&gt;&lt;a style="display: none;" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-6969180732815357346?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/SQG5NGX_H1w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/6969180732815357346/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/09/refactoring-tools-review-part-i.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6969180732815357346?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6969180732815357346?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/SQG5NGX_H1w/refactoring-tools-review-part-i.html" title="Refactoring Tools Review - Part I" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SqLGe5TrlxI/AAAAAAAAADg/Nt4-Zyb8xrI/s72-c/RefactoringTools.VS.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/09/refactoring-tools-review-part-i.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eip7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-5920190773393707095</id><published>2009-07-26T22:46:00.005+03:00</published><updated>2009-10-25T20:58:11.222+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.222+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>One pattern to rule them all</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Well, there is none...&lt;br /&gt;Simply to put, there is &lt;a href="http://en.wikipedia.org/wiki/History_of_software_engineering#1985_to_1989:_No_silver_bullet" target="_blank" title="No Silver Bullet"&gt;no silver bullet&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Yet, while designing an application, there are several well known extremes:&lt;br /&gt;&lt;br /&gt;"Heavy weighted design" - Such a design will use almost each and every pattern described in the &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612" target="_blank" title="Design Patterns"&gt;bible of "Design Patterns"&lt;/a&gt; - by the Gang of Four.&lt;br /&gt;&lt;br /&gt;However, squeezing as much as possible patterns into your design has a bad &lt;a href="http://en.wikipedia.org/wiki/Code_smell" target="_blank" title="Code Smell"&gt;smell&lt;/a&gt;. &lt;a href="http://www.artima.com/lejava/articles/gammadp.html" target="_blank" title="Erich Gamma - Design Patterns"&gt;Here is&lt;/a&gt; what &lt;a href="http://en.wikipedia.org/wiki/Erich_Gamma" title="Erich Gamma"&gt;Erich Gamma&lt;/a&gt; has to say on the matter:&lt;blockquote&gt;"Trying to use all the patterns is a bad thing, because you will end up with synthetic designs-speculative designs that have "flexibility" that no one needs. These days software is too complex. We can't afford speculating what else it should do. We need to focus on what it actually needs. That's why I like &lt;strong&gt;refactoring to patterns&lt;/strong&gt;. People should learn that when they have a particular kind of problem or &lt;a href="http://en.wikipedia.org/wiki/Code_smell" target="_blank" title="Code Smell"&gt;code smell&lt;/a&gt;, as people call it these days, they can go to their patterns toolbox to find a solution.&lt;/blockquote&gt;"&lt;a href="http://en.wikipedia.org/wiki/Big_ball_of_mud" target="_blank" title="Big Ball of Mud"&gt;Big ball of mud&lt;/a&gt;" or "no design" at all - Though the application utilizes classes (objects) and methods, it does it solely due to the language constraints. After all, the code must be placed somewhere and usually it lies in giant classes and methods. Besides that, there are no abstraction layers or small and specialized objects that have "concise conversations" in order to solve the business requirements.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To use the patterns correctly, a Software Engineer must understand the &lt;strong&gt;context&lt;/strong&gt; (=requirements) and the &lt;strong&gt;suggested&lt;/strong&gt; &lt;strong&gt;solutions&lt;/strong&gt; depicted by the patterns. Usually, in the real life scenario, it's hard to grasp where exactly is the right context to which a suggested design solution should be applicable. Especially for the inexperienced Software Engineers, design patterns described by the &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612" target="_blank" title="Design Patterns - GoF"&gt;Gang of Four's bible&lt;/a&gt; can confuse and lead to:&lt;ul&gt;  &lt;li&gt;Misidentify contexts and thus creation of "Big ball of mud" or "no design" applications.&lt;/li&gt;&lt;li&gt;Over identify contexts (even where there is no context at all) and thus creation of "Heavy weighted design" applications.&lt;/li&gt;&lt;/ul&gt; That's where the &lt;a href="http://en.wikipedia.org/wiki/GRASP_%28Object_Oriented_Design%29" target="_blank" title="Expert"&gt;Expert&lt;/a&gt; pattern can be handy! Expert pattern is one of the &lt;a href="http://en.wikipedia.org/wiki/GRASP_%28Object_Oriented_Design%29" target="_blank" title="G.R.A.S.P"&gt;General Responsibility Assignment Software Patterns&lt;/a&gt;. In essence it's a very basic and straightforward pattern that helps to pinpoint what is the &lt;strong&gt;main&lt;/strong&gt; responsibility of a method or a class. Just ask yourself: "What is the &lt;strong&gt;real responsibility&lt;/strong&gt; of the method/class? &lt;strong&gt;Is it really&lt;/strong&gt; this method's/class's &lt;strong&gt;responsibility&lt;/strong&gt; to do &lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;that&lt;/span&gt;&lt;/strong&gt; operation?". By answering those questions it's possible to divide a system effectively to a lot of small, but cohesive objects, that really need to collaborate together in order to solve your business requirements (which is what &lt;a href="http://en.wikipedia.org/wiki/Object-oriented_analysis_and_design" target="_blank" title="OOD"&gt;Object Oriented Design&lt;/a&gt; is really about).&lt;br /&gt;&lt;br /&gt;So it comes, that though there is no "pattern to rule them all", using the Expert pattern/principle effectively, will allow you to rule your application.&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-5920190773393707095?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/lCgU9KDzFRs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/5920190773393707095/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/07/one-pattern-to-rule-them-all.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5920190773393707095?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/5920190773393707095?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/lCgU9KDzFRs/one-pattern-to-rule-them-all.html" title="One pattern to rule them all" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/07/one-pattern-to-rule-them-all.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8CRH88cSp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-7430726259441503543</id><published>2009-07-12T21:21:00.006+03:00</published><updated>2009-10-25T21:11:05.179+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T21:11:05.179+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Asymmetric Accessor Accessibility and Automatic Properties</title><content type="html">(Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Asymmetric Accessor Accessibility – &lt;/i&gt;is a feature that was introduced in .NET 2.0 in order to allow different accessibility levels to &lt;span style="color: blue;"&gt;get&lt;/span&gt; and &lt;span style="color: blue;"&gt;set&lt;/span&gt; portions of a property or an indexer. Those &lt;span style="color: blue;"&gt;get&lt;/span&gt; and &lt;span style="color: blue;"&gt;set&lt;/span&gt; portions are called a&lt;i&gt;ccessors&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
In the example below, the &lt;span style="color: blue;"&gt;get&lt;/span&gt; accessor is public, whereas the &lt;span style="color: blue;"&gt;set&lt;/span&gt; accessor is restricted and private.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-right-style: none; border-top-style: none; direction: ltr; line-height: 12pt; margin: 0em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; text-align: left; width: 100%;"&gt;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; id;
&lt;span style="color: green;"&gt;//...&lt;/span&gt;
&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Id
{
&lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; id; }
&lt;span style="color: blue;"&gt;private set&lt;/span&gt; { id = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }
}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;i&gt;Automatic Properties&lt;/i&gt; – is a syntactic sugar feature, introduced in .NET 3.5 to allow more concise property declaration.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-right-style: none; border-top-style: none; direction: ltr; line-height: 12pt; margin: 0em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; text-align: left; width: 100%;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Id {&lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;;}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The above features, can be combined together to form a very elegant and concise property declaration, with asymmetric accessibility levels:&lt;br /&gt;
&lt;br /&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;pre id="codeSnippet" style="background-color: #f4f4f4; border-bottom-style: none; border-right-style: none; border-top-style: none; direction: ltr; line-height: 12pt; margin: 0em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; text-align: left; width: 100%;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; Id {&lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;private set&lt;/span&gt;;}&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;Using “&lt;i&gt;automatic asymmetric accessibility properties&lt;/i&gt;” contributes to the clarity, elegance and correctness of the code.&lt;br /&gt;
&lt;br /&gt;
One of such examples is &lt;a href="http://msdn.microsoft.com/en-us/library/bb383979.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383979.aspx" target="_blank" title="Implement immutable class"&gt;immutable class implementation&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-7430726259441503543?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/dzJ0qI7lAyM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/7430726259441503543/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/07/asymmetric-accessor-accessibility-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/7430726259441503543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/7430726259441503543?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/dzJ0qI7lAyM/asymmetric-accessor-accessibility-and.html" title="Asymmetric Accessor Accessibility and Automatic Properties" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/07/asymmetric-accessor-accessibility-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eyp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-2981470722171834471</id><published>2009-06-12T18:16:00.005+03:00</published><updated>2009-10-25T20:58:11.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><title>A Cult Programmer</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last week, while conducting interviews for a Senior Software Engineer position, a candidate asked me a “red alert” question. A few moments after starting the interview and explaining the position, the candidate squeezed the following:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;“What is the current .NET framework you are using and are you planning to move to .NET 4.0?”&lt;/blockquote&gt;I bet you wonder… Is it really a “red alert” question?&lt;br /&gt;&lt;br /&gt;Allow me to elaborate. The candidate’s real motivation was to percept &lt;strong&gt;how technological&lt;/strong&gt; is the company that interviews him. If the company is stuck in .NET 1.X or it isn’t planning to move forward with Microsoft’s future plans, it just not technological enough.&lt;br /&gt;&lt;br /&gt;What alerts me is the idea that the specific version of framework used by the software is a measure to the software’s quality and not using a specific technology necessarily means something bad. Maybe the company utilizes the best practices of Software Development by applying: Analysis, Architecture &amp;amp; Design, Automatic Unit Testing, Static Code Analysis, Code Coverage, Integration Tests, Automatic Tests, Automatic Builds, Code Reviews, Peer Programming and etc… Maybe the company stands for writing &lt;strong&gt;quality&lt;/strong&gt; software by applying the Object Oriented Principles like &lt;a href="http://en.wikipedia.org/wiki/GRASP_(Object_Oriented_Design)" target="_blank" mce_href="http://en.wikipedia.org/wiki/GRASP_(Object_Oriented_Design)"&gt;GRASP&lt;/a&gt; (loose coupling / high cohesion), &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)" target="_blank" mce_href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;Design Patterns&lt;/a&gt;, &lt;a href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew" target="_blank" mce_href="http://blog.objectmentor.com/articles/2008/04/08/clean-code-whew"&gt;SOLID&lt;/a&gt; and etc…&lt;br /&gt;Maybe somebody forgot that a good quality software doesn’t mean necessary using the &lt;span style="color:#0000ff;"&gt;dynamic&lt;/span&gt; keyword?&lt;br /&gt;&lt;br /&gt;Allow me to emphasis. Technology is important! Choosing the &lt;strong&gt;right&lt;/strong&gt; technology for the &lt;strong&gt;specific&lt;/strong&gt; requirements of your application is important!&lt;br /&gt;However, a technology is not the key factor in the software’s success.&lt;br /&gt;It reminds me a good &lt;a href="http://www.joelonsoftware.com/articles/fog0000000339.html" target="_blank" mce_href="http://www.joelonsoftware.com/articles/fog0000000339.html"&gt;article&lt;/a&gt; discussing the technology leaps, by &lt;a href="http://www.joelonsoftware.com/" target="_blank" mce_href="http://www.joelonsoftware.com/"&gt;Joel Spolsky&lt;/a&gt;. Jumping from technology to technology seems to be just a plain “Fire and Motion”.&lt;br /&gt;&lt;br /&gt;If you are asked whether you are planning to move towards .NET X.X, just ask the candidate to explain, why (or what) in his opinion moving to .NET X.X will contribute to your application. Most of the time, as in my case, the answer will be quit generic: “It’s just a better technology”. This clearly, as explained above, doesn’t stand! Such a candidate is being marked often as a cult programmer. A Cult Programmer is a programmer who seems to compensate &lt;a href="http://urilavi.blogspot.com/2009/04/hunt-for-software-engineer.html" target="_blank" mce_href="http://urilavi.blogspot.com/2009/04/hunt-for-software-engineer.html"&gt;sound Software Engineering skills&lt;/a&gt; solely with a specific technology evolution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-2981470722171834471?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/e75uujQSpQI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/2981470722171834471/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/06/cult-programmer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2981470722171834471?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2981470722171834471?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/e75uujQSpQI/cult-programmer.html" title="A Cult Programmer" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/06/cult-programmer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eyp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-1532878652574202831</id><published>2009-05-30T23:49:00.022+03:00</published><updated>2009-10-25T20:58:11.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>Separate Domain from Presentation – part III</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a third post in the series of posts about “Separate Domain from Presentation” Refactoring.&lt;br /&gt;&lt;br /&gt;Previous Posts:&lt;br /&gt;&lt;a href="http://urilavi.blogspot.com/2009/04/separate-domain-from-presentation-part_18.html" target="_blank"&gt;Separate Domain from Presentation – part I&lt;/a&gt;&lt;br /&gt;&lt;a href="http://urilavi.blogspot.com/2009/05/separate-domain-from-presentation-part.html" target="_blank"&gt;Separate Domain from Presentation – part II&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last time we explained how to refactor towards MVP – Supervising Controller pattern.&lt;br /&gt;We left our project in the following state:&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SiGcdM0RrMI/AAAAAAAAADI/_SHjXrftpy8/s1600-h/SeparateDomainFromPresentation_AlmostMVP.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 308px; DISPLAY: block; HEIGHT: 202px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5341722658508745922" border="0" alt="" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SiGcdM0RrMI/AAAAAAAAADI/_SHjXrftpy8/s320/SeparateDomainFromPresentation_AlmostMVP.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;In this post I will complete the required refactoring steps and will suggest more steps to even deepen the separation of UI and BL concerns.&lt;br /&gt;&lt;br /&gt;Refactoring Steps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"&lt;span style="color:#800040;"&gt;Extract Interface&lt;/span&gt;" – in order to have a better encapsulation and separation of concerns, the CoursesPresenter shouldn’t access CoursesView directly. After all, the only functionality of interest to the CoursesPresenter is the CoursesView Courses property. Therefore, we will extract an interface from CoursesView class as follows: right click on the CoursesView class » Refactor » Extract Interface and select Courses property as shown in the figure below.&lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SiGdFv8mjHI/AAAAAAAAADQ/s1b_MsrlOvs/s1600-h/SeparateDomainFromPresentation_ExtractCoursesViewInterface.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 265px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5341723355133676658" border="0" alt="" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SiGdFv8mjHI/AAAAAAAAADQ/s1b_MsrlOvs/s320/SeparateDomainFromPresentation_ExtractCoursesViewInterface.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;In the CoursesPresenter class change all the occurrences of CoursesView to ICoursesView. &lt;/li&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;Last time we indicated that the presenter should handle complicated user events by subscribing to the view. After introducing the ICoursesView interface it’s simple. Add to the interface the following code: &lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt; LoadCourses;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt; SaveCourses;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Implement the newly added events in the CoursesView class: &lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#0000ff;"&gt; event&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt; LoadCourses;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#0000ff;"&gt; event&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt; SaveCourses;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;In the CoursesPresenter class rename the Load and Save methods to LoadCoursesEventHandler and SaveCoursesEventHandler respectively. Use right click » Refactor » Rename tool to rename it easily. &lt;/li&gt;&lt;li&gt;Wire-up the events in the CoursesPresenter constructor as follows: &lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CoursesPresenter(&lt;span style="color:#338c7e;"&gt;ICoursesView&lt;/span&gt; view)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.view = view;&lt;br /&gt;   view.LoadCourses += LoadCoursesEventHandler;&lt;br /&gt;   view.SaveCourses += SaveCoursesEventHandler;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;In the CoursesView class add the notification code: &lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; NotifyObservers(&lt;span style="color:#338c7e;"&gt;Delegate&lt;/span&gt; del)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#338c7e;"&gt;Delegate&lt;/span&gt;[] observers = del.GetInvocationList();&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#338c7e;"&gt;Delegate&lt;/span&gt; observer &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; observers)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt; action = observer &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;Action&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (action != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                action.DynamicInvoke();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#008000;"&gt;// graceful degradation.&lt;/span&gt;&lt;br /&gt;        }&lt;br /&gt;    }     &lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Change the CoursesView.Load and CoursesView.Save methods to call NotifyObservers respectively: &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; FrmMain_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#338c7e;"&gt;EventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;    NotifyObservers(LoadCourses);&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Save()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;    NotifyObservers(SaveCourses);&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;Now it is the time to remove all the temporary instantiations of the CoursesPresenter class in the Load and Save methods. Remove all the occurrences. &lt;/li&gt;&lt;li&gt;In the Program.cs class instead of Application.Run(new CoursesView()) write the following: &lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#338c7e;"&gt;CoursesView&lt;/span&gt; coursesView = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;CoursesView&lt;/span&gt;();&lt;br /&gt;   &lt;span style="color:#338c7e;"&gt;CoursesPresenter&lt;/span&gt; coursesPresenter = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#338c7e;"&gt;CoursesPresenter&lt;/span&gt;(coursesView);&lt;br /&gt;   &lt;span style="color:#338c7e;"&gt;Application&lt;/span&gt;.Run(coursesView);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;This concludes the “Separate Domain from Presentation” refactoring.&lt;br /&gt;We ended with the following: &lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SiGes7z8gvI/AAAAAAAAADY/AGjaPLed9FI/s1600-h/SeparateDomainFromPresentation_MVP.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 303px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5341725127845118706" border="0" alt="" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SiGes7z8gvI/AAAAAAAAADY/AGjaPLed9FI/s320/SeparateDomainFromPresentation_MVP.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;For next possible steps, consider the following: &lt;ul&gt;&lt;li&gt;Go over the CoursesView.Designer.cs and remove all the TableAdapter instances. &lt;/li&gt;&lt;li&gt;Create DAL and move Save and Load methods further more, from the presenter to the DAL. &lt;/li&gt;&lt;li&gt;Create the CoursesView and CoursesPresenter using &lt;a href="http://en.wikipedia.org/wiki/Abstract_factory_pattern" target="_blank"&gt;Abstract Factory&lt;/a&gt; or using &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank"&gt;Dependency Injection&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;a style="DISPLAY: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-1532878652574202831?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/POBCvp2YPnA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/1532878652574202831/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/05/separate-domain-from-presentation-part_30.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/1532878652574202831?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/1532878652574202831?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/POBCvp2YPnA/separate-domain-from-presentation-part_30.html" title="Separate Domain from Presentation – part III" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SiGcdM0RrMI/AAAAAAAAADI/_SHjXrftpy8/s72-c/SeparateDomainFromPresentation_AlmostMVP.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/05/separate-domain-from-presentation-part_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eyp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-2944093278443348780</id><published>2009-05-28T16:47:00.006+03:00</published><updated>2009-10-25T20:58:11.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>Var{i-able;}</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is a scoop; The good software engineer is lazy!&lt;br /&gt;You don’t believe me? Then ask yourself this: If a good software engineer was not lazy why would he:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Automate processes? &lt;/li&gt;&lt;li&gt;Reuse a function instead of duplicating its code? &lt;/li&gt;&lt;li&gt;Explicitly name a function for its behavior instead of naming a function F1 and providing a non descriptive (and possibly long) documentation? &lt;/li&gt;&lt;/ul&gt;Yet, here is another scoop; The bad software engineer is lazy too!&lt;br /&gt;While this statement clearly isn’t a shock to you, it immediately pop-ups the question:&lt;br /&gt;&lt;blockquote&gt;What is the difference? &lt;/blockquote&gt;The difference is that a &lt;strong&gt;good software engineer is lazy in a constructive way&lt;/strong&gt; (which allows to build reusable software and automated processes) &lt;strong&gt;while a bad software engineer is lazy in a destructive way&lt;/strong&gt; (which destroys any chance for a reusable software and dooms you for long hours of struggling to understand and fix the bad code).&lt;br /&gt;&lt;br /&gt;And here is a short example:&lt;br /&gt;The &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; keyword allows implicitly typed &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt;&lt;span style="color:#ff8000;"&gt;i&lt;/span&gt;&lt;span style="color:#800000;"&gt;able&lt;/span&gt; declaration.&lt;br /&gt;To tell the truth,&lt;strong&gt; it doesn’t allow to be a bad lazy software engineer! &lt;/strong&gt;&lt;br /&gt;Why bad? Take a look at the code below:&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; database = DatabaseFactory.CreateDatabase();&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;What is the meaning (meaning = type) of the database object in this context? Do I really need to guess that? Does somebody expect me to go to its definition to find out?&lt;br /&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(var observingStore &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; wareHouse.Stores)&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;What is the meaning of the observingStore object in this context? Was it named observingStore due to its implementation of the &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern" target="_blank" mce_href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer&lt;/a&gt; pattern (which implements IObserver), or is it just an object name of a Store, ObserverStore or even ArgicultureStore class type?&lt;br /&gt;&lt;br /&gt;Remember, you want to be lazy in a constructive way; You want to read those lines of code without wondering. You want to immediately grasp the meaning (types) of the objects you are dealing with, without switching the context and jumping to a different location just to refresh your memory.&lt;br /&gt;&lt;br /&gt;The &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; keyword was introduced for one and one purpose only; To allow usage of &lt;a href="http://msdn.microsoft.com/en-us/library/bb397696.aspx" target="_blank" mce_href="http://msdn.microsoft.com/en-us/library/bb397696.aspx"&gt;anonymous types&lt;/a&gt;. Therefore, this is the only place you should use it! &lt;strong&gt;Unless you are a bad lazy software engineer&lt;/strong&gt; (which clearly is not the case :) ) you will follow the rule!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-2944093278443348780?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/Kr8y1v5Zax0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/2944093278443348780/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/05/vari-able.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2944093278443348780?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2944093278443348780?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/Kr8y1v5Zax0/vari-able.html" title="Var{i-able;}" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/05/vari-able.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5eyp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-2932883646931920332</id><published>2009-05-18T22:40:00.055+03:00</published><updated>2009-10-25T20:58:11.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>Separate Domain from Presentation – part II</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a second post in the series of posts about “Separate Domain from Presentation” Refactoring.&lt;br /&gt;&lt;br /&gt;Previous Posts:&lt;br /&gt;&lt;a href="http://urilavi.blogspot.com/2009/04/separate-domain-from-presentation-part_18.html" target="_blank"&gt;Separate Domain from Presentation – part I&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Last time we discussed the ways to disconnect the Presentation (FrmMain) from the Domain Object (CoursesDS) in the IRefactor.CoursesView project. As a consequence, instead of the bloated all-in-one initial project we ended with the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IRefactor.CoursesView – represents the View (CoursesView) without the domain object.&lt;/li&gt;&lt;li&gt;IRefactor.Common – represents the domain object (CoursesDS) without the UI elements.&lt;/li&gt;&lt;/ul&gt;It’s time to continue the UI and BL separations further more. For that purpose I will use the MVP pattern. It seems that there are a lot of misunderstandings regarding definitions of the UI/BL separation patterns (take a look &lt;a href="http://martinfowler.com/eaaDev/uiArchs.html" target="_blank"&gt;here&lt;/a&gt;), I will focus on the following definitions:&lt;br /&gt;&lt;br /&gt;In my post, MVP = Model-View-Presenter will basically stand for:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Model – Hey, I am the domain model;&lt;br /&gt;&lt;strong&gt;I know&lt;/strong&gt; how to manipulate model objects in order to perform required application logic and persistency.&lt;br /&gt;&lt;strong&gt;I don’t know&lt;/strong&gt; how to visualize to the user any information or how to respond to any action the user may take. &lt;/li&gt;&lt;li&gt;View – Hey, I am the view model;&lt;br /&gt;&lt;strong&gt;I know&lt;/strong&gt; how to visually represent to the user information (that will be provided for me by the Presenter).&lt;br /&gt;&lt;strong&gt;I know&lt;/strong&gt; how to perform simple data binding and possible simple UI actions that modify the visual layout of the screen.&lt;br /&gt;&lt;strong&gt;I don’t know&lt;/strong&gt; what to do when an application logic or persistency are required. &lt;/li&gt;&lt;li&gt;Presenter – Hey, I am the presenter model;&lt;br /&gt;&lt;strong&gt;I know how&lt;/strong&gt; to handle user requests to the View (which are more complicated than a simple data binding) and how to delegate those requests to the Model.&lt;br /&gt;&lt;strong&gt;I know how&lt;/strong&gt; to query the Model in order to delegate information to the View, if any should be displayed to the user.&lt;br /&gt;&lt;strong&gt;I don’t know&lt;/strong&gt; how to draw widgets graphically (that’s View’s concern) and &lt;strong&gt;I don’t know&lt;/strong&gt; how to perform any application logic in order to derive that information (that’s Model’s concern). &lt;/li&gt;&lt;/ul&gt;Those who have sharp eyes, will probably spot here the use of a Supervising Controller (that doesn’t introduce right away drastic changes to the code in the spirit of Refactoring. Later on, one could turn the View into the Passive View while continuing to refactor).&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://1.bp.blogspot.com/_6qKL-Tf2QeM/ShG7qzZCwEI/AAAAAAAAACo/f4qua19L2-0/s1600-h/MVP.Supervising+Controller.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 258px; DISPLAY: block; HEIGHT: 191px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5337253377434894402" border="0" alt="MVP - Supervising Controller" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/ShG7qzZCwEI/AAAAAAAAACo/f4qua19L2-0/s320/MVP.Supervising+Controller.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Refactoring Steps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Rename the IRefactor.CoursesView.FrmMain class to CoursesView. Go to FrmMain, right click on it and use Refactor » Rename command to rename it easily.&lt;/li&gt;&lt;li&gt;Create a class CoursesPresenter in IRefactor.CoursesView.&lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/ShG8fXnpghI/AAAAAAAAACw/0-IYyomZpRk/s1600-h/SeparateDomainFromPresentation.CoursesPresenter.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 184px; DISPLAY: block; HEIGHT: 197px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5337254280513028626" border="0" alt="SeparateDomainFromPresentation.CoursesPresenter" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/ShG8fXnpghI/AAAAAAAAACw/0-IYyomZpRk/s320/SeparateDomainFromPresentation.CoursesPresenter.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Add to CoursesPresenter class a pointer to the CoursesView (pay attention to the fact that the view is readonly)&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CoursesPresenter&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; CoursesView view;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Add to CoursesPresenter a constructor that receives CoursesView instance.&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CoursesPresenter(CoursesView view)&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.view = view;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests.&lt;/li&gt;&lt;li&gt;Now we need to delegate user’s interactions from the view to the presenter. We can do it rather by inheriting the &lt;span style="color:#0000ff;"&gt;EventArgs&lt;/span&gt; and creating a CoursesEventArgs class, or we can let the CoursesPresenter query directly the CoursesView and grab the required data. Here I’ll grab the CoursesDS domain object directly. Add to the CoursesView the following:&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CoursesDS Courses&lt;br /&gt;{&lt;br /&gt; get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; coursesDS; }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Let’s start with the Save event delegation. If you look closely at the coursesBindingNavigatorSaveItem_Click event handler, you will notice that the method has &lt;strong&gt;two&lt;/strong&gt; different &lt;strong&gt;responsibilities&lt;/strong&gt;. It treats the required data binding and then performs data access operation in order to save the CoursesDS domain object. To separate the concerns, let's use another Refactoring step called “&lt;span style="color:#800040;"&gt;Extract Method&lt;/span&gt;”. Select the data access code, right click on it and use Refactor » Extract Method command to extract the code into a new method called “Save”.&lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/ShG-O6Q839I/AAAAAAAAAC4/jNv9l4RcVfc/s1600-h/SeparateDomainFromPresentation.SaveItem.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 205px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5337256196778549202" border="0" alt="SeparateDomainFromPresentation.SaveItem" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/ShG-O6Q839I/AAAAAAAAAC4/jNv9l4RcVfc/s320/SeparateDomainFromPresentation.SaveItem.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Validate();&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.bsCourses.EndEdit();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Changed from auto generated code.&lt;/span&gt;&lt;br /&gt;Save();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Save()&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (coursesDS.HasChanges())&lt;br /&gt;   {&lt;br /&gt;       CoursesDS.CoursesDataTable changes =&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.coursesDS.Courses.GetChanges() &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt;&lt;br /&gt;               CoursesDS.CoursesDataTable;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (changes != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;       {&lt;br /&gt;           taCourses.Update(changes);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests.&lt;/li&gt;&lt;li&gt;After breaking the coursesBindingNavigatorSaveItem_Click method we suddenly realize that the Save method doesn’t belong to the CoursesView class as it does a data access operation. By all means this operation should be inside the domain model (business logic). In the meanwhile we will push the method inside the presenter.&lt;/li&gt;&lt;li&gt;In CoursesPresenter create a new method called Save. The method will retrieve the CoursesDS domain object from the CoursesView and save the object into the DB.&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Save()&lt;br /&gt;{&lt;br /&gt;   CoursesDS coursesDS = view.Courses;&lt;br /&gt;   &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests.&lt;/li&gt;&lt;li&gt;Copy all the code from the CoursesView.Save method into the CoursesPresenter.Save method and adjust the new code to its new “place” (pay attention to the CoursesTableAdapter that needs to be redefined).&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Save()&lt;br /&gt;{&lt;br /&gt;    CoursesDS coursesDS = view.Courses;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (coursesDS.HasChanges())&lt;br /&gt;    {&lt;br /&gt;        CoursesDS.CoursesDataTable changes =&lt;br /&gt;            coursesDS.Courses.GetChanges()&lt;br /&gt;                &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; CoursesDS.CoursesDataTable;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (changes != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (CoursesTableAdapter taCourses = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CoursesTableAdapter())&lt;br /&gt;           {&lt;br /&gt;               taCourses.Update(changes);&lt;br /&gt;           }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution.&lt;/li&gt;&lt;li&gt;Now, for the fun part; Put all the code within the CoursesView.Save method inside remarks and declare CoursesPresenter object that calls to its Save method.&lt;/li&gt;&lt;/ul&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Save()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//if (coursesDS.HasChanges())&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//    CoursesDS.CoursesDataTable changes =&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//        this.coursesDS.Courses.GetChanges()&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//            as CoursesDS.CoursesDataTable;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//    if (changes != null)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//    {&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//        taCourses.Update(changes);&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//    }&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//}&lt;/span&gt;&lt;br /&gt;    CoursesPresenter presenter = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CoursesPresenter(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;);&lt;br /&gt;    presenter.Save();&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Walla!&lt;/strong&gt; You have successfully moved a data access method from the view to the presenter. With continuous refactoring you can push that method even further in the data access layer.&lt;/li&gt;&lt;/ul&gt;A quick summary:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We introduced a new presenter class, called CoursesPresenter.&lt;/li&gt;&lt;li&gt;We moved the Save method (which does a data access operation) from the view into the presenter class. (Don’t worry we will eliminate the Save method from the CoursesView in the next post.)&lt;/li&gt;&lt;li&gt;The same should be applied to the Load method (FrmMain_Load). I won’t show it here, just use the same principle.&lt;/li&gt;&lt;/ul&gt;Here is the schematic view of the current IRefactor.CoursesView project.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/ShHBKJeolMI/AAAAAAAAADA/Kakx9k8pxxs/s1600-h/SeparateDomainFromPresentation.MVP.jpg"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 301px; DISPLAY: block; HEIGHT: 200px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5337259413498008770" border="0" alt="SeparateDomainFromPresentation.MVP" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/ShHBKJeolMI/AAAAAAAAADA/Kakx9k8pxxs/s320/SeparateDomainFromPresentation.MVP.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Clearly, it’s not the same as the MVP pattern we depicted earlier. Future postings will explain additional steps to refactor towards the MVP pattern, by applying:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Events – the presenter handles complicated user events by subscribing to the view.&lt;/li&gt;&lt;li&gt;Interfaces – the presenter should manipulate the view only via an interface.Failing to do so, will break the view’s encapsulation.&lt;/li&gt;&lt;/ul&gt;References:&lt;br /&gt;Take a look &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx" target="_blank"&gt;here&lt;/a&gt; for a good summary on Smart Client development.&lt;br /&gt;&lt;a style="DISPLAY: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag"&gt;codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-2932883646931920332?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/NHdyLERqkf0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/2932883646931920332/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/05/separate-domain-from-presentation-part.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2932883646931920332?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/2932883646931920332?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/NHdyLERqkf0/separate-domain-from-presentation-part.html" title="Separate Domain from Presentation – part II" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6qKL-Tf2QeM/ShG7qzZCwEI/AAAAAAAAACo/f4qua19L2-0/s72-c/MVP.Supervising+Controller.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/05/separate-domain-from-presentation-part.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5fCp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3847831202681024127</id><published>2009-04-29T22:02:00.007+03:00</published><updated>2009-10-25T20:58:11.224+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.224+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Agile" /><title>Shooting without Aiming</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/" target="_blank"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;During my lectures on “Refactoring &amp;amp; Design” I am frequently amazed to hear the following ideas:&lt;br /&gt;&lt;blockquote&gt;“Doesn’t Design &lt;strong&gt;contradict&lt;/strong&gt; Agile? Isn’t Agile about gaining speed, while Design about gaining bureaucracy?” - some ask.&lt;br /&gt;“Why bother with Design? Eventually It’s &lt;strong&gt;impossible&lt;/strong&gt; to do any design when using Agile methods, like TDD” - others continue.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I often compare the aforementioned questions to “&lt;span style="color:#008000;"&gt;Shooting without Aiming&lt;/span&gt;”. It won’t occur to shoot at a target without first aiming at it. The rule is true, especially when the time is short and every shot counts; &lt;strong&gt;You will spend an extra minute just to aim it well!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Shooting after Aiming is “life saving”!&lt;br /&gt;So, How does it even come to any mind to code &lt;strong&gt;without thinking&lt;/strong&gt;(thinking=Design)?&lt;br /&gt;&lt;br /&gt;Please, don’t take my word on it. See what &lt;a href="http://blog.objectmentor.com/" target="_blank"&gt;Robert C. Martin&lt;/a&gt; has to say about &lt;a href="http://blog.objectmentor.com/articles/2009/04/25/the-scatology-of-agile-architecture"&gt;The Scatology of Agile Architecture&lt;/a&gt;. Robert C. Martin knows a thing or two about Agile Development. After all, he was the originator of the meeting that led up to &lt;a href="http://agilemanifesto.org/"&gt;The Agile Manifesto&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3847831202681024127?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/A_wokf37iME" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3847831202681024127/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/04/shooting-without-aiming.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3847831202681024127?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3847831202681024127?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/A_wokf37iME/shooting-without-aiming.html" title="Shooting without Aiming" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/04/shooting-without-aiming.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5fCp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-3730874115748173871</id><published>2009-04-24T16:09:00.008+03:00</published><updated>2009-10-25T20:58:11.224+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.224+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term="Anti-Patterns" /><title>Dude, I blew up the Demo!</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am sure, we are &lt;strong&gt;ALL&lt;/strong&gt; familiar with the situation:&lt;br /&gt;&lt;br /&gt;Morning… The sun is shining, the birds are chirping… You are sitting in front of your computer, sipping a delicious cup of coffee. Then, in the corner of your eye, you spot movement; your VP Marketing approaches you with a big smile on his face:&lt;br /&gt;&lt;blockquote&gt;“Jonathan”, he says, “Just got important news, we have a big opportunity! We have been requested to demonstrate our super complex web analysis capabilities to a huge potential client. Could we build a quick demo?”&lt;/blockquote&gt;You sigh and start coding…&lt;br /&gt;&lt;br /&gt;You don't sleep neither eat; you copy and paste; you code; you build and execute and after stressful (but, yes, enjoyable) five days you provide a top-notch Demo.&lt;br /&gt;&lt;br /&gt;The new “toy” becomes the hottest news in the office.&lt;br /&gt;It’s cool, it's fast, it's colorful and it demonstrates an innovative functionality and thinking!&lt;br /&gt;&lt;br /&gt;The VP Marketing is in heaven; he presents the demo to the client and gets an enthusiastic response.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;“Jonathan”, his eyes are gleaming, “They are excited! They just need a small feature - export to excel, to evaluate it a little bit more.”&lt;/blockquote&gt;You return to the operating table and add some “quick &amp;amp; dirty” code to export the analysis to excel. &lt;blockquote&gt;“Jonathan”, your VP Marketing, “Great work! Could you also add a small feature of notification by email?”&lt;/blockquote&gt;A few days later… &lt;blockquote&gt;“Jonathan, Well done!, Could you also add…”&lt;/blockquote&gt;A year later, you find yourself &lt;span style="color:#ff0000;"&gt;maintaining&lt;/span&gt; the demo and cursing that cheerful morning you had agreed to develop the goddamned application!&lt;br /&gt;&lt;br /&gt;If you ask your VP Marketing what happened, he will honestly say: &lt;strong&gt;“Dude, I blew up the demo!”&lt;/strong&gt; Remember the &lt;a href="http://www.youtube.com/watch?v=nG7zCxDz9x8" target="_blank"&gt;Honey, I blew up the kid!&lt;/a&gt;? Your VP Marketing, "accidentally", blew up your five days old “child” into a giant “monster”.&lt;br /&gt;&lt;br /&gt;It’s common for a small-mid size companies to turn their “demo” applications into production ones. The “time to market” is crucial; once the demo was introduced successfully, the features are added patches over patches resulting in a &lt;a href="http://msmvps.com/blogs/peterritchie/archive/2009/01/27/house-of-cards-design-anti-pattern.aspx" target="_blank"&gt;House of Cards AntiPattern&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;House of Cards&lt;/span&gt; &lt;span style="color:#008000;"&gt;AntiPattern&lt;/span&gt; – a continuous patch (card) over patch (card) which is done in order to correct a bug or to add a focused feature without design or refactoring considerations.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;Even in a small demo application, there is a place for a careful examination of the developed features&lt;/span&gt;. You can make assumptions; you can &lt;a href="http://urilavi.blogspot.com/2009/04/separate-domain-from-presentation-part_18.html" target="_blank"&gt;speed-up the UI development&lt;/a&gt;, but you need to design the &lt;strong&gt;core&lt;/strong&gt; features, as you develop the production code:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Separate the Domain from the Presentation, using &lt;a href="http://en.wikipedia.org/wiki/Model_View_Presenter" target="_blank"&gt;MVP&lt;/a&gt; pattern for example. &lt;/li&gt;&lt;li&gt;Use &lt;a href="http://en.wikipedia.org/wiki/Facade_pattern" target="_blank"&gt;Façades&lt;/a&gt; to shadow the BL. &lt;/li&gt;&lt;li&gt;Provide a well organized BL. (Don’t try to address all the future possibilities and requirements. Just provide good object oriented basis). &lt;/li&gt;&lt;li&gt;Don’t duplicate code, don’t provide lengthy and hard to read methods. &lt;/li&gt;&lt;li&gt;Provide Unit Tests and test the BL as much as possible. &lt;/li&gt;&lt;li&gt;Deal with “considerable”exceptional situations (It’s OK to decide not to deal with uncommon demo scenarios). &lt;/li&gt;&lt;/ul&gt;Notice, it is perfectly fine to make assumptions and to apply some limitations during the demo development. However, building the demo correctly will ease the move to the production, even if a certain feature is redesigned or redeveloped.&lt;br /&gt;Undoubtedly, it will ease the development of any additional “demo” features for more potential clients.&lt;br /&gt;&lt;br /&gt;As for the managers, try to remember; unless you want to make excuses for &lt;span style="color:#ff0000;"&gt;unmaintainable&lt;/span&gt; and &lt;span style="color:#ff0000;"&gt;hard to change code&lt;/span&gt;, you need to allow your development teams to work a little bit longer, just to produce a better demo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-3730874115748173871?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/OxDNCCm1mUc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/3730874115748173871/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/04/cross-post-from-irefactor-i-am-sure-we.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3730874115748173871?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/3730874115748173871?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/OxDNCCm1mUc/cross-post-from-irefactor-i-am-sure-we.html" title="Dude, I blew up the Demo!" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/04/cross-post-from-irefactor-i-am-sure-we.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5fCp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-6439076929622551228</id><published>2009-04-18T16:51:00.022+03:00</published><updated>2009-10-25T20:58:11.224+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.224+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Refactoring" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>Separate Domain from Presentation – Part I</title><content type="html">Cross post from &lt;a href="http://www.irefactor.net/"&gt;IRefactor&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;Visual Studio can be a swiss knife in the hands of a Software Developer.
&lt;br /&gt;
&lt;br /&gt;You want a fully functional application within several hours; here you go sir:
&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create Windows Forms Application.&lt;/li&gt;&lt;li&gt;Add relevant Data Sources (in Figure 1 below: Courses table). &lt;/li&gt;&lt;li&gt;Drag generated entities from the Data Sources onto relevant Forms. &lt;/li&gt;&lt;li&gt;Add minimum code to show the Forms in the required order.&lt;/li&gt;&lt;li&gt;Compile &amp;amp; execute.&lt;/li&gt;&lt;/ul&gt;Walla, I present you an “enterprise application”!
&lt;br /&gt;Though it looks amateur, it allows fully functional CRUD operations.
&lt;br /&gt;
&lt;br /&gt;&lt;div align="center"&gt;&lt;strong&gt;Figure 1&lt;/strong&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SenhUv6h6wI/AAAAAAAAABw/q_vWlTXsSHk/s1600-h/SeparateDomainFromPresentation.CoursesView.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 258px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326035780917914370" border="0" alt="" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SenhUv6h6wI/AAAAAAAAABw/q_vWlTXsSHk/s320/SeparateDomainFromPresentation.CoursesView.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;span style="color:#e80000;"&gt;But, the power can corrupt…&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;Lately, I came across a few projects implemented using the above approach. Needless to say, the projects were “spaghetti code” - all the UI elements, visual states, business logic &amp;amp; data access, were centralized within a few Forms.
&lt;br /&gt;
&lt;br /&gt;(Don't think it's a rare situation! There are enough companies that try to "save" time using such a “quick &amp;amp; dirty” approach).
&lt;br /&gt;
&lt;br /&gt;I am a pragmatic Software Engineer and I do believe that the “quick &amp;amp; dirty” approach is vital in some cases.
&lt;br /&gt;If you present a demo application that demonstrates your capabilities; go ahead, use the necessary tools to implement it as fast as possible.
&lt;br /&gt;
&lt;br /&gt;However, if you develop a real life applications using the above approach it’s &lt;strong&gt;a sure road to hell&lt;/strong&gt;. Slowly but surely the “fast development” takes more and more time:
&lt;br /&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;The customer’s button event click is very similar to the employee’s event click, but correlate and update different UI elements » you duplicate the logic in both places. &lt;/li&gt;&lt;li&gt;New requirement add new conditions to some wizard flow » you add an “if” statement to address the conditions. Sometimes you add a “switch” statement due to the fact that many “ifs” already exist. &lt;/li&gt;&lt;li&gt;New requirements impose saving more data » you add more parameters to your methods. You also go further and add those parameters to each and every place (form/method) where the change is required. &lt;/li&gt;&lt;li&gt;The classes and methods become huge, they are overcrowded with UI elements, visual states transformations and business logic. Next time you try to read the code, you will need at least a few hours to concentrate and walk through the mess. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Project Manager responsible for the aforementioned projects, said to me:
&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;“Any change request I want to apply, come back with unrealistic time estimations. When I ask the developer why it takes so long, he answers: My Gosh – do you &lt;strong&gt;know&lt;/strong&gt; what it takes to change &lt;strong&gt;that&lt;/strong&gt; code? Do you &lt;strong&gt;understand&lt;/strong&gt; &lt;strong&gt;how long&lt;/strong&gt; I need to retest the application, just to verify I didn’t break anything?”
&lt;br /&gt;&lt;/blockquote&gt;
&lt;br /&gt;It seems obvious that if in the first place, the project had been written in clear separation of UI, Business Logic and Data Access Layers, it would have been easier to maintain the product lifetime. However, clearly it is not the case here, so what can we do?
&lt;br /&gt;
&lt;br /&gt;One of the tools we can apply here is: &lt;a href="http://en.wikipedia.org/wiki/Refactoring" target="_blank"&gt;Refactoring&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;&lt;span style="color:#008000;"&gt;Refactoring is a process of improving software’s internal structure without changing its external behavior&lt;/span&gt;. Refactoring ensures completeness of the external behavior, by executing automatic unit tests. We improve the code in incremental small steps (refactoring steps) and each change is followed by a compilation and unit tests execution.
&lt;br /&gt;
&lt;br /&gt;In the following posts I will demonstrate refactoring called “Separate Domain from Presentation”, which obviously breaks the tight coupling between UI and BL. After finishing the demonstrations of the refactoring process itself (it will take me several posts to do it) I will also explain how to create the suite of unit tests, which allow validation of external behavior completeness.
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;Remarks:
&lt;br /&gt;
&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I will refactor the application from figure 1 (above).
&lt;br /&gt;The application contains one View (FrmMain) and one domain object (CoursesDS). &lt;/li&gt;&lt;li&gt;Though the sample application contains one &lt;span style="color:#0000ff;"&gt;Form&lt;/span&gt; and one &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt;, the same technique can be applied in more complicated situations. Just identify the groups of objects that fit together and apply for each one of them the following steps of separation.&lt;/li&gt;&lt;li&gt;It’s advisable to download the sample &lt;a href="http://sites.google.com/site/irefactor/storage/SeparateDomainFromPresentation.zip" target="_blank"&gt;IRefactor.CoursesView&lt;/a&gt; project and go through the refactoring steps while reviewing the code. &lt;/li&gt;&lt;li&gt;In the next posts I will introduce how to enhance the separation using refactoring towards MVP (or MVC) patterns. &lt;/li&gt;&lt;li&gt;It’s harder to write about the refactoring process, than actually implement it. Don’t be intimidated, it takes longer to explain each and every small step (and provide screenshots) than to do it in practice. To Separate Domain from Presentation (up to MVP) takes me about 10 min of work. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Refactoring steps: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;When the Irefactor.CoursesView project was defined initially, Visual Studio generated a &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt; called CoursesDS for the Courses Data Source. As you can see, the Irefactor.CoursesView project mixes UI (FrmMain) elements and Domain (CoursesDS) elements.
&lt;br /&gt;
&lt;br /&gt;&lt;div align="center"&gt;&lt;strong&gt;Figure 2&lt;/strong&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SenkMZ8WkvI/AAAAAAAAAB4/wG2sp45-ly0/s1600-h/SeparateDomainFromPresentation_InitialProject.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 191px; DISPLAY: block; HEIGHT: 132px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326038936115909362" border="0" alt="" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SenkMZ8WkvI/AAAAAAAAAB4/wG2sp45-ly0/s320/SeparateDomainFromPresentation_InitialProject.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Let’s start by removing the CoursesDS domain object from the UI (View).
&lt;br /&gt;Create a project IRefactor.Common and copy there CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt;.
&lt;br /&gt;(Drag the CoursesDS from project to project, Visual Studio will do the rest).
&lt;br /&gt;
&lt;br /&gt;Due to the fact that CoursesDS is a VS auto generated class, one should also copy the connection string definition which is stored in the Settings of the IRefactor.CoursesView project. Add Settings.settings to IRefactor.Common Properties folder and copy the connection string.
&lt;br /&gt;
&lt;br /&gt;&lt;div align="center"&gt;&lt;strong&gt;Figure 3&lt;/strong&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SenlcmqSjUI/AAAAAAAAACA/94YvgyltrZU/s1600-h/SeparateDomainFromPresentation_AddingCommon.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 201px; DISPLAY: block; HEIGHT: 218px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326040313919343938" border="0" alt="" src="http://4.bp.blogspot.com/_6qKL-Tf2QeM/SenlcmqSjUI/AAAAAAAAACA/94YvgyltrZU/s320/SeparateDomainFromPresentation_AddingCommon.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;Change the FrmMain (View) to use the newly created IRefactor.Common.CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt;.
&lt;br /&gt;Open the FrmMain’s designer. Remove the coursesDS (the instance of the domain object: IRefactor.CoursesView.CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt; – see red arrow 1). &lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;&lt;strong&gt;Figure 4&lt;/strong&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SenmaF0SXjI/AAAAAAAAACI/eoxG0MhE8qE/s1600-h/SeparateDomainFromPresentation_FrmMain.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 213px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326041370254794290" border="0" alt="" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SenmaF0SXjI/AAAAAAAAACI/eoxG0MhE8qE/s320/SeparateDomainFromPresentation_FrmMain.png" /&gt;&lt;/a&gt;
&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;On the Toolbox window, under the recently added IRefactor.Common Components you will see the IRefactor.Common.CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt;.
&lt;br /&gt;Drag this CoursesDS to the FrmMain Form.&lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;&lt;strong&gt;Figure 5&lt;/strong&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_6qKL-Tf2QeM/Senmy-GsbPI/AAAAAAAAACQ/ubKn28dqrZc/s1600-h/SeparateDomainFromPresentation_Toolbox.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 150px; DISPLAY: block; HEIGHT: 224px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326041797681245426" border="0" alt="" src="http://3.bp.blogspot.com/_6qKL-Tf2QeM/Senmy-GsbPI/AAAAAAAAACQ/ubKn28dqrZc/s320/SeparateDomainFromPresentation_Toolbox.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Dragging the IRefactor.Common.CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt; onto the FrmMain surface generates an instance of the class. Rename it to coursesDS (to match the previous name).&lt;/li&gt;&lt;li&gt;Repeat the three last steps also for IRefactor.CoursesView.CoursesTableAdapter (see Figure 4, red arrow 2)&lt;/li&gt;&lt;li&gt;Select the &lt;span style="color:#0000ff;"&gt;BindingSource&lt;/span&gt; (see Figure 4, bsCourses) and change its &lt;span style="color:#0000ff;"&gt;DataSource&lt;/span&gt; to coursesDS instance (coursesDS now comes from IRefactor.Common project). Also change its &lt;span style="color:#0000ff;"&gt;DataMember&lt;/span&gt; to point the Courses table. &lt;/li&gt;&lt;/ul&gt;&lt;p align="center"&gt;&lt;strong&gt;Figure 6&lt;/strong&gt;
&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SennLzUr8FI/AAAAAAAAACY/crEFsWpmx_M/s1600-h/SeparateDomainFromPresentation_BindingSource.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 226px; DISPLAY: block; HEIGHT: 255px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5326042224283873362" border="0" alt="" src="http://2.bp.blogspot.com/_6qKL-Tf2QeM/SennLzUr8FI/AAAAAAAAACY/crEFsWpmx_M/s320/SeparateDomainFromPresentation_BindingSource.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;In FrmMain code behind file add reference to the IRefactor.Common namespace and change the CoursesDS to a fully qualified name.&lt;/li&gt;&lt;/UL&lt;div id="codeSnippetWrapper"&gt;
&lt;br /&gt;&lt;pre style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; DIRECTION: ltr; BORDER-TOP-STYLE: none; BACKGROUND-: 0emcolor:#f4f4f4;" id="codeSnippet" &gt;&lt;span style="color:#008000;"&gt;// add reference&lt;/span&gt;
&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; IRefactor.Common;
&lt;br /&gt;
&lt;br /&gt;&lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; coursesBindingNavigatorSaveItem_Click
&lt;br /&gt;{
&lt;br /&gt;(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)
&lt;br /&gt;  &lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;  &lt;span style="color:#008000;"&gt;// change the coursesDS to IRefactor.Common.CoursesDS&lt;/span&gt;
&lt;br /&gt;  IRefactor.Common.CoursesDS.CoursesDataTable changes =
&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.coursesDS.Courses.GetChanges()
&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IRefactor.Common.CoursesDS.CoursesDataTable;
&lt;br /&gt;  &lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;
&lt;br /&gt;}&lt;/pre&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;li&gt;Go over IRefactor.CoursesView and remove all instances of the previous domain object IRefactor.CoursesView.CoursesDS &lt;span style="color:#0000ff;"&gt;DataSet&lt;/span&gt;. Also, delete the CoursesDS.xsd file from the project. &lt;/li&gt;&lt;li&gt;Compile the Solution and execute the Unit Tests. &lt;/li&gt;&lt;/ul&gt;We have successfully completed the first steps. We have separated the UI project called IRefactor.CoursesView from the Domain Project called IRefactor.Common. Now it’s time to become serious and continue the refactoring towards the MVP pattern.
&lt;br /&gt;
&lt;br /&gt;&lt;a style="DISPLAY: none" href="http://www.codeproject.com/script/Articles/BlogFeedList.aspx?amid=86199" rel="tag"&gt;codeproject &lt;/a&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-6439076929622551228?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/lKqNFIK4kR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/6439076929622551228/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/04/separate-domain-from-presentation-part_18.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6439076929622551228?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/6439076929622551228?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/lKqNFIK4kR4/separate-domain-from-presentation-part_18.html" title="Separate Domain from Presentation – Part I" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_6qKL-Tf2QeM/SenhUv6h6wI/AAAAAAAAABw/q_vWlTXsSHk/s72-c/SeparateDomainFromPresentation.CoursesView.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/04/separate-domain-from-presentation-part_18.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNQHw5fCp7ImA9WxNVFEQ.&quot;"><id>tag:blogger.com,1999:blog-5286282305278386798.post-4727655626339936624</id><published>2009-04-18T00:30:00.003+03:00</published><updated>2009-10-25T20:58:11.224+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T20:58:11.224+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Peopleware" /><category scheme="http://www.blogger.com/atom/ns#" term="Development" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><title>The Hunt for a Software Engineer</title><content type="html">&lt;font size="2"&gt;   &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;Cross post from &lt;a href="http://blogs.microsoft.co.il/blogs/uri_lavi/archive/2009/04/12/the-hunt-for-software-engineer.aspx" target="_blank"&gt;IRefactor&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;This week I had interesting discussions regarding hiring and interviewing professional personnel. &lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;The reason it was so interesting, is the fact that the discussions were raised simultaneously by two friends of mine, each from his unique point of view.&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="3" face="Calibri"&gt;David is a R&amp;amp;D Manager who leads successfully a complicated software project written in .NET technologies.&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;David tries to hire a Software Engineer with specific experience in Smart Clients and Complicated Servers applications but without any success.&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;David complaints that most of the candidates he meets have a superficial knowledge and don’t meet his expectations.&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="3" face="Calibri"&gt;Daniel is a talented Software Engineer whose major experience is in ASP.NET, willing to change his place of work. Daniel is a very dedicated person; he attends almost each and every summit he can on .NET technologies. He also reads quite a lot of blogs and articles in order to enhance his knowledge.&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;Daniel had already attended more than dozen interviews, most of which he failed because he was unable to solve some “tricky” (according to his words) questions. &lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;By “tricky”, he gives an example of: “Given a uniformly distributed function between 0 to 1 write a function that generates unique numbers from 1 to N in complexity of O(…) and …” and that’s there he loses his nerve.&lt;/font&gt;&lt;/p&gt;    &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="3" face="Calibri"&gt;“What the hack”, he says to me, “The company even doesn’t deal with any statistical or mathematical computations, all it does is pretty standard enterprise application; retrieve, show and update”. &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="3" face="Calibri"&gt;On the one hand it is ridiculous that Daniel cannot pass interviews, but on the other hand it is also true that we lack good Software Engineers. &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="3" face="Calibri"&gt;&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="3" face="Calibri"&gt;But wait, could it be that the problem is within our industry (or us)? &lt;/font&gt;&amp;#160;&lt;/p&gt;   &lt;font size="3" face="Calibri"&gt;     &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Understanding that there is a need to hire a new Software Engineer mostly comes too late (in the project’s schedule).&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;As a consequence, due to time constraints, there is no time to train the new employee. Therefore the employee must meet very rigorous requirements.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;In order to ensure those requirements (that vary a lot from company to company, based on their line of business), the interviewer tries to infer candidate’s competence using one of the following tools: &lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 1in; mso-list: l0 level2 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: &amp;#39;Courier New&amp;#39;; mso-fareast-font-family: &amp;#39;Courier New&amp;#39;"&gt;&lt;span style="mso-list: ignore"&gt;o&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Ask domain specific question, based on the interviewer’s (or his company) experience or immediate needs.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 1in; mso-list: l0 level2 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: &amp;#39;Courier New&amp;#39;; mso-fareast-font-family: &amp;#39;Courier New&amp;#39;"&gt;&lt;span style="mso-list: ignore"&gt;o&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Ask “quiz” questions, question that can be solved using some tweaking.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt 0.5in" class="MsoNoSpacing"&gt;The interviewer forgets &lt;a title="Peopleware" href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439" target="_blank" mce_href="http://www.amazon.com/Peopleware-Productive-Projects-Teams-Second/dp/0932633439"&gt;Peopleware&lt;/a&gt; which clarifies: “Major problems of our work are not so much &lt;b&gt;technological as sociological&lt;/b&gt; in nature.” &lt;em&gt;Failing to answer a tweaking (“a-ha”) question isn’t a virtue you would like to judge on&lt;/em&gt;.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Finally, candidates that somehow meet the requirements are being hired, which deepens and narrows their experience in the long running term.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing" mce_keep="true"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;A good candidate doesn’t need to know how to tweak a domain specific problem within an hour. Moreover, a good candidate doesn’t need to be a specialist in Smart Clients applications.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;Don’t get me wrong, if such a candidate appears during the interviewing process I will gladly hire him (if I need such a skill for long term).&lt;/p&gt;      &lt;p&gt;However, if your projects and recourses are planed correctly, you can loosen your requirements a bit. &lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I have always believed that a Software Engineer should be as versatile as possible and therefore the minimum bare requirement I seek is a &lt;b&gt;&lt;i&gt;very strong&lt;/i&gt;&lt;/b&gt; software engineering background.&lt;/p&gt;      &lt;p&gt;In my opinion, a Software Engineer must &lt;strong&gt;understand in different &lt;font color="#000080"&gt;“tools of trade”&lt;/font&gt;&lt;/strong&gt;. He needs to know why it is better to apply this pattern or that pattern, when it is suitable to use Smart Client applications and when it is not, how to build good infrastructure and clean software and etc… etc… &lt;/p&gt;      &lt;p&gt;Having good software engineering skills, doesn’t mean you don’t need to specialize vertically in a specific field.&lt;span style="mso-spacerun: yes"&gt;&amp;#160; &lt;/span&gt;With the correct mentoring and coaching, candidate’s experience in several disciplines he chooses, will evolve with years (and this can be a whole another post) and I even expect it to happen. &lt;/p&gt;      &lt;p&gt;And that’s how, my conversations with David and Daniel this week ended by discussing how do I find this bare minimum in the candidates, using &lt;strong&gt;technology questions&lt;/strong&gt; and without any tricky (“a-ha”) approaches (of course there are also non technology question that I ask during the interview in order to review candidate’s soft skills).&lt;/p&gt;      &lt;p&gt;Here are the virtues that I try to pursue during an interview:&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;A candidate must show a strong understanding of Software Engineering principles&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;A candidate must be able to learn and evolve with the time.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;A candidate must have a &lt;b&gt;&lt;font color="#000080"&gt;passion&lt;/font&gt;&lt;/b&gt; for the trade.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;The last virtue is extremely important; how many people do you know that work in the hi-tech industry, just because it &lt;strong&gt;seems&lt;/strong&gt; to be “a shiny, nice place”? You probably met such people in the past when they complained to you not to discuss any work issues during the lunch time.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;And here is the basic skeleton of the interview:&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;u&gt;&lt;font color="#004080"&gt;Previous Experience&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;      &lt;p&gt;&lt;/p&gt;      &lt;p&gt;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I ask the candidate to choose an example from his previous work and to explain its design.&lt;/p&gt;      &lt;p&gt;I expect the following:&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Problem explanation – clear and concise explanation of the domain problem.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l0 level1 lfo1" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;Solution explanation – short conceptual model or class diagram explaining the solution, including alternatives that were considered, technological pitfalls that were overcome and etc…&lt;/p&gt;      &lt;p&gt;It’s amazing to see that many candidates don’t know how to communicate simple technological problems, don’t know what they really tried to solve in the first place and why the solution was chosen the way it was.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing" mce_keep="true"&gt;&amp;#160;&lt;u&gt;&lt;font color="#004080"&gt;Design&lt;/font&gt;&lt;/u&gt;&lt;/p&gt;      &lt;p&gt;&lt;/p&gt;      &lt;p&gt;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I ask a design question from a well known domain. &lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;A well known domain helps to remove obstacles when introducing to the candidate some domain specific logic that might come from the interviewer company’s experience. &lt;/p&gt;      &lt;p&gt;An example of such a question will be: &lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;“Please design the MSN Messenger” or “Please design the Linkedin service” &lt;/p&gt;      &lt;p&gt;During the interview I add more and more constraints to the question. &lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I also provide some leads that may (or not) help to solve the question.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I expect the following:&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 37.5pt; mso-list: l1 level1 lfo2" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;An ability to adjust the design with each added constraint. &lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 37.5pt; mso-list: l1 level1 lfo2" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;An ability to learn from my leads and to change the solutions accordingly.&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 37.5pt; mso-list: l1 level1 lfo2" class="MsoNoSpacing" mce_keep="true"&gt;&amp;#160;&lt;/p&gt;     &lt;u&gt;&lt;font color="#004080"&gt;Technology Questions&lt;/font&gt;         &lt;p&gt;&lt;/p&gt;     &lt;/u&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;No tricks here, no “a-ha” questions\answers.&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I really don’t want the candidate to go back home following an interview with me and suddenly to have the “a-ha” answer for the question I asked. &lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;I just try to reveal how deep the candidate understands the “tools of trade” (based on his experience). &lt;/p&gt;      &lt;p&gt;Here are a few examples:&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l2 level1 lfo3" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;What is the difference between &lt;font color="#0000ff"&gt;class&lt;/font&gt; and &lt;font color="#0000ff"&gt;struct&lt;/font&gt;?&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt 0.5in" class="MsoNoSpacing"&gt;The question yields in 70% (there are still people that don’t know the difference?) a correct answer that a class is a reference type sitting on the heap and a struct is a value type sitting on the stack.&lt;/p&gt;      &lt;p style="text-indent: 0.5in; margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;But, wait, what does &lt;b&gt;it really mean&lt;/b&gt;? &lt;/p&gt;      &lt;p style="text-indent: 0.5in; margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;How that helps &lt;b&gt;you&lt;/b&gt; to build better software in .NET technologies?&lt;/p&gt;      &lt;p style="text-indent: 0.5in; margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;&lt;font size="2"&gt;(Here is a quick hint: in .NET everything is a struct or a class. Basic int is a struct; why is that?)&lt;/font&gt;&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l2 level1 lfo3" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;What is the difference between a &lt;font color="#0000ff"&gt;thread&lt;/font&gt; and a &lt;font color="#0000ff"&gt;process&lt;/font&gt;?&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt 0.5in" class="MsoNoSpacing"&gt;The question drives a broad discussion over why and when we need threads, what are the synchronization methods available in .NET framework, what are their pros and cons and etc…&lt;/p&gt;      &lt;p style="text-indent: -0.25in; margin: 0in 0in 0pt 0.5in; mso-list: l2 level1 lfo3" class="MsoNoSpacing"&gt;&lt;span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"&gt;&lt;span style="mso-list: ignore"&gt;·&lt;span style="font: 7pt &amp;#39;Times New Roman&amp;#39;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span dir="ltr"&gt;&lt;/span&gt;How do you retrieve a record from a Database?&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt 0.5in" class="MsoNoSpacing"&gt;This question also drives a broad discussion about connected and disconnected modes, &lt;font color="#0000ff"&gt;dataset&lt;/font&gt;\&lt;font color="#0000ff"&gt;datatable&lt;/font&gt;, typed &lt;font color="#0000ff"&gt;dataset&lt;/font&gt;\&lt;font color="#0000ff"&gt;datatable&lt;/font&gt;, &lt;font color="#0000ff"&gt;XML&lt;/font&gt;, &lt;font color="#0000ff"&gt;ORM&lt;/font&gt;, optimistic and pessimistic locks and etc…&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing" mce_keep="true"&gt;&amp;#160;&lt;/p&gt;      &lt;p style="margin: 0in 0in 0pt" class="MsoNoSpacing"&gt;By adding more and more constraints on the questions asked I evaluate how deeply the candidate knows his “tools of trade”. He doesn’t need to know &lt;b&gt;all&lt;/b&gt; the answers, but you will see; a passionate Software Engineer will know quite a few things under the hood and even if he won’t know, he will try to figure it out, discussing with you all the possibilities and alternatives.&lt;/p&gt;   &lt;/font&gt;&lt;/font&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5286282305278386798-4727655626339936624?l=urilavi.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/BloggerUriLavi/~4/ZZY9gqJagjw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://urilavi.blogspot.com/feeds/4727655626339936624/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://urilavi.blogspot.com/2009/04/hunt-for-software-engineer.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4727655626339936624?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5286282305278386798/posts/default/4727655626339936624?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/BloggerUriLavi/~3/ZZY9gqJagjw/hunt-for-software-engineer.html" title="The Hunt for a Software Engineer" /><author><name>Uri Lavi</name><uri>http://www.blogger.com/profile/02485121702354534208</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="26" height="32" src="http://1.bp.blogspot.com/_6qKL-Tf2QeM/SySN3d9x4bI/AAAAAAAAAGY/sLxiGXXel1E/S220/Uri+-+Blur.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://urilavi.blogspot.com/2009/04/hunt-for-software-engineer.html</feedburner:origLink></entry></feed>

