<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>The Inquisitive Coder - Davy Brion's Blog</title> <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> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/davybrion" /><feedburner:info uri="davybrion" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>davybrion</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>And… That’s All Folks</title><link>http://feedproxy.google.com/~r/davybrion/~3/BbaDji_ccF0/</link> <comments>http://davybrion.com/blog/2012/05/and-thats-all-folks/#comments</comments> <pubDate>Mon, 14 May 2012 21:08:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[About The Blog]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3982</guid> <description><![CDATA[I started blogging about 5 years ago, and over the years I've published 653 posts. This will be the last one. I had some specific personal goals in mind when I started blogging, and I've gotten everything I've wanted out of it, and more. I learned a lot, and I'm happy with a lot of [...]]]></description> <content:encoded><![CDATA[<p>I started blogging about 5 years ago, and over the years I've published 653 posts. This will be the last one. I had some specific personal goals in mind when I started blogging, and I've gotten everything I've wanted out of it, and more. I learned a lot, and I'm happy with a lot of the feedback I've gotten over the years. But the time has come to move on. I want to get back to writing more code instead of writing about writing code. I've mostly enjoyed writing blog posts, but in the past year it has felt more like a chore than a hobby, so it's probably a good idea to just call it quits.</p><p>I'm not entirely sure yet what I'm going to do with the content on this blog. There's quite a few posts I surely want to keep around, but certainly not all of them. For now, I'm going to keep the blog up so everything stays available but after a while, I'm gonna shut it down. I might keep up some kind of static archive of my favorite posts, or I might just put them on GitHub in MarkDown format. If you have any suggestions on what I should do with it, I'd be happy to hear them.</p><p>I will remain active on <a
href="http://twitter.com/davybrion">Twitter</a> and I plan to be more active on <a
href="http://github.com/davybrion">GitHub</a> from now on. But the blogging thing ends here and now. I'd like to thank everyone for reading, especially the ones who've been around since the beginning. It's been an interesting ride for me, but it's time for something else <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=BbaDji_ccF0:1amUMIKr8i0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=BbaDji_ccF0:1amUMIKr8i0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=BbaDji_ccF0:1amUMIKr8i0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=BbaDji_ccF0:1amUMIKr8i0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=BbaDji_ccF0:1amUMIKr8i0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=BbaDji_ccF0:1amUMIKr8i0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=BbaDji_ccF0:1amUMIKr8i0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=BbaDji_ccF0:1amUMIKr8i0:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/BbaDji_ccF0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/05/and-thats-all-folks/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/05/and-thats-all-folks/</feedburner:origLink></item> <item><title>Why Things Don’t Work In Your World</title><link>http://feedproxy.google.com/~r/davybrion/~3/vmRCqUkdXLU/</link> <comments>http://davybrion.com/blog/2012/05/why-things-dont-work-in-your-world/#comments</comments> <pubDate>Sun, 13 May 2012 18:50:36 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3977</guid> <description><![CDATA[A very common reaction for developers to have when they hear about new technical approaches or new approaches to team organization is "yeah right, that won't work in the real world" or "that'll never work in our situation". A lot of us have felt that way. I certainly have as well a few times in [...]]]></description> <content:encoded><![CDATA[<p>A very common reaction for developers to have when they hear about new technical approaches or new approaches to team organization is "yeah right, that won't work in the real world" or "that'll never work in our situation". A lot of us have felt that way. I certainly have as well a few times in the past. The 2 most common excuses you'll hear for not believing something can work are:</p><ol><li><p>The people I work with aren't good/talented/disciplined enough to make this work.</p></li><li><p>It can't possibly work in our organization.</p></li></ol><p>The truth though, is that it's actually because of <em>you</em>. Whenever you say "that won't work for us" or something similar because of the people you work with, you immediately show your lack of faith in them. You might think that that lack of faith is justified, but that basically means you've given up all hope of making things better. You know it, and worst of all, <em>they know it too</em>. People who aren't trusted by their coworkers or superiors generally pick up on that rather quickly. Some of them will respond by putting in more effort and trying to do better. Others will become demotivated and wonder why they should even try because "it's never good enough anyway". At this point, your lack of trust in your coworkers becomes a self-fulfilling prophecy.</p><p>You might want to consider another approach. Think back on how you've responded to situations where you where challenged by coworkers or superiors but where it was clear that they trusted you and believed that you were capable of doing a better job. I'd bet that for most of you, it improved your motivation and your willingness to do better. It probably helped you bring out the best in you. You can use this to your advantage when you're trying to get better results out of your coworkers. It's quite simple really: it's all about how you approach someone. If you want somebody to do better, and you approach them in a positive manner you're much more likely to get better results. If however, they sense your distrust (and most people pick up on that quite easily), they will most likely be defensive or apprehensive. The odds are quite low that something good will come out of that.</p><p>If you want people to improve and do better, it's important to establish a culture where everybody knows that it's <em>ok</em> to make mistakes, and that every mistake is an opportunity for the whole team to get better. If that's not the case in your situation, what is preventing you from trying to get to that point? Even if you're not officially in a leadership position, there's no reason why you can't set the tone and <em>be a leader</em>. Start making an impact on one or two people and build off of that growth. Once you've got a few people convinced, it's much easier to bring the rest along with you. You don't need to shoot for the stars from the beginning either. Try to improve whatever it is you think needs improvement with small steps, in an iterative approach. Instead of thinking "that will never work for my team", think "we're not quite ready for that <em>yet</em>, but we will be someday".</p><p>If you believe you can't improve your way of working due to organizational reasons, it's important to also start with your team. It's easy for management to ignore the opinion of one person, but it gets progressively harder for them to ignore it as more and more people start asking for change. It's much easier to persuade management to try something new if you can show that the whole team believes it's worth a shot. Keep pressing the issue until you get the chance to try it for a short time. If you keep asking for it, management might just get tired of hearing it and who knows, they'll grant you some time to try it out. You'll never know if you stop trying.</p><p>Of course, you won't always succeed in convincing management or your coworkers. But you've gotta try. And if you keep hitting walls, you might actually be better off moving on to another job with other people instead of being frustrated in your current position. Even if you don't agree with what I'm saying in this post, you can't possibly disagree with this: not trying will get you nowhere.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=vmRCqUkdXLU:0dHmB8pfeyA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=vmRCqUkdXLU:0dHmB8pfeyA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=vmRCqUkdXLU:0dHmB8pfeyA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=vmRCqUkdXLU:0dHmB8pfeyA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=vmRCqUkdXLU:0dHmB8pfeyA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=vmRCqUkdXLU:0dHmB8pfeyA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=vmRCqUkdXLU:0dHmB8pfeyA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=vmRCqUkdXLU:0dHmB8pfeyA:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/vmRCqUkdXLU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/05/why-things-dont-work-in-your-world/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/05/why-things-dont-work-in-your-world/</feedburner:origLink></item> <item><title>Three Strikes And You Refactor</title><link>http://feedproxy.google.com/~r/davybrion/~3/OFSdEDuJMHc/</link> <comments>http://davybrion.com/blog/2012/05/three-strikes-and-you-refactor/#comments</comments> <pubDate>Sun, 06 May 2012 14:36:10 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Code Quality]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3966</guid> <description><![CDATA[The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor. That's a quote from Don Roberts, found in Martin Fowler's Refactoring book (page 58). That quote didn't [...]]]></description> <content:encoded><![CDATA[<blockquote><p>The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor.</p></blockquote><p>That's a quote from Don Roberts, found in Martin Fowler's Refactoring book (page 58). That quote didn't really make me think twice at the time I read it, but it got stuck in my head later on when I heard it from someone who's always been very influential to me. When this person told me that this was one of his favorite rules, I was still in my "no way dude, all code needs to be as clean as it can be" phase. But it's really grown on me over the last few years. Now, just to avoid any confusion: this post is about <em>my interpretation</em> of 'Three Strikes And You Refactor', not about what may have been originally intended or what some people think of it now.</p><p>The most important thing I remember when learning about TDD was:</p><ol><li><p>Write a failing test</p></li><li><p>Do the simplest thing that could possibly work to make the test pass.</p></li><li><p>Refactor.</p></li></ol><p>With all the literature that's out there, as well as popular opinion on how important clean code is, it's tempting to go overboard with that 'refactor' step. It's tempting to go for the solution that is crispy clean. The solution that'll have your coworkers or peers go "ohhh, now <em>that</em> is nice". However, you really need to ask yourself the following question: "is it really worth it?". Wanting to make sure that every piece of code is perfect takes up a lot of time, and I've learned that it certainly isn't always worth it. Besides, it's quite easy to go off on a path of introducing new concepts and abstractions to your code that end up being totally unnecessary. If this increases complexity in parts that don't really matter, it ends up being a huge waste. Not only for the person who wrote it, but for every person who has to read it and comprehend it later on.</p><p>'Three Strikes And You Refactor' is a helpful rule of thumb here. Try to keep things as simple as possible and don't be afraid of a <em>little</em> duplication here or there. Once you find yourself (or a teammate) doing the same thing for a third time, it's worth cleaning up because that third time very often means that it wouldn't be the last time either. This way, you only introduce concepts and abstractions that are really needed, and enables you to avoid adding unnecessary cruft to the code.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=OFSdEDuJMHc:gDoJMj70oqo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OFSdEDuJMHc:gDoJMj70oqo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OFSdEDuJMHc:gDoJMj70oqo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OFSdEDuJMHc:gDoJMj70oqo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OFSdEDuJMHc:gDoJMj70oqo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OFSdEDuJMHc:gDoJMj70oqo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OFSdEDuJMHc:gDoJMj70oqo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OFSdEDuJMHc:gDoJMj70oqo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/OFSdEDuJMHc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/05/three-strikes-and-you-refactor/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/05/three-strikes-and-you-refactor/</feedburner:origLink></item> <item><title>It’s Not About The Number Of Hours You Put In</title><link>http://feedproxy.google.com/~r/davybrion/~3/uXaRMjqjhFA/</link> <comments>http://davybrion.com/blog/2012/04/its-not-about-the-number-of-hours-you-put-in/#comments</comments> <pubDate>Thu, 19 Apr 2012 19:35:18 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3961</guid> <description><![CDATA[There's been a lot of talk on twitter about the 501 Manifesto. Be sure to read it if you haven't, because it's got some very good points, though I don't like the dig at people who contribute to open source since these people are having an ever increasing positive impact on our jobs. Anyways, the [...]]]></description> <content:encoded><![CDATA[<p>There's been a lot of talk on twitter about the <a
href="http://501manifesto.org/">501 Manifesto</a>. Be sure to read it if you haven't, because it's got some very good points, though I don't like the dig at people who contribute to open source since these people are having an ever increasing positive impact on our jobs. Anyways, the manifesto is about being a software developer without being defined by it. I actually think it's a healthy point of view.</p><p>I've always disagreed with this seemingly popular point of view or opinion that every developer should spend a lot of time outside of his/her working hours blogging or publishing their code on Github or contributing to open source. Those activities <em>can</em> be important but aren't necessarily so and the people doing them aren't inherently more valuable or important than developers who choose not to contribute to open source software or who don't feel the need to make a name for themselves. I also disagree with the notions that developers who are only involved with software development during their 8 working hours a day must be inferior or that they can't be passionate about it or that they'll never be great at it or any of that other crap that you'll sometimes hear people say.</p><p>I know some great developers who put their code out there and/or their thoughts by blogging. I also know some bad developers who put their code out there and/or their thoughts by blogging. I know some great developers who aren't involved with software development outside their working hours. I also know some bad developers who aren't involved with software development outside their working hours. There are good and bad developers on both sides of every situation you can come up with.</p><p>I think it depends a lot on what people do <em>during their 8 working hours</em>. Can we really say that developers who work 8 hours a day on challenging projects with strong co-workers in teams where knowledge is passed around continuously are missing out on anything if they don't really spend any other time on software development outside of work? That just doesn't make a lot of sense to me. If I look back on my own career so far, I've typically been rather passive outside of working hours in periods where I felt like I was working on cool things, where I was challenged, where I was learning a lot on the job. Conversely, I've always been much more involved with software development outside of work when I was working on things during working hours that I didn't find challenging or interesting or where I wasn't learning anything new. I'm guessing that this holds true for a lot of people, though certainly not all.</p><p>Of course, if you're not working on interesting things or continuously learning and improving on the job, it's your own responsibility to make sure that your skills and insights stay up to date. You don't <em>have</em> to put in the effort to do that, but if you don't, you don't really have a reason to complain either when you're not happy with the kind of work that you're doing. Your employer is not responsible for your career and your future, you are.</p><p>And if you are working on interesting things and continuously learning and improving on the job, you don't need to pressure yourself to do more outside of your working hours because certain people in the community say you should. A lot of people get involved with blogging and open source with the hope that it'll end up leading to more interesting work in the long term. Who knows, you might just be a step ahead of them already.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=uXaRMjqjhFA:Bygtonu7YhM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=uXaRMjqjhFA:Bygtonu7YhM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=uXaRMjqjhFA:Bygtonu7YhM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=uXaRMjqjhFA:Bygtonu7YhM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=uXaRMjqjhFA:Bygtonu7YhM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=uXaRMjqjhFA:Bygtonu7YhM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=uXaRMjqjhFA:Bygtonu7YhM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=uXaRMjqjhFA:Bygtonu7YhM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/uXaRMjqjhFA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/04/its-not-about-the-number-of-hours-you-put-in/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/04/its-not-about-the-number-of-hours-you-put-in/</feedburner:origLink></item> <item><title>Most Valuable Professionals? Give Me A Break.</title><link>http://feedproxy.google.com/~r/davybrion/~3/v0N7GPTJ8-o/</link> <comments>http://davybrion.com/blog/2012/04/most-valuable-professionals-give-me-a-break/#comments</comments> <pubDate>Sun, 15 Apr 2012 18:11:49 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[Rants]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3950</guid> <description><![CDATA[I've always been very skeptical of Microsoft's MVP award. Officially, Microsoft's MVP award stands for Most Valuable Professional, but its true meaning is probably closer to Most Valuable Promoter. The quality and integrity of the MVP's you know is probably dependent on the region in which you work. I work in Belgium, and over here [...]]]></description> <content:encoded><![CDATA[<p>I've always been very skeptical of Microsoft's MVP award. Officially, Microsoft's MVP award stands for Most Valuable Professional, but its true meaning is probably closer to Most Valuable Promoter. The quality and integrity of the MVP's you know is probably dependent on the region in which you work. I work in Belgium, and over here the MVP program is, in my opinion, a joke. I'm going to discuss why I think it's a joke but keep in mind that this will depend on your region. I know that there are indeed great MVP's out there who do have professional integrity and true real world experience in some regions, but I certainly wouldn't be surprised if the state of the MVP program in Belgium occurs in other regions as well.</p><p>First of all, let's take a look at an image that Microsoft uses on its <a
href="http://mvp.support.microsoft.com/">MVP page</a>:</p><p><img
src="http://davybrion.com/mvp.png" alt="MVP image" /></p><p>"Independent Experts. Real world Answers."</p><p>This is indeed what the MVP program <em>should</em> be about. It is however the exact opposite of what I and many others in Belgium have experienced. Let's cover the words in those 2 sentences a bit more in-depth.</p><h3>Independent</h3><p>Most of the .NET MVP's in Belgium work for a handful of companies that happen to be big sponsors of every important Microsoft event in Belgium. Now, could it be possible that the best .NET developers in Belgium all work for these handful of companies? I highly doubt it. I know a lot of great developers in Belgium and none of them work for these companies. And I'm quite sure that none of those people are less valuable or knowledgeable than any of those MVP's. In my experience, there is hardly anything independent about the Belgian .NET MVP's. Most of them got their first MVP award while they were employed by sponsors or 'strategic partners' of Microsoft. Most of them tout the latest and greatest Microsoft technologies, pretty much unquestioned, even if it means contradicting their statements and positions when they were promoting the technology that Microsoft wanted them to promote 3 or 4 years ago. And they're never openly critical of anything Microsoft-related out of fear that it will negatively impact their chances of being renewed as an MVP. They may not work for Microsoft, but they are anything but independent of Microsoft.</p><h3>Experts</h3><p>This is a tough one. What makes one an expert? In some fields, people are considered to be experts based on the amount of research they've done. In other fields, people are considered to be experts based on what they've actually done. I don't think I'm going out on a limb here by saying that in the field of software development, what you've done <em>should</em> be more important than what you've researched or read about. In my opinion, an expert in a specific technology should have built at least one, and ideally more than one, non-trivial system using the technology in question and should be able to tell you about mistakes they've made, things you should avoid, and should never use examples that promote bad practices. I rarely hear MVP's talk about things you should avoid. I rarely hear MVP's talk about mistakes they've learned from. I routinely see examples from MVP's that make me cringe. I routinely hear MVP's promote technologies even though they haven't actually built anything impressive with it. I think of a lot of words when I see examples or proposed solutions by MVP's, but the word 'expert' unfortunately isn't one of them. This also applies to the Microsoft Extended Experts Team by the way. I can only question the validity of such a team if it contains people who are listed as experts of a particular technology when I happen to know for a fact that some of those people have never even used the technology they're supposed to be an expert in in a real world project. Let's be honest here: most of the MVP's and the MEET members simply aren't experts. They are people who have a strong interest in a particular (or more) technology and do their best to promote said technology. There's nothing wrong with that at all, but there's a huge difference between that and being an expert in something.</p><h3>Real world answers</h3><p>This one cracks me up the most because most of the Belgian MVP's hardly work on real world projects. And when they do, they typically work on "multiple projects" as they like to say it. For anyone who's ever worked on multiple projects at the same time: could you honestly say that your contributions were truly valuable to the end result? Let me put it differently: don't we all know that people generally produce the best results when they don't have to juggle too many things at once and can focus on as few things as possible? You will rarely hear about a Belgian MVP working full time on a non-trivial real-world project. A lot of them get to spend a certain number of paid hours each week on 'community work', which means blogging, writing articles for magazines, creating presentations for events, etc. When they're not working on that, you'll often find them talking on Twitter about pretty much anything but interesting or demanding work. And of course, their employers will occasionally send them to clients for a bit of consulting here or there, or to do a product demo. Unless these guys are putting in 60 to 80 hours a week (which I seriously doubt), I'm having trouble figuring out when exactly they do the kind of interesting work on real world projects that would enable them to provide answers based on real world experience.</p><p>It also doesn't help that I've frequently heard rather unflattering stories about these MVP's from people who've worked with them. It's pretty much always the same: they're not invested into the project, they spend too much time 'interacting with the community' and if you let them go near important parts of the code base, bad things usually happen. Now, I'm not the type of person who simply believes everything he hears. In fact, when it comes to matters like these, I generally only believe the stories I hear from people of whom I'm truly sure that they know what they're talking about. And if you've been reading this blog for a while, you'll know I'm rather critical and that I set the bar rather high when it comes to that.</p><p>Lastly, my personal working experience with MVP's has been abysmal as well. I once worked for a client where we had to get rid of 2 people because of how bad they performed in real world circumstances. One of them was an MVP at the time, and now works at Microsoft as an Evangelist. The other wasn't an MVP at the time, but has been one for a few years now and is even one of the Regional Directors of this region. A few years later, I had drinks with a manager of the company they both worked for and he bluntly admitted that both of them are useless on real projects but that their MVP status was a huge benefit to the company from a marketing and image perspective. Not exactly the image or branding I'd be looking to put out there, but hey, to each his own.</p><h3>Why On Earth Did I Write This?</h3><p>For 2 reasons. I think this whole MVP thing sets a bad example to young and impressionable developers who aren't sure what to focus on to advance their careers. To outsiders, these MVP's sure look like they've got a great thing going and it's easy to see how that could impress people who don't know better. There are already quite a few developers who suck up to these MVP's in the hopes of someday getting to 'that level' as well. I'd much rather see these people put effort into learning about concepts that will last them a long time and building skills that are transferable to multiple technologies instead of sucking up to the wrong people, and trying to network their way to more interesting work because the work that results from that is truly mediocre at best. By all means, try to make a name for yourself by blogging and speaking publicly. But do yourself a favor and stay true to yourself and favor quality over quantity when considering the audience you want to target. Hey, it worked for me <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>The second reason is because this whole MVP thing is, in my opinion at least, offensive to the many dedicated professionals who give their all at their jobs as they work on real projects that matter, as they try to mentor younger developers in their workplace, as they try to optimize the way they develop software not only for themselves, but for their teammates and their employers or clients. These are your true <em>valuable professionals</em>.</p><p>I'm sure I'm gonna get a lot of flak for this post, but honestly, it won't really make any difference to me. The people who'll be offended are people I'd rather not work with anyway. And of course, I feel quite confident that I'll rarely, if ever, have to deal with these people in a professional setting since I'm primarily interested in interesting and demanding work <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=v0N7GPTJ8-o:IFYpPR8TCZk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=v0N7GPTJ8-o:IFYpPR8TCZk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=v0N7GPTJ8-o:IFYpPR8TCZk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=v0N7GPTJ8-o:IFYpPR8TCZk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=v0N7GPTJ8-o:IFYpPR8TCZk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=v0N7GPTJ8-o:IFYpPR8TCZk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=v0N7GPTJ8-o:IFYpPR8TCZk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=v0N7GPTJ8-o:IFYpPR8TCZk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/v0N7GPTJ8-o" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/04/most-valuable-professionals-give-me-a-break/feed/</wfw:commentRss> <slash:comments>29</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/04/most-valuable-professionals-give-me-a-break/</feedburner:origLink></item> <item><title>Microsoft And Open Source: Hoping For Better Collaboration</title><link>http://feedproxy.google.com/~r/davybrion/~3/ZetNB_-CXM0/</link> <comments>http://davybrion.com/blog/2012/04/microsoft-and-open-source-hoping-for-better-collaboration/#comments</comments> <pubDate>Mon, 09 Apr 2012 14:04:48 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3944</guid> <description><![CDATA[By now, you've probably all heard that Microsoft is moving to an open development model for ASP.NET MVC and some other ASP.NET projects. Even though the source code of ASP.NET MVC has always been available under an open source license, its development followed a closed development model. This meant that outside contributions weren't possible, nor [...]]]></description> <content:encoded><![CDATA[<p>By now, you've probably all heard that Microsoft is moving to an open development model for ASP.NET MVC and some other ASP.NET projects. Even though the source code of ASP.NET MVC has always been available under an open source license, its development followed a closed development model. This meant that outside contributions weren't possible, nor were we able to follow the actual commits in the MVC source code repository. With the recent announcements, this is no longer the case and I think this is fantastic news. It finally enables collaboration between Microsoft employees and people outside of Microsoft on a strategically important Microsoft product. This is good for Microsoft as well as the open source .NET community.</p><p>I hope that this newfound appreciation for Open Source within Microsoft will lead to another huge improvement in collaborative development in the open source .NET community. While Microsoft is now open to accepting contributions from the community, it would be a tremendous step forward if Microsoft would also contribute to other prominent open source .NET projects in the future. In the past, we've seen numerous open source .NET projects become popular and widely used. And unfortunately, Microsoft responded to some of those projects by producing their own libraries and frameworks that basically do the same thing. Except that, for most of those projects, they never quite matched the quality of the open source projects they were inspired by. If only all of that effort spent on duplicating already existing libraries would've been spent on <em>improving what was already there</em>, the entire .NET community would've been better for it.</p><p>I'd love to see a Microsoft that works <em>with</em> open source developers and encourages them, instead of trying to duplicate their efforts whenever they feel they need to provide their own library or framework for something that's already covered by a superior open source alternative. These duplicated projects only alienate people that at one point were passionate enough about the .NET platform to work on improving it for free, in their spare time. These are the people that Microsoft needs to cherish and nourish instead of competing with them. Microsoft has shown some interesting signs of better understanding of open source development and collaboration in the past year or so. Here's to hoping they take that critical next step as well.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=ZetNB_-CXM0:Q3Vmo47-Fxg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ZetNB_-CXM0:Q3Vmo47-Fxg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ZetNB_-CXM0:Q3Vmo47-Fxg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ZetNB_-CXM0:Q3Vmo47-Fxg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ZetNB_-CXM0:Q3Vmo47-Fxg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ZetNB_-CXM0:Q3Vmo47-Fxg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=ZetNB_-CXM0:Q3Vmo47-Fxg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=ZetNB_-CXM0:Q3Vmo47-Fxg:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/ZetNB_-CXM0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/04/microsoft-and-open-source-hoping-for-better-collaboration/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/04/microsoft-and-open-source-hoping-for-better-collaboration/</feedburner:origLink></item> <item><title>What’s The Point Of Using WCF In A Web App?</title><link>http://feedproxy.google.com/~r/davybrion/~3/p7TClTj7aaA/</link> <comments>http://davybrion.com/blog/2012/03/whats-the-point-of-using-wcf-in-a-web-app/#comments</comments> <pubDate>Sun, 18 Mar 2012 16:28:28 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Code Quality]]></category> <category><![CDATA[Performance]]></category> <category><![CDATA[WCF]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3938</guid> <description><![CDATA[A very common approach of building web applications in .NET is to put most of the non-UI related code behind an internal WCF service layer. I used to be a fan of this approach as well, but these days I just don't see the benefit of that internal service layer anymore. The overhead that an [...]]]></description> <content:encoded><![CDATA[<p>A very common approach of building web applications in .NET is to put most of the non-UI related code behind an internal WCF service layer. I used to be a fan of this approach as well, but these days I just don't see the benefit of that internal service layer anymore. The overhead that an internal WCF service layer adds to development, deployment and runtime performance just doesn't stack up favorably to the supposed benefits IMO. To be clear: I'm talking about WCF services that will <em>only</em> be used by the front end of your web application.</p><p>Let's talk about the overhead on development first. If you're using WCF services in your web app, you need proxies to access those services. Some people prefer to generate the proxies based on the WSDL of the services that will be used. In the worst case, this leads to regenerating proxies and all of the types that are defined in the WSDL every time you change a service contract or one of the types that are used by the services. If multiple people need to make changes to any of these concurrently, this easily leads to merging problems when people need to commit their changes. Another way is to share the same types on both sides (client &amp; server), and implement your service proxies by inheriting from ClientBase and manually keeping the implementation of the proxies up to date with the definitions of their service contracts. This is better than regenerating a bunch of code all the time, but you're still writing a lot of redirection code for the purpose of, well, what exactly? Another possibility is to use dynamic proxies which automatically implement the service contracts but this increases the amount of infrastructure code you need to put in place and it's not always clear to everyone how exactly communication with the services happens. There's also a lot of WCF configuration for each service that you need to maintain, and it can quickly grow unwieldy.</p><p>Then there's the overhead on performance. I hope we can all agree that any operation that goes out of process is at least an order of magnitude slower than a similar operation that can be executed in process. First of all, there's the networking overhead (even if your services are hosted on the same machine as the web app) that you have to keep into account. Secondly, there is the cost of serializing and deserializing <em>everything</em> that is transferred between the client and the server. Even with the most efficient bindings and serializers, the cost of all of this quickly adds up on high-traffic web apps. That's not to say that WCF services are inherently slow. They can be very fast and efficient, but they'll never be as fast and efficient as executing that logic in process within the web app.</p><p>Finally, there's the extra overhead it introduces to the deployment phase:</p><ul><li>more endpoints to set up and transfer artifacts to</li><li>more configuration</li><li>more monitoring of endpoints</li><li>more servers if you're not hosting the services and the web app on the same machine</li></ul><p>Of course, people will argue that there a plenty of benefits to using a WCF service layer in a web app. The ones I hear about most often are the forced separation of business logic and UI logic and improved scalability and reliability. I really disagree that you need a physical separation of business and UI logic. I much prefer approaches where the separation is based on abstractions. A good example was recently posted by Ayende (<a
href="http://ayende.com/blog/154241/limit-your-abstractions-the-key-is-in-the-infrastructurehellip">here</a> and <a
href="http://ayende.com/blog/154273/limit-your-abstractions-and-how-do-you-handle-testing">here</a>). And when it comes to scalability/reliability, a web app that isn't dependent on a WCF service layer is as easy (or even easier depending on your setup) to scale than one that is entirely dependent on WCF services. First of all, if you care about scalability/reliability your web app should already be prepared to run behind a load balancer. If you already have a load balancer in place, you can just add more web servers to your setup when needed. If you'd host the WCF services on the same machines that are hosting the web front end, you'd get less total throughput from one server than you would if that one server could just host a web app that fully executes in process (not including the database obviously). If you're hosting the WCF services on separate machines, you'd end up with more servers to handle the load and to achieve the reliability you need than you would with just being able to add more web servers to your setup. That also increases your licensing costs. And of course, it also means increased networking overhead on every service call, which also implies that the threads on your web servers will be blocked for longer periods while they wait for those service calls to return. Unless you're calling those services asynchronously, but most people simply don't. Also, if you have serious scalability and reliability requirements you're probably better off with asynchronous messaging solutions than with SOAP services.</p><p>WCF has its benefits (though I prefer Web API's or asynchronous messaging over SOAP services these days) and it has its use cases. I just don't think internal service layers for web apps is one of them.</p><p>What are the benefits that you think an internal WCF service layer brings to your web app? And what's your opinion on how they stack up versus the downsides?</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=p7TClTj7aaA:Euy9rEjAZC4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=p7TClTj7aaA:Euy9rEjAZC4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=p7TClTj7aaA:Euy9rEjAZC4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=p7TClTj7aaA:Euy9rEjAZC4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=p7TClTj7aaA:Euy9rEjAZC4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=p7TClTj7aaA:Euy9rEjAZC4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=p7TClTj7aaA:Euy9rEjAZC4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=p7TClTj7aaA:Euy9rEjAZC4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/p7TClTj7aaA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/03/whats-the-point-of-using-wcf-in-a-web-app/feed/</wfw:commentRss> <slash:comments>38</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/03/whats-the-point-of-using-wcf-in-a-web-app/</feedburner:origLink></item> <item><title>Thoughts On Learning New Things</title><link>http://feedproxy.google.com/~r/davybrion/~3/OUX2zAPDwqw/</link> <comments>http://davybrion.com/blog/2012/03/thoughts-on-learning-new-things/#comments</comments> <pubDate>Sun, 11 Mar 2012 20:22:23 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Opinions]]></category> <category><![CDATA[work/career]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3933</guid> <description><![CDATA[Jef Claes published an interesting post about his preferred way of learning new things. There's one part in the post that I don't entirely agree with: I like to believe learning should be a hands-on activity as well. Basically, stop consuming, start producing. Don't get me wrong, I do think there is value in reading [...]]]></description> <content:encoded><![CDATA[<p>Jef Claes published an <a
href="http://jclaes.blogspot.com/2012/03/learning-hacker-way.html">interesting post</a> about his preferred way of learning new things. There's one part in the post that I don't entirely agree with:</p><blockquote><p>I like to believe learning should be a hands-on activity as well. Basically, stop consuming, start producing. Don't get me wrong, I do think there is value in reading blog posts (I might be slightly biased on this one), reading books and watching videos, but I find that this value is marginal compared to what you gain by actually doing it.</p></blockquote><p>Hands-on activity (producing) is certainly a very important part of any learning process, but I wouldn't go as far saying that the value of reading books/blogs (consuming) is marginal compared to that of producing. In fact, I believe their value to be pretty equal. I've seen too many people who start producing simple things, and then think they've got a pretty good grasp of the technology they're using and then move on to producing more complex or bigger things without actually knowing enough of the technology they're using to support the more complex or bigger scenarios. The results certainly aren't always pretty and I'm sure each and every one of you has seen this scenario unfold with at least one developer you know. Probably more than that even.</p><p>I think in a lot of cases, people start the producing phase perhaps a bit too early and then in their enthusiasm of seeing things working sort of skip the more boring consuming that could've benefitted them a lot. Once you've started producing, you <em>need</em> to keep consuming regularly. A tremendously valuable part of any learning experience is getting feedback and insight from minds that have more experience with a given subject than yours. If you're lucky, you can get this from your coworkers. If you're not that lucky, you'll need to find other sources and books, blogs, videos, user group meetings, etc can be a great way to fill that void. And even if you do get to learn a lot from your coworkers, it <em>never</em> hurts to learn more from the experiences of others outside of your immediate circle, if only because their situations and constraints will differ from yours as well.</p><p>The other very important part about consuming is really getting to know the technology you're trying to learn. I've always found it very important to at least get an idea of how things work internally within a technology that I'm using. You certainly don't need to know all of the implementation details but just having an idea of it can really help you avoid a lot of problems once you need to use a technology in a more advanced way than in your initial experiments. Most importantly, it should give you better insights as to whether you're using the technology <em>properly</em>, which unfortunately isn't always the same as getting something working. And as a bonus, you'll probably learn about features you won't immediately need but knowing that they're there can save quite a bit of time and effort later on. Just imagine the improvement of the signal-to-noise ratios that you'd see on mailinglists, forums, and StackOverflow if everyone took the time to get a better grasp of the technologies they're using.</p><p>When I start with learning new libraries or frameworks, I usually start off by reading most (and often, all) of the official documentation of the technology before I even get into building something myself. If I want to learn a new programming language I'll look for the most recommended books for that language and buy one (or more, if I wasn't satisfied with the first one). I won't even start using the language until I've gone through the book. Once I feel like I've got a pretty good theoretical grasp of the technology, I start building something with it. I also start looking for good blogs on the technology and subscribe to them. I'll also start following influential people of the technology on Twitter. And I just continuously try to soak up as much knowledge as I can from people who're doing more impressive things with the technology than I am. At first, you might not understand everything they're talking about but after a while, things just start clicking and you're getting a really good grasp of things. None of this is a substitute for learning from producing, but it certainly is an incredible addition to it. And one that makes a world of difference, IMO.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=OUX2zAPDwqw:Aj21QQibZNE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OUX2zAPDwqw:Aj21QQibZNE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OUX2zAPDwqw:Aj21QQibZNE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OUX2zAPDwqw:Aj21QQibZNE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OUX2zAPDwqw:Aj21QQibZNE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OUX2zAPDwqw:Aj21QQibZNE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=OUX2zAPDwqw:Aj21QQibZNE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=OUX2zAPDwqw:Aj21QQibZNE:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/OUX2zAPDwqw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/03/thoughts-on-learning-new-things/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/03/thoughts-on-learning-new-things/</feedburner:origLink></item> <item><title>Architectural Drivers</title><link>http://feedproxy.google.com/~r/davybrion/~3/yuIOGHkNr8w/</link> <comments>http://davybrion.com/blog/2012/02/architectural-drivers/#comments</comments> <pubDate>Sun, 26 Feb 2012 17:10:50 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3912</guid> <description><![CDATA[There are many different opinions and preferences when it comes to how we should deal with software architecture. My personal preference is to try not to make things more complex than they should be, while striving to maintain enough flexibility to be able to deal with future changes in both functional and non-functional requirements in [...]]]></description> <content:encoded><![CDATA[<p>There are many different opinions and preferences when it comes to how we should deal with software architecture. My personal preference is to try not to make things more complex than they should be, while striving to maintain enough flexibility to be able to deal with future changes in both functional and non-functional requirements in a way that hopefully doesn't require extensive effort. I've always thought of good architecture essentially being something that enables developers to keep implementing new features over time at a similar cost than what it took to implement features in the early stages of development. Thus I prefer to try to find a balance between simplicity of the codebase, and making sure that the architecture scales nicely (from a code quality point of view) as the application grows in functionality. I also like to make sure that we can scale out (from a performance/throughput point of view) relatively easily if that need to scale comes up. These are just my general preferences though, and aren't always relevant to every project or suitable for every situation. I'm now in the 10th year of my career and have seen a variety of architectural styles in the wild, and of course I've read and heard about many more since the subject has always interested me a lot. I've learned that it's important to keep <em>architectural drivers</em> of a project in mind when thinking about what kind of architecture is suitable for a certain project or situation. Those drivers are often more important than whatever your personal preferences are. I've come up with a list of drivers that I think should influence the architecture used by teams or organizations.</p><h3>Simplicity/Complexity of the application</h3><p>A common mistake is to decide to use a fashionable architectural style in a project that doesn't really have enough complexity to warrant the use of said architectural style. For instance, there's no reason whatsoever to go the DDD route if your application is mostly a forms-over-data CRUD app. You won't really get any benefit from it, and you'll only increase the total cost of the required development effort. On the other hand, an application which will feature a lot of <em>behavior</em> in a complex domain will certainly benefit from using a DDD approach versus a data-driven approach that implements the behavior in a more procedural, transaction-script based approach. Be honest to your customer/employer and <em>yourself</em> and make an objective decision based on the simplicity or the complexity of the required solution that you're being paid to build. Don't let enthusiasm for a fashionable architectural style influence your decision.</p><h3>Expected lifetime of the application</h3><p>Some applications live for years and years, and some are only temporary solutions that will be phased out a year or two after having been put in production. Of course, some of those temporary solutions end up being used much longer than what was originally expected due to a variety of reasons but that certainly isn't always a given. Unless you're familiar enough with how things typically go at your client or your company to predict these things, your best bet is to just go with the initially expected lifetime of the application. Does a temporary solution require the best possible architecture out there, and the resulting impact that would have on the cost to build it? I'd say it most often doesn't. In these cases, there's nothing wrong with going for the approach that is simply good enough for what is required. Striving for perfection is expensive, and generally not worth it for short-term solutions. Conversely, if the solution is expected to last a long time, a solid architecture becomes more important and is worth the extra investment to (try to) get it right if that makes it possible to keep the costs of long-term development under control.</p><h3>Strategic importance of the application</h3><p>Some applications are meant to improve the <em>core business</em> of a company, while others play a more supportive role in something that isn't actually part of the company's core business. Some applications generate revenue (directly or by improving efficiency of revenue-generating activities) while others are meant to reduce costs, typically administrative in nature. Cost reduction is important, but it's not quite as important as revenue generation and that's a factor that should be taken under consideration. A strategically important application almost always warrants putting in the effort to come up with a good architecture because it's highly likely that the application will have to evolve in whichever direction the business evolves. That's not to say that the same kind of effort wouldn't be important for cost-reducing applications. But it just might be less important than you'd like to think it is. Again, good architecture increases the cost of the project, and the return on that investment in the big picture of the company should not be ignored.</p><h3>Skill-level/discipline of team</h3><p>Good code and good architecture requires skill and discipline. A strong team is capable of letting good architecture grow organically and keep it at a high quality level. For a mediocre team, letting it grow organically is too often a recipe for disaster. Ideally, we'd always be working with strong teams but as we all know, that simply isn't always possible. For mediocre teams, it often makes sense to put architecture in place that is more restrictive in nature and where everyone knows how the code should be structured in advance. The downside is that this typically reduces flexibility and individual creativity, and often introduces more ceremony and indirection than what many of us would ideally like to see. But it's likely that those downsides are offset by having everyone on the same page and taking some possibly difficult decisions away from people who might not be strong enough to make the right decisions. I know that sounds harsh, but that's a reality that many of us have to deal with.</p><h3>Conformity/Continuity</h3><p>A lot of IT departments or software development companies prefer to use the same architecture and frameworks/libraries for most (or even all) of their projects because it makes it easier to have people work on multiple projects. In this situation, it's easier to move people between projects or have them do maintenance work on a project they weren't initially involved in. While this often prevents going with the most suitable approach for every project, it does introduce a few benefits that are hard to argue with. People will need less time to get familiar with a code base. In-house training and sharing of knowledge get easier. Bringing in new people (especially for temporary assignments) also gets somewhat easier because you have a baseline of required skills/knowledge that should go a long way within the organization. A huge downside however, is that it creates an environment that will quickly frustrate creative developers. Also, when new strong developers are brought in, they could quickly tune out once they realize they got there too 'late' to have any influence on how projects are developed. The interesting part about this driver is that it is influenced by the skill-level-discipline driver, while simultaneously influencing it towards the future.</p><h3>Non-functional requirements</h3><p>This is the last driver on the list, but it is certainly not the least important. Obviously, architecture is greatly influenced by some important non-functional requirements. There are many factors that can have a profound influence on what the most suitable architecture of a system could be, and it's important to think about those as quickly as possible. Do you need to respond in real time? Do you need to support mobile devices? Will there be connectivity issues? Will you need to scale massively? What are the auditing requirements? Are you dependent on third-party services? Do you need to minimize resource consumption? What kind of accessibility do you have to keep into account? The list goes on and on and many of these issues can end up becoming huge problems if you don't think about them ahead of time. Of course, you can't think of everything in advance, and many non-functional requirements can be introduced during the lifetime of the application instead of being known in advance. But the more you know in advance, the better you can prepare your software for them from the beginning.</p><h3>Conclusion</h3><p>There is a virtually endless variety of architectural choices and styles that can influence how you develop software. And unfortunately, there's a lot of dogma surrounding it as well. I hope this post made it clear that there is no definitive 'right' or 'wrong' when it comes to architecture, and that (as pretty much everything else in this business) it all really depends <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>I'm sure you can think of more architectural drivers, and I'd love to hear about any that you think I've forgotten.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=yuIOGHkNr8w:Ba16cBbiCmg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=yuIOGHkNr8w:Ba16cBbiCmg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=yuIOGHkNr8w:Ba16cBbiCmg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=yuIOGHkNr8w:Ba16cBbiCmg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=yuIOGHkNr8w:Ba16cBbiCmg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=yuIOGHkNr8w:Ba16cBbiCmg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=yuIOGHkNr8w:Ba16cBbiCmg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=yuIOGHkNr8w:Ba16cBbiCmg:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/yuIOGHkNr8w" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/02/architectural-drivers/feed/</wfw:commentRss> <slash:comments>7</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/02/architectural-drivers/</feedburner:origLink></item> <item><title>DTO’s Should Transfer Data, Not Entities</title><link>http://feedproxy.google.com/~r/davybrion/~3/wDCy16gD6Uc/</link> <comments>http://davybrion.com/blog/2012/02/dtos-should-transfer-data-not-entities/#comments</comments> <pubDate>Sun, 19 Feb 2012 19:32:17 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Architecture]]></category> <category><![CDATA[Code Quality]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3907</guid> <description><![CDATA[I've read a couple of posts recently where the authors were complaining about excessive mapping to DTO's and whether or not it's worth it. I've been a fan of DTO's for a long time, but I'm not a fan of how I frequently see them being used. More specifically, I very much dislike the all-too-common [...]]]></description> <content:encoded><![CDATA[<p>I've read a couple of posts recently where the authors were complaining about excessive mapping to DTO's and whether or not it's worth it. I've been a fan of DTO's for a long time, but I'm not a fan of how I frequently see them being used. More specifically, I very much dislike the all-too-common approach of creating a DTO for each entity in your domain model. In the worst cases, the DTO's actually reference each other and try too hard to mimic the structure of the entities. For example, an OrderDto which has a reference to a CustomerDto and a collection of OrderLineDto instances. In those cases, I absolutely agree that all of the mapping involved introduces way too much ceremony to the codebase without really offering any concrete benefits.</p><p>Of course, it really depends on the architecture of your system.  If you're using services that are only used by the front-end of your system, then I'd still advise against making those entities available outside of the service boundary for reasons that I've discussed <a
href="http://davybrion.com/blog/2010/05/why-you-shouldnt-expose-your-entities-through-your-services/">earlier</a>. That doesn't mean that you should go the entity-mimicking-DTO-route though. In fact, entity-mimicking-DTO's introduce a few of the same downsides you'd get from exposing entities directly through  your services. For an 'internal' service (i.e. only used by <em>your</em> application), I think it makes a lot more sense to use DTO's per service operation which are optimized for the use case that that service operation is meant to implement.</p><p>Essentially, an internal service's operations will be either <em>queries</em> or <em>commands</em>. When it comes to queries, why not just do the simplest thing possible? In most cases, it's sufficient to just return the data in the exact same form that the data will be displayed in. Quite often, that means a denormalized set of data where the data comes from more than one type of entity/table. There's no reason to send a bunch of entity-mimicking DTO's that reference each other to the client if you're going to use the data to populate a grid. Just send a list of DTO's which are already in the most optimal form. Populating those DTO's can then simply be done through straight SQL, a view, a stored procedure, a <a
href="http://davybrion.com/blog/2010/09/think-twice-before-you-map-entities-to-dtos/">projection through your ORM</a>, a map/reduce operation, or whatever else that makes sense. The point is that in most cases, you should just <em>populate</em> those DTO's as directly as you can instead of <em>mapping</em> to those DTO's. In this case, the DTO's offer a clear-cut benefit and don't really introduce tedious ceremony code in your codebase.</p><p>As for the commands (inserts, updates, anything that <em>creates</em> something or results in something <em>happening</em>), why even use DTO's in the first place? People will often argue that the ability to reuse the entity-mimicking-DTO's for these operations is a benefit. Personally, I don't really see the benefit. The mere presence of entity-mimicking-DTO's only encourages people to use them for the queries as well. Instead, I prefer to go with types that encapsulate all of the data relevant to the current command (the data to be inserted/updated, or whatever else the command needs). In a very simple scenario, this could be an InsertCustomerCommand type which simply has properties for the data that needs to be inserted. Nobody will be confusing these types with any other purpose than what their name communicates.</p><p>If you're building a web app where the server-side code does everything in process (i.e. without a WCF service), then you can in many cases just use the entities directly without a real drawback, though I'd recommend keeping an eye on unexpected select N+1 problems, since those will frequently come up when you're preparing your views. But even in this case, using DTO's that are optimized for the scenarios in which they're being used can really simplify the query-side of your system a lot.</p><p>There's nothing inherently wrong with DTO's if you use them to simply transfer <em>data</em>. If you're using them to transfer entities, you're robbing yourself of their biggest benefit while only making things more complex than they need to be.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=wDCy16gD6Uc:Dm-fM00yqSc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=wDCy16gD6Uc:Dm-fM00yqSc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=wDCy16gD6Uc:Dm-fM00yqSc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=wDCy16gD6Uc:Dm-fM00yqSc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=wDCy16gD6Uc:Dm-fM00yqSc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=wDCy16gD6Uc:Dm-fM00yqSc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=wDCy16gD6Uc:Dm-fM00yqSc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=wDCy16gD6Uc:Dm-fM00yqSc:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/wDCy16gD6Uc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/02/dtos-should-transfer-data-not-entities/feed/</wfw:commentRss> <slash:comments>10</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/02/dtos-should-transfer-data-not-entities/</feedburner:origLink></item> <item><title>NHibernate Training Course In Mechelen, Belgium – April 23/25</title><link>http://feedproxy.google.com/~r/davybrion/~3/HKKd471Hr00/</link> <comments>http://davybrion.com/blog/2012/02/nhibernate-training-course-in-mechelen-belgium-april-2325/#comments</comments> <pubDate>Sun, 12 Feb 2012 16:07:46 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3902</guid> <description><![CDATA[I'm organizing a public NHibernate Training Course from April 23rd through April 25th in Mechelen, Belgium. This time, I'm taking care of the whole thing myself instead of working together with a more established training company (except for renting a suitable training location). This enables me to offer the course at a lower price than [...]]]></description> <content:encoded><![CDATA[<p>I'm organizing a public NHibernate Training Course from April 23rd through April 25th in Mechelen, Belgium. This time, I'm taking care of the whole thing myself instead of working together with a more established training company (except for renting a suitable training location). This enables me to offer the course at a lower price than the previous public course. All details can be found <a
href="http://thatextramile.be/training/nhibernate">here</a>. Feel free to spread the word! <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=HKKd471Hr00:M3XrImatP4I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKKd471Hr00:M3XrImatP4I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKKd471Hr00:M3XrImatP4I:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKKd471Hr00:M3XrImatP4I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKKd471Hr00:M3XrImatP4I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKKd471Hr00:M3XrImatP4I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=HKKd471Hr00:M3XrImatP4I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=HKKd471Hr00:M3XrImatP4I:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/HKKd471Hr00" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/02/nhibernate-training-course-in-mechelen-belgium-april-2325/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/02/nhibernate-training-course-in-mechelen-belgium-april-2325/</feedburner:origLink></item> <item><title>(Ab)Using Conventions To Enforce Good Practices</title><link>http://feedproxy.google.com/~r/davybrion/~3/flTvNIlkmus/</link> <comments>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/#comments</comments> <pubDate>Thu, 26 Jan 2012 19:15:29 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3886</guid> <description><![CDATA[I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for [...]]]></description> <content:encoded><![CDATA[<p>I always tell people to explicitly specify the lengths of their string properties in their NHibernate mappings for performance reasons. If you don't specify them, the ADO.NET parameter lengths of those strings will always be set to the length of the actual string value that's been assigned to the parameter. This is a problem for SQL Server, because it can't cache those statements as efficiently as it would if the parameter lengths were always the same for a given statement. Simply put, if you don't specify the lengths, SQL Server's statement cache gets polluted with a bunch of statements that are often the same, but they're considered to be different simply because of the lengths of those string parameters. And this can really hurt the performance of your application.</p><p>Of course, not everyone remembers to set those lengths, so I thought it'd be great if I could force people to do this. With a little creative use of Fluent NHibernate's conventions, it's quite easy to enforce this:</p><div><pre class="brush: csharp; title: ; notranslate">
public class StringsMustHaveLengthConvention: IPropertyConvention, IPropertyConventionAcceptance
{
    public void Apply(IPropertyInstance instance)
    {
        var msg = string.Format(&quot;The string property '{0}' of type '{1}' does not have a length value specified, &quot; +
            &quot;which is required for performance reasons. Add something like this to your mapping override:\r\n&quot; + 
            &quot;\tmapping.Map(e =&gt; e.{0}).Length(50); // with an appropriate length for this property&quot;,
            instance.Property.Name, instance.EntityType.Name);

        throw new MappingException(msg);
    }

    public void Accept(IAcceptanceCriteria&lt;IPropertyInspector&gt; criteria)
    {
        criteria.Expect(x =&gt; x.Type == typeof(string)).Expect(x =&gt; x.Length == 0);
    }
}
</pre></div><p>With that convention in place, you won't even be able to run your code until you've specified the string lengths <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=flTvNIlkmus:vbJ3YxaBVC4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=flTvNIlkmus:vbJ3YxaBVC4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/flTvNIlkmus" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/feed/</wfw:commentRss> <slash:comments>15</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/abusing-conventions-to-enforce-good-practices/</feedburner:origLink></item> <item><title>Stop Storing Passwords Already!</title><link>http://feedproxy.google.com/~r/davybrion/~3/bskd34YcIcg/</link> <comments>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/#comments</comments> <pubDate>Mon, 23 Jan 2012 20:53:51 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[security]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3882</guid> <description><![CDATA[This is largely common sense already, but I still frequently run into people who don't know how dangerous this is or how to properly store user credentials. The many Anonymous hacks in the past year that resulted in the leaking of users' passwords also show that many sites still store passwords in either clear-text or [...]]]></description> <content:encoded><![CDATA[<p>This is largely common sense already, but I still frequently run into people who don't know how dangerous this is or how to properly store user credentials. The many Anonymous hacks in the past year that resulted in the leaking of users' passwords also show that many sites still store passwords in either clear-text or encrypted form. It's actually quite simple to store credentials safely, so here's a quick recap and example.</p><p>The biggest issue with storing passwords is that you have to assume that it's always possible that someone can get access to your database. Yes, even if it's not directly exposed to the outside world, which it <strong>never</strong> should be. Whatever security measures you've put in place to protect your database, it's a good idea to assume that sooner or later, someone will be able to punch a hole through your security measures and be able to read the data. So obviously, you really don't want to store clear-text passwords. You also don't want to store encrypted passwords because encrypted data can always be decrypted. And if people get access to those encrypted passwords even if they weren't supposed to, it'd be wise to assume that they also know how to decrypt them, or that it won't take them long to figure it out.</p><p>A much better approach is to store a hashed representation of the password instead, using a strong one-way cryptographic algorithm and a <strong>unique</strong> salt value per password. If the cryptographic algorithm is one-way, it means you can't apply another algorithm to get the original source value again. The only way to compare passwords is to apply the cryptographic algorithm on a given password using the originally used salt value, and then compare the resulting hash with the one you've stored. If they are identical, the given password is the same as the one that was used originally. If they differ, the password is invalid.</p><p>Attackers can still employ <a
href="http://en.wikipedia.org/wiki/Rainbow_table">rainbow tables</a> to try to find password values that generate the same hashes as the ones in your database. Luckily, generating rainbow tables takes time and plenty of space as well so it makes it much harder for attackers to find the passwords. This is why it's so important to use a unique salt value per password. It effectively means that a rainbow table would have to be generated for every single salt value that you've used, making it practically infeasible to find the original password values.</p><p>Let's demonstrate this with a simple example. The example is from a Node.js application, but this technique can be applied with whatever technology stack you're using.</p><p>This is my User model:</p><div><pre class="brush: jscript; title: ; notranslate">
var mongoose = require('mongoose'),
    crypto = require('crypto'),
    uuid = require('node-uuid'),
    Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var userSchema = new Schema({
    name: { type: String, required: true, unique: true },
    email: { type: String, required: true },
    salt: { type: String, required: true, default: uuid.v1 },
    passwdHash: { type: String, required: true }
});

var hash = function(passwd, salt) {
    return crypto.createHmac('sha256', salt).update(passwd).digest('hex');
};

userSchema.methods.setPassword = function(passwordString) {
    this.passwdHash = hash(passwordString, this.salt);
};

userSchema.methods.isValidPassword = function(passwordString) {
    return this.passwdHash === hash(passwordString, this.salt);
};

mongoose.model('User', userSchema);
module.exports = mongoose.model('User');
</pre></div><p>Notice that the salt property of my User type has its default value set to 'uuid.v1'. In this case, uuid.v1 is a function which will be invoked by Mongoose whenever a new User instance is created. Every User instance will thus have a UUID value stored in its salt property. You can also see that I'm not storing the given passwordString in the setPassword function, but that I calculate the hash value based on the passwordString and the UUID salt value.</p><p>Suppose I create a user with the following code:</p><div><pre class="brush: jscript; title: ; notranslate">
var user = new User({
    name: 'test_user',
    email: 'blah'
});
user.setPassword('test');

user.save(function(err, result) {
    if (err) throw err;
}); 
</pre></div><p>Its database representation will look like this:</p><div><pre class="brush: jscript; title: ; notranslate">
{ 
    &quot;passwdHash&quot; : &quot;b604367796274cf64177eec345532fc6ca66c6f0501906f82bb03f7916265e9d&quot;, 
    &quot;name&quot; : &quot;test_user&quot;, 
    &quot;email&quot; : &quot;blah&quot;, 
    &quot;_id&quot; : ObjectId(&quot;4f1dbb2cfa6157b118000001&quot;), 
    &quot;salt&quot; : &quot;304a33f0-45fc-11e1-80d2-43c594a44fa0&quot; 
}
</pre></div><p>If an attacker would get access to this, he'd have to generate a rainbow table using the salt value, which takes time, and even then he has no guarantee that the rainbow table will actually contain the correct password. Again, this is why it's so important to use a unique salt for every password. Also, you can use whatever value you want as the salt value so if you can determine it based on some other fields or by using a specific formula you don't need to store the actual salt value. It's recommended to use a long salt value though. Theoretically speaking, it's safer if the salt value isn't stored so clearly as I'm doing here, but even with the salt value clearly visible to a possible attacker, it would still be practically infeasible for him to generate all those rainbow tables.</p><p>And of course, my actual authentication function is still very simple as well:</p><div><pre class="brush: jscript; title: ; notranslate">
var authenticate = function(username, password, callback) {
    User.findOne({ name: username }, function(err, user) {
        if (err) return callback(new Error('User not found'));
        if (user.isValidPassword(password)) return callback(null, user);
        return callback(new Error('Invalid password'));
    });
};
</pre></div><p>So as you can see, there's nothing hard or complicated about storing credentials in a secure manner. It's quite easy to do so and there are no downsides to doing this.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=bskd34YcIcg:SBOcMlCO2Xo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=bskd34YcIcg:SBOcMlCO2Xo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/bskd34YcIcg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/stop-storing-passwords-already/</feedburner:origLink></item> <item><title>How Do You Pick Open Source Libraries?</title><link>http://feedproxy.google.com/~r/davybrion/~3/4BpBYXj8pYY/</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="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=4BpBYXj8pYY:lkkPo1JSHCM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=4BpBYXj8pYY:lkkPo1JSHCM:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/4BpBYXj8pYY" height="1" width="1"/>]]></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> <feedburner:origLink>http://davybrion.com/blog/2012/01/how-do-you-pick-open-source-libraries/</feedburner:origLink></item> <item><title>Hosting A Node.js Site Through Apache</title><link>http://feedproxy.google.com/~r/davybrion/~3/r3DqhWiU0Qc/</link> <comments>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/#comments</comments> <pubDate>Sun, 15 Jan 2012 14:23:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[node.js]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3869</guid> <description><![CDATA[I recently lost some time trying to figure out how to host a Node.js site through Apache, so I figured I might as well write a post about how I got it working. Of course, this approach only makes sense if you already have a server that's running Apache and you want to add your [...]]]></description> <content:encoded><![CDATA[<p>I recently lost some time trying to figure out how to host a Node.js site through Apache, so I figured I might as well write a post about how I got it working. Of course, this approach only makes sense if you already have a server that's running Apache and you want to add your Node.js site with minimal impact/changes on your server. If you're not using Apache already but just want to publish a Node.js site, you're better off using Node.js to host it directly, or to put Nginx in front of it since it's more lightweight than Apache. But anyways, here's how you get it working with Apache.</p><p>First of all, you need a way to start your Node.js process automatically when your system boots, and to shut it down when the system is shut down. This will depend on the type of server you're running on. In my case, it's a Debian server so I just went with the <a
href="https://github.com/nicokaiser/node-monit/tree/master/init.d" target="_blank">sysv init script from Nico Kaiser</a>. Another popular alternative is the upstart utility, which is already preinstalled if you're using Ubuntu. Once you have a start|stop|restart script in place, you'll want something to monitor the Node.js process to restart it in case it goes down. An easy to use tool for this is <a
href="http://mmonit.com/monit/" target="_blank">monit</a>. Nico Kaiser again has a good example script available for Node.js on <a
href="https://github.com/nicokaiser/node-monit/tree/master/monit/conf.d" target="_blank">Github</a>.</p><p>Once you have your sysv init or upstart script in place, as well as monit, your Node.js process can stay running on your server. Of course, you probably have it set to listen to connections on some other port than port 80 because that's what your Apache server is listening on. So now, the only thing you have to do is configure Apache to proxy all requests coming in on port 80 through the URL of your Node.js site to your local Node.js process. You'll first need to install <a
href="http://httpd.apache.org/docs/2.1/mod/mod_proxy.html" target="_blank">mod_proxy</a> and <a
href="http://httpd.apache.org/docs/2.0/mod/mod_proxy_http.html" target="_blank">mod_proxy_http</a>. After that, the configuration to make it work is quite easy:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;VirtualHost 109.74.199.47:80&gt;
    ServerAdmin davy.brion@thatextramile.be
    ServerName thatextramile.be
    ServerAlias www.thatextramile.be

    ProxyRequests off

    &lt;Proxy *&gt;
        Order deny,allow
        Allow from all
    &lt;/Proxy&gt;

    &lt;Location /&gt;
        ProxyPass http://localhost:3000/
        ProxyPassReverse http://localhost:3000/
    &lt;/Location&gt;
&lt;/VirtualHost&gt;
</pre></div><p>And that's it. Every request coming in at http://thatextramile.be or http://www.thatextramile.be will be forwarded to http://localhost:3000 where Node.js is listening. Note that the ProxyPassReverse is required to make sure that all HTTP response headers will contain the proxied URL instead of the real one (localhost).</p><p>If you need the raw throughput that Node.js offers, this solution is far from optimal. Every request that comes in through Apache will cause an Apache thread to wait/block until the response is returned from your Node.js process. This is essentially the same as when hosting PHP or Ruby through Apache, so it's not a problem, but it does take away one of the benefits of using Node.js. Again, this approach only makes sense if you're already using Apache to host other sites and you just want to add a Node.js site with minimal impact to your server.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r3DqhWiU0Qc:NjNpppKhXMI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r3DqhWiU0Qc:NjNpppKhXMI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/r3DqhWiU0Qc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/hosting-a-node-js-site-through-apache/</feedburner:origLink></item> <item><title>Company Website Finally Online</title><link>http://feedproxy.google.com/~r/davybrion/~3/r-HQC-l9-nk/</link> <comments>http://davybrion.com/blog/2012/01/company-website-finally-online/#comments</comments> <pubDate>Sun, 15 Jan 2012 09:39:19 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Off Topic]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3852</guid> <description><![CDATA[I finally got around to putting my new company website online. I originally planned to do this sometime last year, but it just kept getting postponed for a variety of reasons. I'm pretty bad at graphic/web design so I had the design done by Ken Bekaert since I thought he had already done a great [...]]]></description> <content:encoded><![CDATA[<p>I finally got around to putting my new <a
href="http://thatextramile.be" target="_blank">company website</a> online. I originally planned to do this sometime last year, but it just kept getting postponed for a variety of reasons. I'm pretty bad at graphic/web design so I had the design done by <a
href="http://frozenyogurt.be/" target="_blank">Ken Bekaert</a> since I thought he had already done a great job on my <a
href="http://twitpic.com/5zgm99" target="_blank">logo and business cards</a>. Next up was the slicing of the design to HTML and CSS. I could theoretically do that myself, but it would've taken me way too long and I would not have enjoyed it one bit, so I preferred to have it done by some old <a
href="http://nivario.be/" target="_blank">friends who know what they're doing</a>. After that, it was finally my turn to play around with it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>So of course, I couldn't resist doing the site with Express/Node.js. And I'm pretty happy with the result too: about <a
href="https://github.com/davybrion/companysite/tree/master/lib" target="_blank">130 lines of server-side code</a> that allows me to write the content of the site in Markdown (including caching and automatically updating the cache if the Markdown files are updated) and my <a
href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/" target="_blank">preferred solution to displaying feed items</a>. Does a simple site like this call for Express/Node.js? Of course not. But I knew it would be simple and fun, so that's why I used it.</p><p>The hardest part was actually writing the content of the site. Apparently, writing content for a company website is a lot harder than churning out a few blog posts occasionally, and I definitely underestimated that. Not because there's a lot of content (there's very little actually), but because you want to <em>avoid</em> ending up with a lot of content. It has to be concise and yet still contain everything you want it to say. After many revisions, it says everything I want it to say, and unlike on this blog I actually managed to keep it short <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>An extra benefit of doing it with Express/Node.js is that it reminded me how much fun I have working with that stack, so I'm going to get back to work on my <a
href="https://github.com/davybrion/therabbithole" target="_blank">breakable toy</a> which I've been neglecting for too long. I suppose this will lead to a few future posts as well <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=r-HQC-l9-nk:LXDSSiTB9kI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=r-HQC-l9-nk:LXDSSiTB9kI:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/r-HQC-l9-nk" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2012/01/company-website-finally-online/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2012/01/company-website-finally-online/</feedburner:origLink></item> <item><title>Looking Back On 2011</title><link>http://feedproxy.google.com/~r/davybrion/~3/kthPy9_wMg0/</link> <comments>http://davybrion.com/blog/2011/12/looking-back-on-2011/#comments</comments> <pubDate>Mon, 26 Dec 2011 19:43:09 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Off Topic]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3848</guid> <description><![CDATA[This was my first year working as an independent, and it's been quite a year. Things have gone very well, and I'm amazed at how quickly it all went by. This time last year, I was looking forward to start working for my first client though I didn't quite know what to expect. I hoped [...]]]></description> <content:encoded><![CDATA[<p>This was my first year working as an independent, and it's been quite a year. Things have gone very well, and I'm amazed at how quickly it all went by. This time last year, I was looking forward to start working for my first client though I didn't quite know what to expect. I hoped it would be interesting, and it certainly has been. I've been able to work with interesting technologies, with the kind of technical variety that I've come to really enjoy. I wrote more code in JavaScript than in C# this year, and I've also been able to do quite a bit of Ruby as well. I certainly didn't expect that going into this contract, so that was a major bonus. Even better than the technologies I've been able to work with this year are the people I've worked with. The team I've worked with has a fantastic mix of experience, knowledge and talent and it feels like all of us continuously learn new things from each other which is a situation I can only recommend to every developer.</p><p>Another great part about being independent is that you're free to do extra things on the side as well. I'm very happy with the responses that I've gotten from the people who've taken my <a
href="http://thatextramile.be/training/nhibernate">NHibernate course</a>, and I'm going to continue to offer it in 2012. I initially thought it would be something I'd do once or twice, but I was able to do the course 4 times this year: 1 public and 3 private ones. I've got another private one scheduled in February and will organize another public course in 2012, though this time I'm taking care of the whole thing myself instead of working with another company to organize it.</p><p>The most important thing I've learned from this first year is that it's important not to try to do too much. The first 6 months of 2011 were way too busy and hectic, and I only spent one full day doing absolutely nothing work-related. I've been taking things much slower since July and I'm spending much more time enjoying other things in life outside of work. For 2012, my biggest priority is pacing myself much better and spreading things out more. I always seem to alternate between months where I'm always working on something, followed by months of doing as little as possible outside of the 40 hours a week I do for my client. Hopefully, I can finally find a maintainable balance between those two extremes in 2012 <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>On the blogging front, 2011 was a different year than the previous ones on this blog. In the previous years, I averaged about 150 posts a year but this year I only published 71 posts. And I'm actually happy about that. In fact, I hope to get that number down to 50 next year. I still like writing posts, but I no longer feel the need to like I did in the past while I was trying to build a bit of an audience. That often meant pushing myself to keep publishing new posts. Nowadays, I'll only write a post if I really feel like it, which in the long run is much more sustainable anyway. As far as topics covered this year, things have changed quite a bit as well. Some of my views, opinions and technical preferences have changed this year, which naturally reflects in the content I've published. I'm sure I've lost some readers this year because of it, but I also seem to have gained a lot more readers than I've lost. I don't know yet what I'll be writing about in 2012, but I will continue to push people to learn new things (or old things that people seem to forget about) and do better like I always have on this blog, in my own unique way of course <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>I hope you all enjoyed Christmas, and I wish you all a happy 2012. If it does turn out to be our last year on this planet, we might as well make it count.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=kthPy9_wMg0:graD7mYys-A:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=kthPy9_wMg0:graD7mYys-A:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/kthPy9_wMg0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/looking-back-on-2011/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/looking-back-on-2011/</feedburner:origLink></item> <item><title>Displaying Feed Items On A Web Page: My Solution</title><link>http://feedproxy.google.com/~r/davybrion/~3/YOg6tZlA7JI/</link> <comments>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/#comments</comments> <pubDate>Tue, 20 Dec 2011 07:00:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[express.js]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[node.js]]></category> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3830</guid> <description><![CDATA[A couple of days ago I asked you how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this: It needs to be fast The fewer requests that are impacted by retrieving the feed data, the better If I [...]]]></description> <content:encoded><![CDATA[<p>A couple of days ago I <a
href="http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/">asked you</a> how you'd implement showing links from an RSS feed on a web page (in this case: my new company web site). These are my requirements for this:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>I came up with a very simple solution, which satisfies these requirements better than any other solution I could think of, or heard of from other people. It is extremely fast, doesn't delay any requests, and doesn't require me to deploy anything but the company website. I'm building the site with <a
href="http://expressjs.com/">Express</a> on <a
href="http://nodejs.org/">Node.js</a>, which means I can take full advantage of the asynchronous nature of Node.js to implement this.</p><p>Let's go over the code... in the script that starts the express server, I have the following code:</p><div><pre class="brush: jscript; title: ; notranslate">
var express = require('express'),
    app = module.exports = express.createServer(),
    NodePie = require('nodepie'),
    request = require('request'),
    recentFeedItems = null;

app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});

// ... some extra configuration of Express that isn't relevant to this post

var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};

setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>I'll discuss the code in just a moment, but first I want to show the view code that renders the links:</p><div><pre class="brush: xml; title: ; notranslate">
&lt;ul&gt;
&lt;% getRecentFeedItems.forEach(function(item) { %&gt;
    &lt;li&gt;&lt;time class=&quot;date&quot;&gt;&lt;%= item.getDate().getDate() + '/' + (item.getDate().getMonth() + 1) %&gt;&lt;/time&gt;&lt;a href=&quot;&lt;%= item.getPermalink() %&gt;&quot;&gt;&lt;%= item.getTitle() %&gt;&lt;/a&gt;&lt;/li&gt;
&lt;% }); %&gt;
&lt;/ul&gt;
</pre></div><p>And that's all. This is the solution in its entirety!</p><p>If you're new to Node, this code probably requires some explanation. Let's start with this part:</p><div><pre class="brush: jscript; title: ; notranslate">
app.dynamicHelpers({
    getRecentFeedItems: function() {
        return recentFeedItems;
    }
});
</pre></div><p>Here I'm adding a dynamic helper to the Express application. It basically means that my views have access to the getRecentFeedItems function, which returns the value of the recentFeedItems variable. It's important to know that the getRecentFeedItems function creates a closure on the recentFeedItems variable created above it. That means that if the value of the recentFeedItems variable changes at any point in time, the getRecentFeedItems function will return that new value.</p><div><pre class="brush: jscript; title: ; notranslate">
var processFeed = function(callback) {
    request('http://feeds.feedburner.com/davybrion', function(err, response, body) {
        if (!err &amp;&amp; response.statusCode == 200) {
            var feed = new NodePie(body);
            feed.init();
            recentFeedItems = feed.getItems(0, 5);
            if (callback) callback();
        };
    }); 
};
</pre></div><p>This just creates a function that we can use later on. It retrieves the feed asynchronously, and when the result is retrieved, we parse the feed using the NodePie library and we get the 5 most recent items which we store in the recentFeedItems variable. Again, this creates a closure on the recentFeedItems variable which means that every time we assign a value to this variable, any subsequent call to the getRecentFeedItems function will return the value we just assigned to it because both functions point to the same memory thanks to the magic of closures. Finally, if a callback is provided as a parameter, the callback will be invoked.</p><div><pre class="brush: jscript; title: ; notranslate">
setInterval(processFeed, 1800000); // process feed items every 30 minutes

processFeed(function() {
    app.listen(3000);
    console.log('Express started on port 3000');    
});
</pre></div><p>The call to setInterval makes sure that the processFeed function is called every 30 minutes. After that, we call the processFeed function manually, and we pass in a callback where we start the Express server. This guarantees that the feed items will be in memory before the server starts processing requests.</p><p>What makes this solution so great is that we take full advantage of some of Node's benefits. Whenever we retrieve the RSS feed, Node.JS will retrieve that data asynchronously. As soon as it has fired the request to get the RSS feed, it just goes to the next event in its eventloop so no request is kept waiting while we wait for the data to be downloaded. Until the data from the RSS feed is returned, each request will just use the items that are stored in the recentFeedItems variable. Once the data has been returned, our callback is executed which overwrites the value of the recentFeedItems variable. We don't need to do any locking here because the Node.JS eventloop is single-threaded: while our callback is running, no other code that has access to the recentFeedItems variable can be executed anyway. And the actual parsing of the RSS feed is done by NodePie, which uses <a
href="http://expat.sourceforge.net/">expat</a> behind the scenes, which is supposedly the fastest C XML parser available.</p><p>Looking back on my initial requirements, I think this solution matches very well.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=YOg6tZlA7JI:EHTJxGRSvX8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=YOg6tZlA7JI:EHTJxGRSvX8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/YOg6tZlA7JI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/feed/</wfw:commentRss> <slash:comments>7</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/</feedburner:origLink></item> <item><title>Node.js For Dummies</title><link>http://feedproxy.google.com/~r/davybrion/~3/AsPaZvBN6HA/</link> <comments>http://davybrion.com/blog/2011/12/node-js-for-dummies/#comments</comments> <pubDate>Sun, 18 Dec 2011 17:40:39 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[JavaScript]]></category> <category><![CDATA[node.js]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3838</guid> <description><![CDATA[I'm sure you've all heard of Node.js by now. Its popularity is increasing rapidly, which means it's a good idea to be aware of what Node.js is and especially how it differs from more traditional technology stacks. In this post, I'll try to give an easy-to-understand overview of what makes Node.js different and make it [...]]]></description> <content:encoded><![CDATA[<p>I'm sure you've all heard of Node.js by now. Its popularity is increasing rapidly, which means it's a good idea to be aware of what Node.js is and especially how it differs from more traditional technology stacks. In this post, I'll try to give an easy-to-understand overview of what makes Node.js different and make it clear that it's more than just server-side JavaScript. Note that this overview is highly simplified and only meant to help people understand how Node.js works. This is definitely not a completely accurate description of the lower-level details of Node.js.</p><h2>Evented/Asynchronous I/O</h2><p>In most technology stacks, API calls for I/O operations are synchronous. As in, the thread that executes the operation is blocked for the duration of the I/O operation until that operation has completed. Once completed, execution of your code proceeds. Of course, a lot of technology stacks have asynchronous variants of those operations available as well, but generally speaking, they aren't used as often as the synchronous variants. In Node.js, it's the other way around. All I/O operations are asynchronous and there are only a few synchronous implementations available (and you're generally discouraged from using them).</p><p>This means that whenever you do an I/O operation (file manipulation, network requests, database operations, etc…), Node.js initiates the I/O operation through a lower-level C/C++ layer which will perform the operation asynchronously. Once the operation has completed, Node.js will execute your callback function that you passed as a parameter to the I/O operation's function call. The important thing here is that while the I/O operation is being executed, Node.js doesn't have to wait for the operation to complete, and is able to focus entirely on processing other events. And those events can be anything: incoming network requests, executing callbacks from other operations that have completed, or invoking whatever function that is assigned to a particular event.</p><h2>Eventloop</h2><p>The Node.js eventloop is what makes Node.js so interesting and powerful. Node.js basically just keeps reading from an event queue until that queue is empty. As it loops through the events to be processed, it invokes the JavaScript functions that have been assigned for those events. If any of those functions performs an I/O operation, Node.js will initiate the operation and then immediately move to the next event in the event queue. Once the I/O operation has completed, an event will be added to the event queue with a reference to your original callback. Once all preceding events have been processed, Node.js will get to the newly added event and invoke your callback. Because all I/O operations are asynchronous, this enables Node.js to maximize its efficiency as it processes events because it doesn't need to wait for slow I/O operations to complete.</p><h2>Single-threaded</h2><p>One thing that people don't always realize is that the Node.js eventloop is single-threaded. This has some nice benefits but there's a huge drawback as well. The biggest benefit is that you don't need to worry about concurrent access to shared state. After all, there is never more than 1 thread executing your JavaScript functions. This means you don't have to write any locking code to protect shared state. The drawback to the single-threaded eventloop is that you need to be careful not to block the event loop. If you're planning on doing heavy synchronous processing in your JavaScript code, you need to realize that no other events can be processed by Node.js until that synchronous block of code has completed. Obviously, since there's only one thread going through the eventloop, any delay you cause in your code can be very costly to overall throughput and performance. For now, it's best to execute synchronous processing routines as a child process, possibly even in a language that is more suitable for this than JavaScript. But it seems that future Node.js versions will provide a more integrated way to deal with this.</p><h2>Why JavaScript?</h2><p>JavaScript's support of closures and it treating functions as first class objects means it's ideally suited for the evented programming model that Node.js offers. Many people still think of JavaScript as a joke or a toy language, but it's a lot more powerful than many people think it is. Yes, it certainly has problems as well, but it's definitely worth learning. I do hope that this post has made it clear that there's a lot more to Node.js than simply being server-side JavaScript. What makes Node.js so interesting are the principles that I've tried to explain in this post. Those principles can be implemented with other languages as well, and could be made to work just as great as, or perhaps even greater than Node.js itself. But you'd be hard-pressed to find a language that's so ubiquitous, yet completely devoid of a pre-existing synchronous I/O infrastructure.</p><p>Anyways, I hope I succeeded at making it somewhat clear how Node.js works and why it's so different from most other technology stacks.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=AsPaZvBN6HA:0t_GLmgkIK8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=AsPaZvBN6HA:0t_GLmgkIK8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/AsPaZvBN6HA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/node-js-for-dummies/feed/</wfw:commentRss> <slash:comments>15</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/node-js-for-dummies/</feedburner:origLink></item> <item><title>Challenge: Displaying Feed Items On A Web Page</title><link>http://feedproxy.google.com/~r/davybrion/~3/Awt1njA8rQU/</link> <comments>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/#comments</comments> <pubDate>Sat, 17 Dec 2011 15:17:41 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Performance]]></category><guid isPermaLink="false">http://davybrion.com/blog/?p=3822</guid> <description><![CDATA[I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts: Of course, I don't want to update those links [...]]]></description> <content:encoded><![CDATA[<p>I'm finally getting around to implementing the website for my company, and there's one small part of it that's quite interesting from an implementation point of view. The website will have a footer on each page which displays links to my 5 most recent blog posts:</p><p><a
href="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" rel="prettyPhoto[3822]"><img
src="http://davybrion.com/blog/wp-content/uploads/2011/12/feed_items.png" alt="" title="feed_items" width="683" height="402" class="aligncenter size-full wp-image-3823" /></a></p><p>Of course, I don't want to update those links manually whenever I publish a new post, so they need to be retrieved from my blog's RSS feed, which is published by Feedburner. I was hoping to be able to retrieve only the metadata from the posts (date, title and URL is all I need) because my feed always contains the last 20 posts and its total size is usually above 100KB. I haven't found a way to do that, so getting the information I need has to be retrieved through the full feed. Sure, 100KB isn't much but keep in mind that you need to retrieve it and parse it and that I absolutely want to minimize the time each request takes and that I'd rather not see any visual delays on the page either.</p><p>I'm interested in hearing how you would implement this. You have total freedom to pick the technologies you'd like to use and no limits on how you'd use them. My only requirements are these:</p><ul><li>It needs to be <strong>fast</strong></li><li>The fewer requests that are impacted by retrieving the feed data, the better</li><li>If I publish a post, the links on the company website should contain the new link within 30 minutes</li><li>The simpler the solution, the better</li></ul><p>My solution can be found <a
href="http://davybrion.com/blog/2011/12/displaying-feed-items-on-a-web-page-my-solution/">here</a>.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/davybrion?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/davybrion?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/davybrion?a=Awt1njA8rQU:7Gti5R8zH_4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/davybrion?i=Awt1njA8rQU:7Gti5R8zH_4:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/davybrion/~4/Awt1njA8rQU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://davybrion.com/blog/2011/12/challenge-displaying-feed-items-on-a-web-page/</feedburner:origLink></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 1/84 queries in 0.051 seconds using disk: basic
Object Caching 1308/1488 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-05-14 23:22:45 -->

