<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>The Inquisitive Coder - Davy Brion&#039;s Blog &#187; Software Development</title> <atom:link href="http://davybrion.com/blog/category/software-development/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Mon, 14 May 2012 21:08:36 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>How Do You Pick Open Source Libraries?</title><link>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/</link> <comments>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/#comments</comments> <pubDate>Mon, 16 Jan 2012 21:15:40 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3875</guid> <description><![CDATA[I'm currently looking into which library I'm going to use to handle authentication in a breakable toy project. Now, despite it being just a breakable toy, I want to do it with as few constraints on technical quality as possible because I want to maximize the learning experience I'm going to get from it. That [...]]]></description> <content:encoded><![CDATA[<p>I'm currently looking into which library I'm going to use to handle authentication in a breakable toy project. Now, despite it being just a breakable toy, I want to do it with as few constraints on technical quality as possible because I want to maximize the learning experience I'm going to get from it. That means I don't just want to quickly put something together that just works. I want something that works, but that would also hold up in real world scenarios, even though the project will at best only be used by myself. Which means that I'm going to be picky about any libraries that I take a dependency on, just as I would if this were a project that I'd be getting paid to work on.</p><p>So as I was browsing through a few possible alternatives for my authentication needs, I started thinking about my thought process when evaluating libraries/frameworks to use. I generally base my decision on the following items, listed in order of importance (to me):</p><ul><li><strong>How well does it work for my scenario?</strong> If a library satisfies all other items on this list, that certainly doesn't mean it's an automatic lock. How it works and the impact it has on my code is definitely the most important factor.</li><li><strong>Popularity</strong>. I've noticed that I let the number of watchers/forks on sites like Github influence my opinion. If a project has many watchers and many forks, odds are high that there's a relatively large group of happy users as well as people involved with the project. It also increases the odds that the project will be around for a while. Of course, inactive Open Source projects often remain available as well but if nobody's working on it, I'm not exactly tempted to take a dependency on it. Log4net is a notable exception to this, obviously. But when a project has a lot of people interested in it, or better yet, contributing to it, it's a good sign that you'll easily get help if needed, it's only going to get better in the long run and that it might get forked should the original developers stop working on it. As the author of an Open Source project that doesn't have a lot of watchers/forks (<a
href="https://github.com/davybrion/Agatha">Agatha</a>), I'm aware that my point of view on this is rather hypocritical but hey, it is what it is.</li><li><strong>Code quality</strong>. I don't have the time to do an in-depth review of the code as I'm sure most of us don't do either. But I do like to glance over the code to get a general feel of the quality of the code. I focus mostly on the clarity of the code and also keep an eye open for sloppiness or downright WTF's. I guess the questions I'm mostly trying to answer when doing this are: "is this code I'd like to try to improve or fix if I need to?" and "how easy would it be to debug this when I need to troubleshoot some non-obvious issues?".</li><li><strong>Location of code and issue tracker</strong>. A lot of people will probably take issue with this, but I consider it to be a major plus if the project is on Github. Not just because of my personal preference of Github, but because they truly encourage people to collaborate and contribute to projects and they make it very easy to do so. Also, the site is fast! I cringe when I have to look over issues of projects on Codeplex because it's just terribly slow. And the UI doesn't come close to that of Github either. I've heard that Bitbucket is pretty similar to Github, but I've never even looked for projects there. In any case: I want to be able to download the <em>latest</em> version of the code at any time, or of a particular branch if I need to, as easily as possible. I also prefer an issue tracker which is fast, responsive and easy to search. It doesn't have to be Github, but those 2 requirements are important to me.</li><li><strong>License</strong>. If it's GPL, I don't use it. Also, I check whether or not a commercial license needs to be purchased when you want to use the library/framework in production. Pay attention to dual-licensed projects because that Open Source license might not apply to commercial/production use!</li></ul><p>I'd love to hear your thoughts on this. Did I miss any important factors? I just quickly put this post together so it's likely that I missed some good ones <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2012%2F01%2Fhow-do-you-pick-open-source-libraries%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/"  data-text="How Do You Pick Open Source Libraries?" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Faster Hardware? Not On Our Budget!</title><link>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/</link> <comments>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/#comments</comments> <pubDate>Tue, 08 Nov 2011 22:16:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category> <category><![CDATA[work/career]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/</guid> <description><![CDATA[A lot of developers working in enterprise environments are used to not getting the right hardware that would make them more productive. You know how it goes: Operations likes to 'standardize' the hardware that gets rolled out and in too many cases, no exceptions are made for developers. Which is a shame, really. The simplest, [...]]]></description> <content:encoded><![CDATA[<p>A lot of developers working in enterprise environments are used to not getting the right hardware that would make them more productive. You know how it goes: Operations likes to 'standardize' the hardware that gets rolled out and in too many cases, no exceptions are made for developers. Which is a shame, really.</p><p>The simplest, and probably most effective example is that of giving developers SSD's instead of regular disks. I'm willing to bet that using an SSD instead of a regular disk could save an hour of lost time per day, per developer on average. Suppose the hourly cost of a developer is 80€. Now suppose you have 30 developers in total. That would be waste of 2400€ a day. Now suppose you have to buy 30 SSD's at 300€ each, which would set the company back 9000€.</p><p>That 9000€ investment will have paid itself back after 112,5 man-days, which is only 5 calendar days if you have 30 devs. After those 5 calendar days, the investment starts reducing development costs with 2400€ a day (on average), which for a full year (using 220 working days) could result in a yearly saving of 528000€ for the company.</p><p>Of course, Operations is usually a separate division from those that are responsible for development, which means that they have a separate budget sanctioned for what they need to do. Now suppose that Operations has to spend about 5000€ per year to replace failed SSD's. And lets assume that the yearly support cost for those SSD's is 20000€. I pulled that number out of my ass, which unless I'm mistaken is standard operating procedure whenever an Operations division gives you an estimate of support costs. Anyway, it would mean that on top of the 9000€ investment, a yearly recurrent cost of 25000€ would need to budgetted. And for what? The Operations division can't demonstrate a single benefit for <em>their</em> division to justify the cost.</p><p>Nevermind the fact that the company would save about 500000€ a year...</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F11%2Ffaster-hardware-not-on-our-budget%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/"  data-text="Faster Hardware? Not On Our Budget!" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/11/faster-hardware-not-on-our-budget/feed/</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>The Non-Typical .NET Job</title><link>http://davybrion.com/blog/2011/10/the-non-typical-net-job/</link> <comments>http://davybrion.com/blog/2011/10/the-non-typical-net-job/#comments</comments> <pubDate>Sun, 23 Oct 2011 22:00:33 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[ALT.NET]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[Patterns]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[work/career]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2011/10/the-non-typical-net-job/</guid> <description><![CDATA[I recently referred to an interesting .NET job as a 'non-typical .NET job'. I hadn't used that term yet up until that point, so I thought that was rather interesting. But what exactly do I mean with 'non-typical .NET job'? It's pretty simple really: a job where you're using .NET technology without blindly following the [...]]]></description> <content:encoded><![CDATA[<p>I recently referred to an interesting .NET job as a 'non-typical .NET job'. I hadn't used that term yet up until that point, so I thought that was rather interesting. But what exactly do I mean with 'non-typical .NET job'? It's pretty simple really: a job where you're using .NET technology without blindly following the guidelines, recommendations and software from Microsoft on how to develop software on the .NET platform. It basically means that you'll use <em>whatever</em> you think is most appropriate for what you're trying to do.</p><p>The biggest problem in the .NET world is that most companies that do .NET development just stick to what Microsoft tells them to use and how to use it. Many .NET developers largely focus on that, because they know all too well that it increases their odds of getting hired. And let's face it: Microsoft has a solution for practically everything. The only problem is that those solutions are rarely the best in what they're trying to solve. But hey, no manager gets fired for going with Microsoft, right?</p><p>The result is that there are too many companies and too many developers that focus only on what Microsoft offers. But there's a lot more to software development than what Microsoft offers, or even knows about. There are countless examples of Microsoft being late to whatever technical party is interesting at the time. And when they show up, they certainly don't always make a good impression.</p><p>If you're the kind of developer that likes to learn from what other software development communities are doing, odds are high that you're screwed. There is an interesting OSS community within the .NET world, and they frequently produce great solutions, quite often based on succes stories coming from other development communities. The problem is not that .NET developers don't have great solutions available to them. The problem is that the majority of them simply don't know about them only because there hasn't been any Microsoft hype about it, or that the devs who do know about it aren't allowed to use it because their managers are sceptical about it, most likely also because there's no Microsoft backing for the technology or architectural style that is being proposed.</p><p>I'm not advocating the avoidance of Microsoft products or solutions. By all means, use Microsoft products if they are indeed the best solution to your problem. But do be aware of the things that are getting attention outside of the Microsoft sphere and use them when it makes more sense to use them. That's the essence of the 'non-typical .NET job' and that's exactly what makes it interesting: using the right tool for the right job.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F10%2Fthe-non-typical-net-job%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/10/the-non-typical-net-job/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/10/the-non-typical-net-job/"  data-text="The Non-Typical .NET Job" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/10/the-non-typical-net-job/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/10/the-non-typical-net-job/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/10/the-non-typical-net-job/feed/</wfw:commentRss> <slash:comments>19</slash:comments> </item> <item><title>The Worst Code I Ever Wrote, And Why I&#8217;m Still Happy About It</title><link>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/</link> <comments>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/#comments</comments> <pubDate>Sun, 18 Sep 2011 12:03:54 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/</guid> <description><![CDATA[My last 2 years in high school, I was lucky enough to have 13 hours of programming-related classes every week. Those classes covered a few languages, but the most of it was spent on C/C++ (and nothing advanced either… mostly basic stuff) and Visual Basic. We thought we learned a lot, and I guess from [...]]]></description> <content:encoded><![CDATA[<p>My last 2 years in high school, I was lucky enough to have 13 hours of programming-related classes every week. Those classes covered a few languages, but the most of it was spent on C/C++ (and nothing advanced either… mostly basic stuff) and Visual Basic. We thought we learned a lot, and I guess from a purely syntactical point of view that may have indeed been true. But we didn't really learn a lot about the differences between good code and bad code.</p><p>We mostly cared about getting our assignments working. When you completed an assignment, you moved on to the next one and none of the code of the previous assignment really mattered anymore. Maintainability or even readability were things that never even occurred to us. Maybe a few of the teachers tried to tell us about it at some point, but it certainly didn't stick.</p><p>In the final year, we could pick a project to work on for the majority of the year. There were no limits on the assignment, so most people picked something that interested them. I was pretty interested in manager/simulation games, so I figured I'd just build my own Formula 1 manager game. The player would get full control over a F1 team, which in my game meant:</p><ul><li>picking the suppliers for tires, fuel and engines, all of which had varying levels of quality and costs associated with it</li><li>hiring a chief-designer, chief-mechanic and drivers, all of which had a specified talent level and negotiations took the results of the team's previous year into account, as well as the results of the potential hire's previous team, which influenced prices and negotiation tactics.</li><li>landing sponsors, some of which were more than happy to sponsor your team depending on last year's results, or wouldn't even answer your calls and they all had varying budgets as well</li></ul><p>I came up with a pretty good formula to simulate realistic race results based on all these factors as well as a dose of luck, or bad luck. If you played for a few seasons, the decisions you made all added up nicely, and gradually. When the project was due, it all worked. Since I loved playing those kind of games, I tested it very extensively by playing it regularly. When issues came up, I'd fix them. When I thought of improvements, I implemented them. I delivered something that worked, and that was large enough in scope and complexity to be impressive for a school project.</p><p>But the codebase was truly atrocious. I wasn't using proper structures for either data or behavior and I ended up with a shitload of extensive multi-dimensional arrays. All of my types were in those arrays, as I just didn't know yet that they should've been types of their own. Of course, I listed all of the indices on pieces of paper so I'd know which data properties corresponded with each index. Behavior was all implemented in the UI layer. I was using VB5 at the time, which didn't really encourage me to seek out nicer ways to structure my code. I copy/pasted large gobs of code whenever I needed to reuse something. And of course, whenever I had to make a change, I needed to do it in multiple places. Quite a few places in most cases even. I was using flat files to store data, so I didn't have the opportunity to make a horrendous mess out of a SQL-based data layer but if I had used a database, my usage of it would've surely been epic.</p><p>I got a very good grade for the project, and while I was happy to see that all of my hard work was rewarded, it did kinda scare me that a codebase that was so brittle and so painful could actually work, and work well even. It was my first encounter with what is by far the biggest problem with software development to this day: <em>if you keep adding code, sooner or later it might actually work</em>. Luckily, this was just a school project. But can you imagine if this were a project done by a professional company? That codebase would've cost money to develop, and the company would actually have a working project, no matter how expensive it would've been to keep working on it. At the time, I couldn't imagine a company in such a situation that would say: "ah, it sucks… we need to start over". And I think we all know that very few companies would actually do that.</p><p>I love that horrendous codebase for the lessons it taught me so early on. I learned a lot about what you shouldn't do when you're developing something that's supposed to stick around for a while, and I'm glad I learned it without it costing a lot of money. Of course, that doesn't mean that every single thing I've written since is all roses and peaches, but it put me on the path of trying to continuously improve as a developer, not only in what I was able to do with code, but also as to how clear I could make it to others.</p><p>Note: I no longer have that codebase unfortunately. Really wish I did, if only because it'd be pretty funny going through it after all these years.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F09%2Fthe-worst-code-i-ever-wrote-and-why-im-still-happy-about-it%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/"  data-text="The Worst Code I Ever Wrote, And Why I&#8217;m Still Happy About It" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/09/the-worst-code-i-ever-wrote-and-why-im-still-happy-about-it/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>There&#8217;s Only One Valid Metric For Developer Productivity And Quality</title><link>http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/</link> <comments>http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/#comments</comments> <pubDate>Sat, 19 Feb 2011 17:37:19 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Opinions]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3086</guid> <description><![CDATA[Depending on who you ask, software developers have been programming for over 40 to 50 years. And we still have no truly objective way to measure a developer's productivity and quality level. People can think or say that a developer is fast or productive, but they can't truly quantify it. People can think or say [...]]]></description> <content:encoded><![CDATA[<p>Depending on who you ask, software developers have been programming for over 40 to 50 years.  And we still have no truly objective way to measure a developer's productivity and quality level.  People can think or say that a developer is fast or productive, but they can't truly quantify it. People can think or say that a developer is great, good or bad, but again, they can't truly quantify it with numbers.  We often look at other metrics to give us an idea on quality or productivity such as code metrics, or velocity but those numbers often reflect the efforts of a group of people.  After all, a codebase is more often the result of the efforts of more than one person, and a team's velocity is typically the result of the productivity of, well, a group of people.  Those numbers can't really be used to gain insight to the quality or productivity of a specific developer.</p><p>Not only is the current way of trying to determine the productivity or quality of a developer rather subjective, it's quite often based on things that are only one part of the equation: what they did, and the time in which they did it. I've always felt that that only really tells you half the story. I don't hold much value on knowing how long a developer took to write a certain piece of code or to complete a specific feature.  I also don't really care a lot about the code metrics for that piece of code or that specific feature.  All i know is that it took some effort.  The quality or productivity of that effort can't truly be measured without knowing how much extra effort will be introduced later on <em>because of</em> that effort.</p><p>Suppose you have 2 developers, John and Sally. You give them both the same task and you tell them that the estimated workload for that task is 12 hours.  John completes the task in 10 hours, and Sally needs 14 hours to complete it.  It would be easy to think that John is more productive than Sally based on this.  Especially if results like those were to repeat quite often.  But what if John's solution requires an extra 6 hours of effort down the line to fix some bugs, or because his code was such a mess to follow that it slowed down future tasks which required another developer to comprehend the code of John's task?  That would put John's eventual total to 16 hours of effort, instead of the originally reported 10 hours.  And what if Sally's solution didn't introduce any future effort whatsoever down the line?  Hell, maybe Sally's solution saved someone else an hour here or there because her solution was so easy to comprehend or perhaps even to reuse.  Her total for that task remains at 14 while at the same time maybe even reducing future numbers.  In this scenario, Sally is clearly a more productive and better programmer than John though we wouldn't know about it if we'd based ourselves on the initial numbers.</p><p>Consider another scenario though.  John again spends 10 hours on the same task, and Sally again spends 14 hours.  John kept it as simple and as straightforward as he could.  Hell, he actually took a shortcut or two to finish faster.  Sally is an outspoken member of the Software Craftsmanship movement and stays up to date with all of the latest and greatest patterns and approaches that are making their rounds on the internet.  Sally spent a little bit of extra effort to make sure the code is as great as it possibly can be.  It's incredibly readable and uses a great new pattern that all the cool kids on the internet rave about.  The code metrics clearly show that Sally's solution is of a much higher quality.  Unfortunately, it turns out that the other team members are having trouble understanding that code and they often lose time trying to figure it out whenever they need to do something which involves that part of the codebase.  While Sally may claim that she took more time because she did it 'better', the extra effort wasn't worth it because no matter how well her intentions with that code, it ended up costing other people time.  And what if John's shortcuts didn't introduce any future effort?</p><p>There are countless variations on this scenario which makes it virtually impossible to come up with a way to measure productivity or quality based on hours spent or code metrics. The only way to objectively measure this is to define a new metric which holds into account the extra effort that will be introduced later on. I'd call this metric Eventual Efficiency.  Quality or productivity by themselves don't really mean anything if one influences the other negatively.  Efficiency however can be seen as a combination of the two.  Did you write truly fantastic code which ended up not mattering at all? Not efficient.  Did you write mediocre code that got the job done and didn't (or hardly) introduced future effort? Sounds pretty efficient to me.  Did you write great code that reduced future effort? Very efficient!  Did you write bad code quickly that ended up introducing a lot of effort? Not efficient at all.</p><p>Unfortunately, we'll probably never get to the point where we can actually measure the Eventual Efficiency of developers.  Until we do, it's worth keeping in mind that whatever numbers we might be looking at don't really mean anything without the link to the related future effort.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F02%2Ftheres-only-one-valid-metric-for-developer-productivity-and-quality%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/"  data-text="There&#8217;s Only One Valid Metric For Developer Productivity And Quality" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/02/theres-only-one-valid-metric-for-developer-productivity-and-quality/feed/</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>How Developers Should &#8216;Read&#8217; Exceptions</title><link>http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/</link> <comments>http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/#comments</comments> <pubDate>Thu, 13 Jan 2011 21:57:50 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=3006</guid> <description><![CDATA[I heard a coworker talk about how he doesn't understand why some developers never seem to bother to actually try to comprehend an exception thrown in their (or other people's) code. And i never understood that either, but it has certainly bothered me in the past as well. So let's just list once and for [...]]]></description> <content:encoded><![CDATA[<p>I heard a coworker talk about how he doesn't understand why some developers never seem to bother to actually try to comprehend an exception thrown in their (or other people's) code.  And i never understood that either, but it has certainly bothered me in the past as well.  So let's just list once and for all the steps a developer should follow when presented with a thrown exception.</p><ol><li>Check whether the exception has an inner exception. If not, proceed to step 2. If it does, check recursively until you've got the original exception (the one that doesn't have an inner exception).</li><li>Read the exception message. Don't just glance at it, actually read it. If you got an 'aha!' moment upon reading it, you already know what to do.  If you didn't, proceed to step 3.</li><li>Take a look at the stacktrace.  If the technology you're using prints its stacktraces in reverse chronological order (as in: the most recent method call is the first one listed) then open the first class of your code base that is listed in the stacktrace and go to the method of that class that is listed first in the stacktrace.  If the stacktrace is printed in chronological order (as in: the most recent method call is the last one listed) then open the last class of your code base that is listed in the stacktrace and go to the method of that class that is listed last in the stacktrace.  If line-numbers are displayed in the stacktrace, go the line-number that is printed next to the first mention of the first class of your codebase (in the case of reverse chronological order) or the last mention of the last class of your code base (in the case of chronological order) that is listed in the stacktrace.  This is the part where you need to begin your search.  The actual bug might be somewhere else, but at least you've got a starting point for your search.  Once again, if you got an 'aha!' moment after this step, you already know what to do.  If not, proceed to step 4.</li><li>Here's where it gets tricky.  Some people immediately enlist the assistence of a teammate at this point.  Others spend hours searching until finally calling upon a teammate who might spot the problem after 10 seconds.  If it's not immediately clear, spend 10 minutes tops looking for a solution before consulting with a teammate.  If you haven't found a solution after 10 minutes, you haven't lost that much time and you can ask a teammate for help.  If the teammate can help, neither of you lost a lot of time and at least you tried to fix it yourself before interrupting a teammate.  If the teammate can't help, you're probably going to have to investigate this further on your own.  Perhaps your teammate has enough time to help you, but don't count on it.</li></ol><p>For a lot of the people reading this, there's absolutely nothing new in this list so i apologize for wasting your time.  However, odds are high that you're going to run into a developer who can use this sooner or later so feel free to send him a link to this page <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F01%2Fhow-developers-should-read-exceptions%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/"  data-text="How Developers Should &#8216;Read&#8217; Exceptions" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/01/how-developers-should-read-exceptions/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>First NuGet Experience</title><link>http://davybrion.com/blog/2011/01/first-nuget-experience/</link> <comments>http://davybrion.com/blog/2011/01/first-nuget-experience/#comments</comments> <pubDate>Thu, 06 Jan 2011 13:12:54 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[agatha]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2989</guid> <description><![CDATA[I haven't used NuGet before, and just now i accidentally triggered its UI while playing around with an ASP.NET MVC3 sample project. When i clicked on the link for online packages, the first thing i saw was this: I didn't even know there was a NuGet package for Agatha, so this was a nice surprise. [...]]]></description> <content:encoded><![CDATA[<p>I haven't used NuGet before, and just now i accidentally triggered its UI while playing around with an ASP.NET MVC3 sample project.  When i clicked on the link for online packages, the first thing i saw was this:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2011/01/nuget_first_experience.png" rel="prettyPhoto[2989]"><img
src="http://davybrion.com/blog/wp-content/uploads/2011/01/nuget_first_experience.png" alt="first look at Nuget" title="nuget_first_experience" width="897" height="248" class="aligncenter size-full wp-image-2990" /></a></p><p>I didn't even know there was a NuGet package for Agatha, so this was a nice surprise. I have no idea who made the package, but thanks <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2011%2F01%2Ffirst-nuget-experience%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2011/01/first-nuget-experience/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2011/01/first-nuget-experience/"  data-text="First NuGet Experience" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2011/01/first-nuget-experience/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2011/01/first-nuget-experience/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/01/first-nuget-experience/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Announcing: DrinksWithDevs (The Belgian Chapter)</title><link>http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/</link> <comments>http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/#comments</comments> <pubDate>Fri, 17 Dec 2010 11:54:19 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2948</guid> <description><![CDATA[As i mentioned in my last post, i want to get together with developers regularly and in an informal manner. Enough people expressed interest to get it started, so i've created a Google Group called DrinksWithDevs-Belgium which we can use to plan the 'meetings'. Everybody is welcome to join, so please feel free to do [...]]]></description> <content:encoded><![CDATA[<p>As i mentioned in my <a
href="http://davybrion.com/blog/2010/12/calling-all-belgian-developers/">last post</a>, i want to get together with developers regularly and in an informal manner.  Enough people expressed interest to get it started, so i've created a Google Group called <a
href="http://groups.google.com/group/drinkswithdevs-belgium">DrinksWithDevs-Belgium</a> which we can use to plan the 'meetings'.</p><p>Everybody is welcome to join, so please feel free to do so.  The idea is very simple: you can suggest a get-together at a bar (or restaurant) of your choice.  If people respond, agree on a date, go out, talk about software development, have a few drinks and just have fun.  Ideally, these get-togethers will happen pretty frequently and in various locations throughout the country.  That way, you can just pick which ones you want to go to.  If you can't make one, or don't feel like going, just skip one.  Or skip a few, doesn't matter.  Just show up when you want to.</p><p>Finally, i'd like to repeat the 'rules' again so that we're all very clear on this:</p><ul><li>Leave your ego at home.</li><li>You pay for your own drinks <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></li><li>Open to all kinds of developers (.NET, Java, Ruby, Python, PHP, whatever...)</li></ul><p>Hope to see some of you on these meetings in the future <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F12%2Fannouncing-drinkswithdevs-the-belgian-chapter%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/"  data-text="Announcing: DrinksWithDevs (The Belgian Chapter)" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/12/announcing-drinkswithdevs-the-belgian-chapter/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Calling All Belgian Developers</title><link>http://davybrion.com/blog/2010/12/calling-all-belgian-developers/</link> <comments>http://davybrion.com/blog/2010/12/calling-all-belgian-developers/#comments</comments> <pubDate>Sun, 12 Dec 2010 23:02:04 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2927</guid> <description><![CDATA[About 2,5 years ago, i tried to start a Belgian ALT.NET group. Some people were interested at first and we had a few meetings. After a while though, things slowed down due to a variety of reasons. I do meet up with some of the people who were involved from time to time, and one [...]]]></description> <content:encoded><![CDATA[<p>About 2,5 years ago, i tried to start a <a
href="http://davybrion.com/blog/2008/06/dutch-altnet-group/">Belgian ALT.NET group</a>.  Some people were interested at first and we had a few meetings.  After a while though, things slowed down due to a variety of reasons.  I do meet up with some of the people who were involved from time to time, and one of the things we all seem to agree on is that the most important parts of those meetings were the informal discussions about our jobs and projects that took place either before or after the actual 'meetings' or 'events'.</p><p>I want to get something like that going in Belgium again.  I want to talk to other developers who are serious about their job.  I want to know what they're doing and how they're doing it.  I want to know what people are studying or experimenting with on their own time.  I want to know what works for people and what doesn't.  And i want us to share that information and that experience.  If you feel the same way, please respond to this post with a comment (and do fill out your email address) or email me directly.  I don't care how many or how few people respond.  If 5 passionate developers respond, it's already a win-win situation for each one of them.</p><p>But... there are a few rules that i would like to propose to avoid the same result that we saw with the Belgian ALT.NET movement:</p><ul><li>If you wanna come to the meetings, leave your ego at home.  We are not interested in being a part of your career plan.  We just want to share knowledge and experiences.</li><li>Let's not restrict ourselves to a single technology.  It'd be great if these meetings were attended by people who were doing .NET, Java, Ruby, Python, whatever.  The goal is to learn from each other and to pick each others brains, and one of the best ways to do that is to look outside of your immediate (technological) environment.</li><li>Let's keep things simple.  Let's not seek out sponsorship.  Let's not seek out opportunities to do presentations.  Let's just hang out and talk about software development.</li><li>Let's get together regularly.  Twice a month or so.  If you can't make a meeting, show up for the next one.  Or the one after that.  It doesn't matter, as long as we always have a small group of people who show up to talk with and learn from each other.</li></ul><p>Who's with me?</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F12%2Fcalling-all-belgian-developers%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/12/calling-all-belgian-developers/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/12/calling-all-belgian-developers/"  data-text="Calling All Belgian Developers" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/12/calling-all-belgian-developers/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/12/calling-all-belgian-developers/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/12/calling-all-belgian-developers/feed/</wfw:commentRss> <slash:comments>21</slash:comments> </item> <item><title>Favor Value Over Quality</title><link>http://davybrion.com/blog/2010/11/favor-value-over-quality/</link> <comments>http://davybrion.com/blog/2010/11/favor-value-over-quality/#comments</comments> <pubDate>Thu, 11 Nov 2010 21:25:53 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2897</guid> <description><![CDATA[A mistake that many developers often make is that of putting too much effort into making their code and their designs as good as they can be. Don't get me wrong, good code and good design is obviously important. But what is even more important is that in most cases, someone is paying you to [...]]]></description> <content:encoded><![CDATA[<p>A mistake that many developers often make is that of putting too much effort into making their code and their designs as good as they can be.  Don't get me wrong, good code and good design is obviously important.  But what is even more important is that in most cases, someone is paying you to write and/or maintain that code and that person deserves a good return on his/her investment in you.  Your job is to create value. Whatever it is that you're working on needs to add value in some way or another.</p><p>The most obvious way in which you can create value is when you write code that results in noticeable improvement when it is being executed. It could be a new feature. It could be an improvement to an already existing feature. It could be a performance optimization somewhere. It could be a bugfix.  All of these make the software better in an externally observable manner which, like it or not, is all that really matters to the people who are funding your development activities.</p><p>Obviously, we all know that good code and good design make software better as well. It just improves the quality of the software in a more internal manner. It's not directly externally observable.  It is however quite reasonable to claim that good code and good design lead to sustained productivity while working on the software.  It enables the continuous creation of value without making it increasingly expensive.</p><p>So focusing on the quality of your code and design is a good thing, right? Of course it is, as long as it doesn't prevent you from actually <em>delivering</em> your software to the people who are supposed to use it in a timely fashion. At some point, you are going to have to accept that you can't spend all that extra time and money to make it perfect.  The software you're working on is most likely supposed to reduce costs for its users, or generate money for its owners.  As long as it's not being used, it's nothing more than a cost.  A big one even.</p><p>Focus on creating value. Make sure you keep your code and your design clean enough to achieve that. It's not about how great you think you are.  It's not about your ego.  It's not about how you can tell people that you've used approach X or pattern Y or library Z in a project that users might not be happy with.  It's about delivering the value that you were requested to deliver. Plain and simple.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F11%2Ffavor-value-over-quality%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/11/favor-value-over-quality/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/11/favor-value-over-quality/"  data-text="Favor Value Over Quality" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/11/favor-value-over-quality/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/11/favor-value-over-quality/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/11/favor-value-over-quality/feed/</wfw:commentRss> <slash:comments>14</slash:comments> </item> <item><title>Check Out PragPub, An Excellent Free Magazine</title><link>http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/</link> <comments>http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/#comments</comments> <pubDate>Thu, 11 Nov 2010 20:01:37 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=2898</guid> <description><![CDATA[In case you've missed it, as i have for the first 15 issues, the Pragmatic Programmers have an excellent free magazine called PragPub. There's a new issue every month which you can either read online, or download in a couple of formats (pdf, epub, mobi) so you can read it on pretty much every device [...]]]></description> <content:encoded><![CDATA[<p>In case you've missed it, as i have for the first 15 issues, the Pragmatic Programmers have an excellent free magazine called <a
href="http://www.pragprog.com/magazines">PragPub</a>.  There's a new issue every month which you can either read online, or download in a couple of formats (pdf, epub, mobi) so you can read it on pretty much every device you want. It's about software development in general, with no particular focus on a certain technology.  Just great content with great variety. And it's free.  So do yourself a favor, and check it out if you haven't already <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F11%2Fcheck-out-pragpub-an-excellent-free-magazine%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/"  data-text="Check Out PragPub, An Excellent Free Magazine" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/11/check-out-pragpub-an-excellent-free-magazine/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Check Out QuickGenerate</title><link>http://davybrion.com/blog/2010/06/check-out-quickgenerate/</link> <comments>http://davybrion.com/blog/2010/06/check-out-quickgenerate/#comments</comments> <pubDate>Wed, 30 Jun 2010 07:05:38 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[testing]]></category><guid
isPermaLink="false">http://davybrion.com/blog/2010/06/check-out-quickgenerate/</guid> <description><![CDATA[One of several interesting things in Mark Meyers’ QuickNet project is the whole input generation thing that you need for property-based testing.&#160; It turns out that those input generators are very usable for far more purposes than just property-based testing, so it’s evolved into its own library.&#160; It can generate object instances of almost any [...]]]></description> <content:encoded><![CDATA[<p>One of several interesting things in Mark Meyers’ <a
href="http://code.google.com/p/quicknet/" target="_blank">QuickNet</a> project is the whole input generation thing that you need for property-based testing.&#160; It turns out that those input generators are very usable for far more purposes than just property-based testing, so it’s evolved into its own library.&#160; It can generate object instances of almost any kind, while you can still have fine-grained control over the generation if you want to.&#160; You can use it for simple types, complex objects or even entire object graphs. I wish i had time to write a more in-depth post about this, but for now i’m just gonna point you guys in the right direction, and i hope that you’ll see the value in this <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>The announcement of the first release can be found <a
href="http://kilfour.wordpress.com/2010/06/29/quickgenerate-0-1-released/" target="_blank">here</a>, and an example can be found <a
href="http://kilfour.wordpress.com/2010/06/29/quickgenerate-example/" target="_blank">here</a>.&#160; Here’s a little glimpse at the code of one the examples:</p><p><a
href="http://davybrion.com/pictures/CheckOutQuickGenerate_7FE6/quickgenerate.png" rel="prettyPhoto[2363]"><img
style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="quickgenerate" border="0" alt="quickgenerate" src="http://davybrion.com/pictures/CheckOutQuickGenerate_7FE6/quickgenerate_thumb.png" width="653" height="500" /></a></p><p>I think that piece of code is a nice illustration of how powerful and flexible this is <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2010%2F06%2Fcheck-out-quickgenerate%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2010/06/check-out-quickgenerate/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2010/06/check-out-quickgenerate/"  data-text="Check Out QuickGenerate" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2010/06/check-out-quickgenerate/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2010/06/check-out-quickgenerate/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2010/06/check-out-quickgenerate/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Database Audit Trails: How Would You Do It?</title><link>http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/</link> <comments>http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/#comments</comments> <pubDate>Mon, 19 Oct 2009 17:40:03 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1764</guid> <description><![CDATA[For those of you wondering what the background story on the previous post is about: we had a meeting today to discuss 2 alternatives on how we should implement the database audit trail for a new project we're doing. These are the functional requirements: We have to be able to easily retrieve what user X [...]]]></description> <content:encoded><![CDATA[<p>For those of you wondering what the background story on the <a
href="http://davybrion.com/blog/2009/10/wrong-on-so-many-levels/">previous post</a> is about: we had a meeting today to discuss 2 alternatives on how we should implement the database audit trail for a new project we're doing.  These are the functional requirements:</p><ul><li>We have to be able to easily retrieve what user X changed in the database on day Y or during a certain time frame.</li><li>We need to know what record X looked like at point Y in time, and be able to show a historic list of changes for a specific record.</li><li>We need to configure the duration for which auditing data must be kept in the database on a per-table (or per-schema) level</li></ul><p>We've done this in the past, but never in a manner that is just perfect (or close enough to being perfect anyway) for both requirements.  So we discussed two alternative approaches to tackling this problem.</p><p>The first approach is to have 3 tables.  The first two tables would contain metadata about the database structure (tables and columns basically).  The third table would have a reference to each column with a previous value, the new value, who changed it and a timestamp of when the change occurred.  We would use database triggers that would store the appropriate auditing data in the third table for each action (insert/update/delete).  The benefits of this approach would be that it would be pretty easy to set up and also easy to query which changes were made by a certain user.   It would be a bit more complex to reconstruct the state of a record at a certain point in time, but it would still be doable.  The biggest downside (in my opinion), is that for each insert/update you would have X amount of inserts into the auditing table, and you'd also have to either perform some queries to get the identifier values of the relevant tables/columns or hardcode those identifier values in the generated triggers to avoid the cost of the extra select statements.  So if you have an entity with 12 columns, an insert into the entity's table would mean 12 inserts into the auditing table.  Updating 4 columns of that entity would lead to 4 insert statements in the auditing table, etc...</p><p>The other alternative that we considered was to use a specific auditing table for each real table, and every time a user does an insert/update/delete, insert one record into the table's specific auditing table with the current state of the record along with a timestamp, the userid, and an indication of which action was performed (insert/update/delete).  This insert would also be done with database triggers.  The benefits of this approach would be that it would be very easy to show what the state of a certain entity was at a certain point in time, and that you'd only pay the cost of the single extra insert.  There are however two big downsides to this approach.  The first is that it'll lead to an explosion of tables.  We'd probably store the auditing tables in a separate database but you still basically have twice the amount of tables (and scripts!) that you'd have to worry about compared to what you'd usually have.  We can very realistically expect a couple hundred of real tables in a few years, so you'd have to multiply that by two if you'd go for this auditing approach.  Another big downside is that it would be very expensive to perform a query which would tell you what user X changed at point Y in time (or during a time frame).</p><p>Neither solution appears to be ideal.  Also, this database will definitely grow a lot (more tables and obviously data) as we add more functionality and it's pretty safe to consider this entire project as something that will be expanding in functionality for a couple of years to come.</p><p>So my question to you is: Which approach do you think is best, and why?  Or better yet, is there a better approach that we simply haven't thought of yet?  I would definitely appreciate some feedback on this (either on the validity of both approaches or alternative approaches) so please do feel free to leave your thoughts in the comments <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F10%2Fdatabase-audit-trails-how-would-you-do-it%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/"  data-text="Database Audit Trails: How Would You Do It?" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/10/database-audit-trails-how-would-you-do-it/feed/</wfw:commentRss> <slash:comments>22</slash:comments> </item> <item><title>Slutty Types</title><link>http://davybrion.com/blog/2009/10/slutty-types/</link> <comments>http://davybrion.com/blog/2009/10/slutty-types/#comments</comments> <pubDate>Sun, 11 Oct 2009 17:57:11 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1729</guid> <description><![CDATA[Slutty Types are types which: give you access to their privates without too many difficulties don't really care about your intentions, or if they do, aren't very clear on that occasionally seem like a good short-term fix can be used in a variety of ways, with different outcomes and none of them are guaranteed can [...]]]></description> <content:encoded><![CDATA[<p>Slutty Types are types which:</p><ul><li>give you access to their privates without too many difficulties</li><li>don't really care about your intentions, or if they do, aren't very clear on that</li><li>occasionally seem like a good short-term fix</li><li>can be used in a variety of ways, with different outcomes and none of them are guaranteed</li><li>can not to be trusted</li><li>really need to be tested</li><li>will burn you sooner or later if you're not careful</li><li>become even more of a mess during the aging process</li></ul><p>Feel free to add to the list <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F10%2Fslutty-types%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/10/slutty-types/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/10/slutty-types/"  data-text="Slutty Types" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/10/slutty-types/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/10/slutty-types/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/10/slutty-types/feed/</wfw:commentRss> <slash:comments>23</slash:comments> </item> <item><title>What Kind Of Developer Are You?</title><link>http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/</link> <comments>http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/#comments</comments> <pubDate>Sun, 27 Sep 2009 18:24:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1694</guid> <description><![CDATA[It occurred to me recently how much i've changed as a developer in the past few years. When i first started working as a developer, i was pretty quick at adding new features to projects and fixing bugs. I was almost fully focused on adding functionality but i didn't really spend a lot of time [...]]]></description> <content:encoded><![CDATA[<p>It occurred to me recently how much i've changed as a developer in the past few years.  When i first started working as a developer, i was pretty quick at adding new features to projects and fixing bugs.  I was almost fully focused on adding functionality but i didn't really spend a lot of time thinking about <strong>how</strong> i was adding the functionality.  In some cases, i complained when i felt that some of our approaches could be better and in other cases i came up with alternative approaches but generally speaking, i was in full "i'm new at this, i'm learning and i'm just trying to do the best i can"-mode.  For me, that meant trying to complete your assignments within (or ahead of) time, and with as few issues/bugs as possible.</p><p>This worked pretty well for the first 2 years or so of my career, but a lot of that changed when i started working on our own little ORM in VB6 together with a more experienced coworker.  For some reason, writing code that made the job of developers easier somehow was more appealing to me than writing code that made the job of our users easier.  From that point on, my focus gradually shifted from being a developer who tries to add value through functionality to being a developer who tries to add value by reducing complexity.  With that i mean that i spent less time working on actual features that our users would benefit from, and more time on writing code that other developers would benefit from.  And that, in turn, would (should?) offer more benefit to our users on a larger scale because my code was supposed to make it easier for other developers to add new functionality.</p><p>Just to be clear on this: i think we need both 'kinds' (yes, i know there are more 'kinds' of developers but bear with me on this) of developers.  If a team of developers consists solely of people like me, you're never going to deliver anything of value to your users because we would spend all of our time trying to improve whatever it is that we're doing.  Just like you need people who are willing to think a bit further about how you're doing things, you need people who manage to actually get things done in a manner that is good from both the technical as well as the end-user point of view.</p><p>Sadly, i'm no longer one of those people.  I used to be, but i don't really think i'm capable of going back to that.  To me, providing a good User Experience means coming up with a good API.  So i spend most of my time working on architectural and framework stuff.  One of my biggest fears is that i'll some day end up as the typical non-coding architect so i try to stay very involved with how people are actually writing code to deliver real functionality.  I may not write that kind of code anymore, but i do keep looking at a lot of that code so i can keep coming up with possible improvements.</p><p>So what about you? What are the things you focus most on, as a developer, and why?  What are the things that get you the most satisfaction (keep this technical, i don't wanna know about your personal life) and are you able to focus most of your energy on this?</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F09%2Fwhat-kind-of-developer-are-you%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/"  data-text="What Kind Of Developer Are You?" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/09/what-kind-of-developer-are-you/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Why Are Mutable Value Types Even Possible?</title><link>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/</link> <comments>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/#comments</comments> <pubDate>Sun, 17 May 2009 12:06:07 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1352</guid> <description><![CDATA[A coworker of mine was recently trying to figure out why some code wouldn't compile. Consider the following code: This compiles and works. Now consider the following class: And then this small piece of code: You'd typically expect that this code would compile, right? Well it doesn't. It fails with the following compiler error: error [...]]]></description> <content:encoded><![CDATA[<p>A coworker of mine was recently trying to figure out why some code wouldn't compile.</p><p>Consider the following code:</p><div><pre class="brush: csharp; title: ; notranslate">
            var point = new System.Windows.Point(5, 7);
            point.X = 6;
            point.Y = 8;
            Assert.AreEqual(6, point.X);
            Assert.AreEqual(8, point.Y);
</pre></div><p>This compiles and works.  Now consider the following class:</p><div><pre class="brush: csharp; title: ; notranslate">
    public class SomeClass
    {
        public System.Windows.Point SomePoint { get; set; }
    }
</pre></div><p>And then this small piece of code:</p><div><pre class="brush: csharp; title: ; notranslate">
            var myObject = new SomeClass
            {
                SomePoint = new Point(2, 3)
            };
 
            myObject.SomePoint.X = 5;
</pre></div><p>You'd typically expect that this code would compile, right? Well it doesn't.  It fails with the following compiler error:</p><p>error CS1612: Cannot modify the return value of 'SomeApp.SomeClass.SomePoint' because it is not a variable</p><p>Not exactly what you would expect, right? Well, the compiler error in this case is actually a good thing, though the message isn't as clear as it should be.  See, System.Windows.Point is actually a value type instead of a reference type, and as you should know, value types behave very differently from reference types when passed around.  You basically get a copy every time instead of the actual instance.</p><p>Let me just borrow the explanation of the "DO NOT define mutable value types" guideline, from Microsoft's <a
href="http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321545613/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1241181546&#038;sr=8-1">Framework Design Guidelines</a>:</p><blockquote> Mutable value types have several problems.  For example, when a property getter returns a value type, the caller receives a copy. Because the copy is created implicitly, developers might not be aware that they are mutating the copy, and not the original value.</blockquote><p>Now the compiler error makes sense, right? Well, the message still sucks, but it makes sense that the compiler would protect you from making this mistake.</p><p>It won't protect you from the following mistake though:</p><div><pre class="brush: csharp; title: ; notranslate">
            var myObject = new SomeClass
            {
                SomePoint = new Point(2, 3)
            };
 
            var point = myObject.SomePoint;
            point.X = 5;
</pre></div><p>This code will compile, though if you expect that myObject.SomePoint.X will return 5, you're in for a treat.  Hopefully nobody writes code like this, but imagine having to debug something like this in some legacy code that was never properly tested.</p><p>But really, why are mutable value types even possible? In what situation does a mutable value type make sense? I'd really like to know, so please point out those situations in the comments if you know of one.  The only reason i can think of is performance but the number of situations where a mutable value type is going to give you a significant performance boost is probably so small that it would've made more sense to enable mutability for value types with a language keyword or something like that.  Unless there is another benefit that i'm not aware of yet?</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fwhy-are-mutable-value-types-even-possible%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/"  data-text="Why Are Mutable Value Types Even Possible?" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/05/why-are-mutable-value-types-even-possible/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Who&#8217;s In Charge Of The Time?</title><link>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/</link> <comments>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/#comments</comments> <pubDate>Wed, 06 May 2009 16:53:07 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1356</guid> <description><![CDATA[I recently noticed that 2 tests were suddenly failing for no apparent reason. This was in a large codebase where we have a mix of two development approaches. The project is simply too big to convert everything at once to the latest development approach so we're using Ayende's Obsolete In Isolation approach on this. The [...]]]></description> <content:encoded><![CDATA[<p>I recently noticed that 2 tests were suddenly failing for no apparent reason.  This was in a large codebase where we have a mix of two development approaches.  The project is simply too big to convert everything at once to the latest development approach so we're using Ayende's <a
href="http://ayende.com/Blog/archive/2008/07/14/Obsolete-in-Isolation.aspx">Obsolete In Isolation</a> approach on this.  The 2 failing tests were in the old parts of the code, so i cringed and then set out to investigate.</p><p>The tests of the old part of the code aren't always easy to comprehend and they use the database all over the place.  I figured i'd quickly run them on the database that we use when we run those tests on our local machines, and after that, run them on the database that the buildserver uses (which is rebuilt entirely with each build) to examine the differences between both test runs.  They both passed in both cases.  They were still failing on the buildserver though.</p><p>Upon first inspection of the code of those tests, it didn't seem like there was any blatantly obvious reason why those tests were failing on one machine, and not on the others.  They were inserting some records with some manipulated DateTime values, and then calling some code which would execute a query which should have retrieved these values.  The records inserted by the test were not retrieved for some reason, which caused the tests to fail.</p><p>DateTime values and tests can be tricky sometimes so i started looking in that direction.  The queries that where executed in those tests would use the current date/time together with a margin of a couple of minutes to retrieve records where a certain date/time column's value would fall in the range of the current date/time with the given margin.  The records that were inserted in the tests would use the current date/time, minus 2 minutes, or plus 2 minutes.  Hmm... this could possibly be flaky depending on how the query determines the current date/time.  If the query receives the current date/time from the calling code, then this wouldn't cause problems but if it uses the current date/time of the database, then this is not only a flaky test, but a real bug in the code.</p><p>I then checked the system clock of the buildserver, and as i suspected, it was about 4 minutes ahead of the system clock of the database server.  Normally, all of our servers' system clocks are synchronized, but for some reason, the buildserver hadn't had its system clock synchronized since the day before.  The code was inserting records in the database with modified date/time values, based on the system clock of the system the code was running on, and was then querying the database using the database's system clock.  Since the time difference was big enough, the query would not return the expected rows and this made the tests fail on the buildserver.</p><p>Obviously, this never would've happened if the query would've used a parameter supplied by the caller which would've represented the current date.  And that is the real bug that these flaky tests (which up until this particular incident never failed) highlighted.  A situation like this could've occurred in production if the application server's clock and the database server's clock would've gotten out of synch.  Can you imagine the pain you'd go through when investigating a bug report like this? :p</p><p>Date/Time values are often tricky, especially when there is more than one source which could determine the current Date/Time.  So do yourself, and anyone who will maintain your code down the line, a favor by making sure that only ONE source is in charge of Date/Time values in your system.  Using the database for all date/time values is definitely not always possible, so it's best to have your application server be in charge of all date/time values.  If you need the current date/time in a query, simply supply it as a parameter to the query and you'll avoid problems like this.</p><p>Though this advice does leave me wondering what the best approach to deal with this is when you have multiple application servers which could assign date/time values.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F05%2Fwhos-in-charge-of-the-time%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/"  data-text="Who&#8217;s In Charge Of The Time?" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/05/whos-in-charge-of-the-time/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Help Us Name This Method</title><link>http://davybrion.com/blog/2009/04/help-us-name-this-method/</link> <comments>http://davybrion.com/blog/2009/04/help-us-name-this-method/#comments</comments> <pubDate>Fri, 24 Apr 2009 13:48:35 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1334</guid> <description><![CDATA[This worked pretty good last time so i'm gonna try it again. We have a Repository base class (yes we still use it, and no, i'm not going to get into the discussion that's going on about in on other blogs) which uses NHibernate underneath. We have the typical Get method which retrieves an object [...]]]></description> <content:encoded><![CDATA[<p>This worked pretty good <a
href="http://davybrion.com/blog/2009/03/help-us-name-this-property/">last time</a> so i'm gonna try it again.  We have a Repository base class (yes we still use it, and no, i'm not going to get into the discussion that's going on about in on other blogs) which uses NHibernate underneath.  We have the typical Get method which retrieves an object based on an ID.  This method uses NHibernate's ISession's Get method, which either returns the entity if it's present in the database, or it returns null.</p><p>Some people want to put an equivalent to NHibernate's ISession's Load method into the base repository class, but we just can't come up with a good name for it.  In case you don't know, ISession.Load either returns the actual entity if it's already in the session cache, or it returns a proxy for the entity but it does not immediately hit the database.  The functionality of the Load method is thus very different from the Get method.  Now, i think this is a case of extremely bad naming within NHibernate, and i don't want to have the same naming issue in our Repository implementation.</p><p>So basically, the question is: how would you name the equivalent of the Load method? Remember: this method returns a proxy to an entity if it's not yet in the session cache, whereas the Get method actually retrieves the entity from the database immediately or returns null if the entity for the given ID does not exist.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fhelp-us-name-this-method%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/04/help-us-name-this-method/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/04/help-us-name-this-method/"  data-text="Help Us Name This Method" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/04/help-us-name-this-method/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/04/help-us-name-this-method/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/04/help-us-name-this-method/feed/</wfw:commentRss> <slash:comments>23</slash:comments> </item> <item><title>Small Milestone</title><link>http://davybrion.com/blog/2009/04/small-milestone/</link> <comments>http://davybrion.com/blog/2009/04/small-milestone/#comments</comments> <pubDate>Tue, 21 Apr 2009 11:20:57 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1329</guid> <description><![CDATA[Finally]]></description> <content:encoded><![CDATA[<p><img
src="http://davybrion.com/blog/wp-content/uploads/2009/04/subscriber_count.png" alt="subscriber_count" title="subscriber_count" width="99" height="31" class="alignnone size-full wp-image-1330" /></p><p>Finally <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fsmall-milestone%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/04/small-milestone/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/04/small-milestone/"  data-text="Small Milestone" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/04/small-milestone/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/04/small-milestone/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/04/small-milestone/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Gotta Love Refactoring</title><link>http://davybrion.com/blog/2009/04/gotta-love-refactoring/</link> <comments>http://davybrion.com/blog/2009/04/gotta-love-refactoring/#comments</comments> <pubDate>Sun, 19 Apr 2009 15:19:50 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=1323</guid> <description><![CDATA[Behold the following two classes: &#160;&#160;&#160; public class FutureCriteriaBatch &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; private readonly List&#60;ICriteria&#62; criterias = new List&#60;ICriteria&#62;(); &#160;&#160;&#160; &#160;&#160;&#160; private readonly IList&#60;System.Type&#62; resultCollectionGenericType = new List&#60;System.Type&#62;(); &#160; &#160;&#160;&#160; &#160;&#160;&#160; private int index; &#160;&#160;&#160; &#160;&#160;&#160; private IList results; &#160;&#160;&#160; &#160;&#160;&#160; private readonly ISession session; &#160; &#160;&#160;&#160; &#160;&#160;&#160; public FutureCriteriaBatch(ISession session) &#160;&#160;&#160; &#160;&#160;&#160; { [...]]]></description> <content:encoded><![CDATA[<p>Behold the following two classes:</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">class</span> <span
class="cb2">FutureCriteriaBatch</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">List</span>&lt;<span
class="cb2">ICriteria</span>&gt; criterias = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;<span
class="cb2">ICriteria</span>&gt;();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">IList</span>&lt;System.<span
class="cb2">Type</span>&gt; resultCollectionGenericType = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;System.<span
class="cb2">Type</span>&gt;();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">int</span> index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb2">IList</span> results;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">ISession</span> session;</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> FutureCriteriaBatch(<span
class="cb2">ISession</span> session)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">this</span>.session = session;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IList</span> Results</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">get</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">if</span> (results == <span
class="cb1">null</span>)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">var</span> multiCriteria = session.CreateMultiCriteria();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">for</span> (<span
class="cb1">int</span> i = 0; i &lt; criterias.Count; i++)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; multiCriteria.Add(resultCollectionGenericType[i], criterias[i]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; results = multiCriteria.List();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ((<span
class="cb2">SessionImpl</span>)session).FutureCriteriaBatch = <span
class="cb1">null</span>;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> results;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add&lt;T&gt;(<span
class="cb2">ICriteria</span> criteria)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; criterias.Add(criteria);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; resultCollectionGenericType.Add(<span
class="cb1">typeof</span>(T));</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; index = criterias.Count - 1;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add(<span
class="cb2">ICriteria</span> criteria)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Add&lt;<span
class="cb1">object</span>&gt;(criteria);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IFutureValue</span>&lt;T&gt; GetFutureValue&lt;T&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">FutureValue</span>&lt;T&gt;(() =&gt; (<span
class="cb2">IList</span>&lt;T&gt;)Results[currentIndex]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IEnumerable</span>&lt;T&gt; GetEnumerator&lt;T&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">DelayedEnumerator</span>&lt;T&gt;(() =&gt; (<span
class="cb2">IList</span>&lt;T&gt;)Results[currentIndex]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>and</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">class</span> <span
class="cb2">FutureQueryBatch</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">List</span>&lt;<span
class="cb2">IQuery</span>&gt; queries = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;<span
class="cb2">IQuery</span>&gt;();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">IList</span>&lt;System.<span
class="cb2">Type</span>&gt; resultCollectionGenericType = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;System.<span
class="cb2">Type</span>&gt;();</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">int</span> index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb2">IList</span> results;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">ISession</span> session;</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> FutureQueryBatch(<span
class="cb2">ISession</span> session)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">this</span>.session = session;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IList</span> Results</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">get</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">if</span> (results == <span
class="cb1">null</span>)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">var</span> multiQuery = session.CreateMultiQuery();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">for</span> (<span
class="cb1">int</span> i = 0; i &lt; queries.Count; i++)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; multiQuery.Add(resultCollectionGenericType[i], queries[i]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; results = multiQuery.List();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ((<span
class="cb2">SessionImpl</span>)session).FutureQueryBatch = <span
class="cb1">null</span>;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> results;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add&lt;T&gt;(<span
class="cb2">IQuery</span> query)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; queries.Add(query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; resultCollectionGenericType.Add(<span
class="cb1">typeof</span>(T));</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; index = queries.Count - 1;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add(<span
class="cb2">IQuery</span> query)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Add&lt;<span
class="cb1">object</span>&gt;(query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IFutureValue</span>&lt;T&gt; GetFutureValue&lt;T&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">FutureValue</span>&lt;T&gt;(() =&gt; (<span
class="cb2">IList</span>&lt;T&gt;)Results[currentIndex]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IEnumerable</span>&lt;T&gt; GetEnumerator&lt;T&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">DelayedEnumerator</span>&lt;T&gt;(() =&gt; (<span
class="cb2">IList</span>&lt;T&gt;)Results[currentIndex]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>They are almost exactly the same, which is obviously a problem.  The root cause of this situation is that there is no common interface between IQuery and ICriteria, and there also isn't a common interface between IMultiQuery and IMultiCriteria.  Introducing those interfaces would make a lot of things easier, but can't be done right now.  Still, that shouldn't prevent us from striving to avoid duplicate code.</p><p>This is actually pretty easy to do... here's the new FutureBatch class:</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">abstract</span> <span
class="cb1">class</span> <span
class="cb2">FutureBatch</span>&lt;TQueryApproach, TMultiApproach&gt;</p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">List</span>&lt;TQueryApproach&gt; queries = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;TQueryApproach&gt;();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">readonly</span> <span
class="cb2">IList</span>&lt;System.<span
class="cb2">Type</span>&gt; resultTypes = <span
class="cb1">new</span> <span
class="cb2">List</span>&lt;System.<span
class="cb2">Type</span>&gt;();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">int</span> index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb2">IList</span> results;</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">readonly</span> <span
class="cb2">SessionImpl</span> session;</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> FutureBatch(<span
class="cb2">SessionImpl</span> session)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">this</span>.session = session;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IList</span> Results</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">get</span></p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">if</span> (results == <span
class="cb1">null</span>)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GetResults();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> results;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add&lt;TResult&gt;(TQueryApproach query)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; queries.Add(query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; resultTypes.Add(<span
class="cb1">typeof</span>(TResult));</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; index = queries.Count - 1;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">void</span> Add(TQueryApproach query)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Add&lt;<span
class="cb1">object</span>&gt;(query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IFutureValue</span>&lt;TResult&gt; GetFutureValue&lt;TResult&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">FutureValue</span>&lt;TResult&gt;(() =&gt; GetCurrentResult&lt;TResult&gt;(currentIndex));</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb2">IEnumerable</span>&lt;TResult&gt; GetEnumerator&lt;TResult&gt;()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">int</span> currentIndex = index;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> <span
class="cb1">new</span> <span
class="cb2">DelayedEnumerator</span>&lt;TResult&gt;(() =&gt; GetCurrentResult&lt;TResult&gt;(currentIndex));</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb1">void</span> GetResults()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">var</span> multiApproach = CreateMultiApproach();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">for</span> (<span
class="cb1">int</span> i = 0; i &lt; queries.Count; i++)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; AddTo(multiApproach, queries[i], resultTypes[i]);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; results = GetResultsFrom(multiApproach);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ClearCurrentFutureBatch();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">private</span> <span
class="cb2">IList</span>&lt;TResult&gt; GetCurrentResult&lt;TResult&gt;(<span
class="cb1">int</span> currentIndex)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> (<span
class="cb2">IList</span>&lt;TResult&gt;)Results[currentIndex];</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">abstract</span> TMultiApproach CreateMultiApproach();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">abstract</span> <span
class="cb1">void</span> AddTo(TMultiApproach multiApproach, TQueryApproach query, System.<span
class="cb2">Type</span> resultType);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">abstract</span> <span
class="cb2">IList</span> GetResultsFrom(TMultiApproach multiApproach);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">abstract</span> <span
class="cb1">void</span> ClearCurrentFutureBatch();</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And now the original 2 classes look like this:</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">class</span> <span
class="cb2">FutureCriteriaBatch</span> : <span
class="cb2">FutureBatch</span>&lt;<span
class="cb2">ICriteria</span>, <span
class="cb2">IMultiCriteria</span>&gt;</p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> FutureCriteriaBatch(<span
class="cb2">SessionImpl</span> session) : <span
class="cb1">base</span>(session) {}</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb2">IMultiCriteria</span> CreateMultiApproach()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> session.CreateMultiCriteria();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb1">void</span> AddTo(<span
class="cb2">IMultiCriteria</span> multiApproach, <span
class="cb2">ICriteria</span> query, System.<span
class="cb2">Type</span> resultType)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; multiApproach.Add(resultType, query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb2">IList</span> GetResultsFrom(<span
class="cb2">IMultiCriteria</span> multiApproach)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> multiApproach.List();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb1">void</span> ClearCurrentFutureBatch()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; session.FutureCriteriaBatch = <span
class="cb1">null</span>;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>and</p><p><code><style type="text/css">.cf{font-family:Consolas;font-size:9pt;color:black;background:white}.cl{margin:0px}.cb1{color:blue}.cb2{color:#2b91af}</style></p><div
class="cf"><p
class="cl">&nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> <span
class="cb1">class</span> <span
class="cb2">FutureQueryBatch</span> : <span
class="cb2">FutureBatch</span>&lt;<span
class="cb2">IQuery</span>, <span
class="cb2">IMultiQuery</span>&gt;</p><p
class="cl">&nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">public</span> FutureQueryBatch(<span
class="cb2">SessionImpl</span> session) : <span
class="cb1">base</span>(session) {}</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb2">IMultiQuery</span> CreateMultiApproach()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> session.CreateMultiQuery();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb1">void</span> AddTo(<span
class="cb2">IMultiQuery</span> multiApproach, <span
class="cb2">IQuery</span> query, System.<span
class="cb2">Type</span> resultType)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; multiApproach.Add(resultType, query);</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb2">IList</span> GetResultsFrom(<span
class="cb2">IMultiQuery</span> multiApproach)</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">return</span> multiApproach.List();</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
class="cb1">protected</span> <span
class="cb1">override</span> <span
class="cb1">void</span> ClearCurrentFutureBatch()</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; session.FutureQueryBatch = <span
class="cb1">null</span>;</p><p
class="cl">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
class="cl">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>They are still very similar, but at least it's a big improvement over the original situation.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2009%2F04%2Fgotta-love-refactoring%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2009/04/gotta-love-refactoring/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2009/04/gotta-love-refactoring/"  data-text="Gotta Love Refactoring" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2009/04/gotta-love-refactoring/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2009/04/gotta-love-refactoring/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2009/04/gotta-love-refactoring/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 2/89 queries in 0.055 seconds using disk: basic
Object Caching 1543/1725 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-05-23 14:22:05 -->
