<?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>Buu Nguyen's Blog</title>
	
	<link>http://www.buunguyen.net/blog</link>
	<description>Thoughts on software development and project management</description>
	<lastBuildDate>Fri, 26 Jun 2009 07:07:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/BuuNguyensBlog" type="application/rss+xml" /><feedburner:emailServiceId>BuuNguyensBlog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>ASP.NET MVC Client-side Resource Combine</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/_z9lY7Sg5A0/aspnet-mvc-client-side-resource-combine.html</link>
		<comments>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html#comments</comments>
		<pubDate>Fri, 26 Jun 2009 07:05:29 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=355</guid>
		<description><![CDATA[ASP.NET MVC Client-side Resource Combine is another spin-off library from one of my current development projects.  (The other is ASP.NET MVC Validation Library.)  While the name is &#8220;resource combine&#8221;, this library actually does more than just combining client side resources including JavaScript and CSS.  It allows you to organize resources into groups [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aspmvccombine.codeplex.com/">ASP.NET MVC Client-side Resource Combine</a> is another spin-off library from one of my current development projects.  (The other is <a href="http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html">ASP.NET MVC Validation Library</a>.)  While the name is &#8220;resource combine&#8221;, this library actually does more than just combining client side resources including JavaScript and CSS.  It allows you to organize resources into groups which will be combined, minified, compressed, and cached (at both client and server sides) together.  While the library comes bundled with some routing and link utility to help developers easily integrate it into their ASP.NET MVC applications, there&#8217;s no reason why the library cannot be used with ASP.NET WebForms applications.  </p>
<p>Refer to the <a href="http://aspmvccombine.codeplex.com/">project CodePlex page</a> for detailed usage and binary/code download.  The library uses the great <a href="http://yuicompressor.codeplex.com/">YUI Compressor</a> library for the minification part.</p>
<p>Hopes it helps!</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=ASP.NET%20MVC%20Client-side%20Resource%20Combine&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Faspnet-mvc-client-side-resource-combine.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=_z9lY7Sg5A0:a1V_eMzEh_Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=_z9lY7Sg5A0:a1V_eMzEh_Y:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=_z9lY7Sg5A0:a1V_eMzEh_Y:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/aspnet-mvc-client-side-resource-combine.html</feedburner:origLink></item>
		<item>
		<title>Lost of posts &amp; comments from 1/9/2009 to June/2009</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/FtsuC5tfjQE/lost-of-posts-comments-from-192009-to-june2009.html</link>
		<comments>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html#comments</comments>
		<pubDate>Fri, 26 Jun 2009 06:57:26 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[experience]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=372</guid>
		<description><![CDATA[Upon writing a new blog post today, I recognized an shocking truth: the provider hosting my blog during their database migration had somehow cleaned up all of my blog&#8217;s posts and comments dated after 1/8/2009.  Since I trusted my provider in their infrastructure, I did not do the backup job well myself so I [...]]]></description>
			<content:encoded><![CDATA[<p>Upon writing a new blog post today, I recognized an shocking truth: the provider hosting my blog during their database migration had somehow cleaned up all of my blog&#8217;s posts and comments dated after 1/8/2009.  Since I trusted my provider in their infrastructure, I did not do the backup job well myself so I did not have anything to repopulate the database.  </p>
<p>Luckily, Google&#8217;s cache made it possible for me to retrieve the text and posted them again with an adjusted timestamp.  As for the comments, since there were many of them and yet not all of them could be found in Google&#8217;s cache, I had to leave them for now.  Therefore, you won&#8217;t see any comments dated from 1/9/2009 to around June 2009 (when the migration occurred).  My sincere apologies to those comments are lost due to this incidence.  I myself feel very very bad about it.  I will work with the host provider in a last attempt to find way to recover the comments.  If that doesn&#8217;t turn out right, I will find a new provider.  And I will surely backup my blog frequently in the future.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=Lost%20of%20posts%20%26%23038%3B%20comments%20from%201%2F9%2F2009%20to%20June%2F2009&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Flost-of-posts-comments-from-192009-to-june2009.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=FtsuC5tfjQE:FunCFn1AOOk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=FtsuC5tfjQE:FunCFn1AOOk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=FtsuC5tfjQE:FunCFn1AOOk:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/lost-of-posts-comments-from-192009-to-june2009.html</feedburner:origLink></item>
		<item>
		<title>Junior developers beware, SOLID principles and design patterns are indeed useful for you</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/mIy5wMQX6UY/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html</link>
		<comments>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html#comments</comments>
		<pubDate>Fri, 13 Feb 2009 06:40:47 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career advices]]></category>
		<category><![CDATA[Self Improvement]]></category>
		<category><![CDATA[Software Engineering]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=368</guid>
		<description><![CDATA[I have several times disagreed with Jeff.  They are just rare occasions though, given the amount of blog posts he wrote and I read (and agreed with).  However, given his popularity as a blogger, any misleading advice may be highly destructive to junior software developers who may turn to his blog for advices. [...]]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://www.buunguyen.net/blog/jeff-atwood-on-design-patterns.html">several</a> <a href="http://www.buunguyen.net/blog/the-impassionate-and-nnpps-are-not-that-destructive.html">times</a> disagreed with Jeff.  They are just rare occasions though, given the amount of blog posts he wrote and I read (and agreed with).  However, given his popularity as a blogger, any misleading advice may be highly destructive to junior software developers who may turn to his blog for advices.  This time around, <a href="http://www.codinghorror.com/blog/archives/001225.html">Jeff bashes guidelines, rules, and checklist</a> with <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">SOLID principles</a> being one of the targets.</p>
<p>Now, young developers, before you start throwing away all the books about design patterns, agile, OO principles etc., let me tell you one thing: if Jeff Atwood is a better developer at all today, it&#8217;s because he has learned from the rules preached by more knowledgeable people.  Don&#8217;t believe?  Read <a href="http://www.codinghorror.com/blog/archives/000021.html">this</a>.  There you go, Jeff Atwood as a fan of <a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_sim_b_3">Code Complete</a>, a 900-page book full of coding rules, was so much interested in the book that he even named his blog after one of the book&#8217;s symbol.  He just seems to forget about where he came from when he wrote:</p>
<blockquote><p>While I do believe every software development team should endeavor to follow the instructions on the paint can, there&#8217;s a limit to what you can fit on a paint can. It&#8217;s the most basic, most critical information you need to proceed and not make a giant mess of the process. As brief as the instructions on a paint can are, they do represent the upper limit of what most people will realistically read, comprehend, and derive immediate benefit from. </p>
</blockquote>
<p>It&#8217;s normal for a very experienced developer to rely mostly on his judgment instead of a set of rules and principles to do thing.  But it&#8217;s just uncool for such an experienced developer to advise the newbies to do the same thing, i.e. they&#8217;d better use their judgment first before resorting to the distilled and valuable knowledge taught by others.  </p>
<blockquote><p>&#8230;I&#8217;ve found less and less use for rules in my career. Not because I&#8217;m a self-made genius who plays by my own rules, mind you, but because I value the skills, experience, and judgment of my team far more than any static set of rules&#8230;  Rules, guidelines, and principles are gems of distilled experience that should be studied and respected. But they&#8217;re never a substute for thinking critically about your work.</p>
</blockquote>
<p>The thing is people are not born making good judgment.  And one of the best ways to sharpen one&#8217;s judgment is to learn from the knowledge of those people who have made good judgment.  Only after one has practiced these teachings long enough, making a lot of right and wrong decisions based on these teachings, one will for the first time, really understand about them and don&#8217;t have to think about them any longer as they have become part of one&#8217;s instinct.  That should be the thing experienced developers teach junior developers, not this:</p>
<blockquote><p>The types of developers who could benefit from SOLID a) aren&#8217;t thoughtful enough about their work to care and b) won&#8217;t read much of anything</p>
</blockquote>
<p>Don&#8217;t get me wrong, I respect many of Jeff&#8217;s opinions, but I think he should feel more responsible for his influence on those developers who are new to the industry and seek for advices from his writings.  Obviously no one man is perfect and Jeff, like any other, doesn&#8217;t necessarily always have great things to say.  But at least he should acknowledge that he&#8217;s wrong when he&#8217;s wrong.  </p>
<p><strong>Appendum 2/14</strong><br />
On the contrary to what I think Jeff Atwood should do in the previous paragraph given the large amount of thoughtful comments from many of his readers, he seems to dig himself deeper into the hole with his <a href="http://www.codinghorror.com/blog/archives/000856.html">follow-up post</a>.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=Junior%20developers%20beware%2C%20SOLID%20principles%20and%20design%20patterns%20are%20indeed%20useful%20for%20you&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fjunior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=mIy5wMQX6UY:-TSCJaejMh4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=mIy5wMQX6UY:-TSCJaejMh4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=mIy5wMQX6UY:-TSCJaejMh4:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/junior-developers-beware-solid-principles-and-design-patterns-are-indeed-useful-for-you.html</feedburner:origLink></item>
		<item>
		<title>ASP.NET MVC Validation Library</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/Hqpj3ccce2I/aspnet-mvc-validation-library.html</link>
		<comments>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html#comments</comments>
		<pubDate>Tue, 10 Feb 2009 06:32:18 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[codeplex]]></category>
		<category><![CDATA[enterprise library]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=364</guid>
		<description><![CDATA[Inspired by the work of Emad Ibrahim, I set out to develop a validation library for ASP.NET MVC.  Besides trying to meet the same objectives as Emad Ibrahim&#8217;s library, i.e. model-based validation, integration with the jQuery validation plugin, and little or no duplication between client-side and server-side validation, these are the differences of my [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://www.emadibrahim.com/2008/09/08/client-server-side-validation-in-aspnet-mvc/">the work</a> of Emad Ibrahim, I set out to develop a validation library for ASP.NET MVC.  Besides trying to meet the same objectives as Emad Ibrahim&#8217;s library, i.e. model-based validation, integration with the <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery validation plugin</a>, and little or no duplication between client-side and server-side validation, these are the differences of my library:</p>
<ul>
<li>Built for <a href="Validation Application Block?PHPSESSID=3c28d1ec5adc35404e534c68747bf06b&PHPSESSID=a2414d3c3764afd441f61c34995183c0">MS Validation Application Block</a>.  (Emad Ibrahim&#8217;s library targets <a href="http://www.castleproject.org/">Castle</a>&#8217;s validation framework.  Check out <a href="http://www.emadibrahim.com/2008/09/08/client-server-side-validation-in-aspnet-mvc">his library</a> if you need this feature.)</li>
<li>Allow users to specify the properties to be included in a server-side validation.  This is useful in situation in which you use part of the model in some pages (e.g. Change Password page only uses the <code>Password</code> field of the <code>User </code>entity).</li>
<li>Allow users to tell the client-side code generator to generate script to ignore missing DOM elements.  This feature goes nicely with the above feature.  The generator could have been implemented to receive a list of properties to generate client script for but I have not made up my mind yet whether this is a better approach or not.</li>
<li>Allow users to specify whether they want the validation initialization code to be generated or not.  This is particular useful if you want to customize the validation initialization code differently for different pages.</li>
</ul>
<p><strong>How does it work?</strong><br />
The idea of the library is that one should be able to decorate an entity object with some validation attributes and then have that entity validated at both the server-side and client-side with the minimum amount of code.  Let&#8217;s say you have a <code>User</code> entity in your application, you can annotate it as follows:</p>
<pre name="code" class="csharp">
public class User
{
     [NotNullOrEmptyValidator(MessageTemplate = "Name is required")]
     [StringLengthValidator(6, 20, MessageTemplate = "Name must be between {3} and {5}")]
     public string Name { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Email is required")]
     [EmailValidator(MessageTemplate = "Invalid email address")]
     public string Email { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Location is required")]
     public string Location { get; set; }

     [NotNullOrEmptyValidator(MessageTemplate = "Password is required")]
     [StringLengthValidator(6, 50, MessageTemplate = "Password must be between {3} and {5}")]
     public string Password { get; set; }
}
</pre>
<p>Now, whenever this entity is populated with form posted values, you can perform server-side validation by invoking the <code>Validate()</code> extension method on the entity.  Let&#8217;s do that in the action method.</p>
<pre name="code" class="csharp">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditUser([Bind(Prefix=&quot;&quot;)]User user)
{
     try
     {
          user.Validate&lt;User&gt;();
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}
</pre>
<p>The above code will perform validation on the entity given its validation attributes.  If there&#8217;s any validation error, an <code>EntityValidationException </code>object is thrown and you can use it the populate the model state with error messages.  The method <code>PopulateWithErrors </code>is another extension method provided by the library.</p>
<p>If you want to limit the properties to be validated (e.g. in a password change scenario), you can pass an array of property names into the <code>Validate()</code> method.</p>
<pre name="code" class="csharp">
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChangePassword([Bind(Prefix=&quot;&quot;)]User user)
{
     try
     {
          // Only validate the password property
          user.Validate&lt;User&gt;(new[] {&quot;password&quot;});
     }
     catch (EntityValidationException ex)
     {
          ViewData.ModelState.PopulateWithErrors(ex);
     }
     return View();
}
</pre>
<p>I could have added a custom model binder to the library so that validation happens at the model binding phase but I think that&#8217;s not a flexible approach since in many cases we would want to perform validation in the service layer instead so that the validation takes place consistently for any client of the service.</p>
<p>Let&#8217;s see the result of the server-side validation:<br />
<img src="http://www.buunguyen.net/blog/wp-content/uploads/2009/02/server-side-validation.png" alt="" title="Server-side validation result" width="322" height="375" class="size-full wp-image-391" /></p>
<p>Okay, let&#8217;s move to client-side validation.  The trick behind the client-side validation is that the view will invokes the <code>HtmlHelper</code>&#8217;s <code>ClientSideValidation()</code> extension method which will retrieve all validation attributes of the specified entity type (e.g. <code>User</code>) and generate equivalent client-side validation script for them.  </p>
<p>Currently, while you can apply as many validation attributes to an entity as you like and the server-side validation will work perfectly fine, only a couple of validation rules are supported by the client-side code generator, namely required field validation, string length validation, and email validation.  These3 rules are sufficient for my current need and I will add more on a needed basis (or you can download the code and implement more rules yourself.) </p>
<p>There are a couple of overloads of the <code>ClientSideValidation() </code>method:</p>
<pre name="code" class="csharp">
// Generates validation script for the User type
Html.ClientSideValidation&lt;User&gt;();

// Generates validation script for the User type, including the code to initialize form validation
Html.ClientSideValidation&lt;User&gt;(string formName);

// Generates validation script for the User type and adds necessary code to avoid JavaScript error if one or
// more properties in the User type do not match with any DOM element.
Html.ClientSideValidation&lt;User&gt;(bool ignoreMissingElements);

// See the above 2 overloads
Html.ClientSideValidation&lt;User&gt;(string formName, bool ignoreMissingElements);
</pre>
<p>For example, the generated code for an invocation of the second overload will result in the following code:</p>
<pre name="code" class="javascript">
&lt;script language=&quot;JavaScript&quot;&gt;&lt;!--
$().ready(function() {

$(&quot;#edit-user-form&quot;).validate();
$(&quot;#name&quot;).rules(&quot;add&quot;, {
	minlength : &quot;6&quot;, maxlength : &quot;20&quot;,
	required : true,
	messages: {
		minlength : &quot;Name must be between 6 and 20&quot;, maxlength : &quot;Name must be between 6 and 20&quot;,
		required : &quot;Name is required&quot;

	}
});

$(&quot;#email&quot;).rules(&quot;add&quot;, {
	required : true,
	email : true,
	messages: {
		required : &quot;Email is required&quot;,
		email : &quot;Invalid email address&quot;
	}
});

$(&quot;#location&quot;).rules(&quot;add&quot;, {
	required : true,
	messages: {
		required : &quot;Location is required&quot;

	}
});

$(&quot;#password&quot;).rules(&quot;add&quot;, {
	minlength : &quot;6&quot;, maxlength : &quot;50&quot;,
	required : true,
	messages: {
		minlength : &quot;Password must be between 6 and 50&quot;, maxlength : &quot;Password must be between 6 and 50&quot;,
		required : &quot;Password is required&quot;
	}
});

});
--&gt;&lt;/script&gt;
</pre>
<p>That&#8217;s it, you don&#8217;t need to write a single line of JavaScript to have this nice client-side validation:<br />
<img alt="" src="http://www.buunguyen.net/blog/wp-content/uploads/2009/02/client-side-validation.png" title="Client-side validation result" class="size-full wp-image-391" width="452" height="274" /></p>
<p><strong>How can I download and use it?</strong><br />
The library is hosted at <a href="http://www.codeplex.com/aspmvcvalidation">CodePlex</a>.  I have built it with ASP.NET MVC Beta, Enterprise Library 4.1, jQuery 1.2, and jQuery validation plug-in 1.5.  You might need to make a couple of changes if you want it to work with a different version of those libraries.  Any bug, please post on the project page instead of posting here.  Thanks &#038; hope you&#8217;ll find the library useful.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=ASP.NET%20MVC%20Validation%20Library&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Faspnet-mvc-validation-library.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Hqpj3ccce2I:-0QahSOft8I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Hqpj3ccce2I:-0QahSOft8I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Hqpj3ccce2I:-0QahSOft8I:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/aspnet-mvc-validation-library.html</feedburner:origLink></item>
		<item>
		<title>Common developers CV’s mistakes</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/Va1hu42pOXI/common-developers-cvs-mistakes.html</link>
		<comments>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html#comments</comments>
		<pubDate>Wed, 21 Jan 2009 06:28:49 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[hr]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[recruitment]]></category>
		<category><![CDATA[Self Improvement]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=357</guid>
		<description><![CDATA[Being responsible for hiring developers in almost every position I landed, I&#8217;ve screened probably a few hundreds of developers CVs through out my career.  Following is the list of mistakes I often found in CVs.

First and most common mistakes: the CV lists too many skills. In fact, I&#8217;ve seen many CVs with roughly a [...]]]></description>
			<content:encoded><![CDATA[<p>Being responsible for hiring developers in almost every position I landed, I&#8217;ve screened probably a few hundreds of developers CVs through out my career.  Following is the list of mistakes I often found in CVs.</p>
<ul>
<li><strong>First and most common mistakes: the CV lists too many skills.</strong> In fact, I&#8217;ve seen many CVs with roughly a dozen lines mentioning about many dozens of technologies and tools. In many cases as the on-site interviews revealed, these developers just possessed superficial or absolutely no knowledge about the things they listed.  One can only go so far (to the on-site interview) being untruthful.  On the other hand, even if these developers really know about these things, among the too many things they list, I can hardly find the ones that should really stand out (i.e. the things that the candidates have expertise in.)  Now, there are those of you who really have extensive set of skills under your belt and want to list them all, it&#8217;s still better if you can highlight the top skills that you master so that they can stand out from the rest. Most of the time, employers don&#8217;t care about the skills you are not really good at. Think about it, would I hire a top .NET developer to write Java code just because the guy happens to know a bit about Java?  </li>
<p></p>
<li><strong>Some candidates describe what they were supposed to do instead of what they actually did in their previous positions.</strong> If one implemented the security module of a software using Spring Security or used Struts 2.0 to implement a web module of another software then I would want to know about that. On the other hand, I don&#8217;t want to read a some general job description stating the obvious and of little interest (to me) such as &#8220;designed and implemented the application&#8221;, &#8220;worked with QA to resolve defects&#8221;, and &#8220;participated in code review&#8221; etc.  (Guess what, if you&#8217;re not doing these things, you are not developers.) On the other hand, some candidates went so far quoting text from the job description while they have not actually carried out such responsibilities and that has resulted in quite a couple of embarrassing on-site interviews. Be very specific about the things that you did is the key to avoid this mistake.</li>
<p></p>
<li><strong>Mention too much about the clients and products. </strong>As a matter of fact, I&#8217;ve seen some CVs in which every project is accompanied with a lengthy paragraph describing the product and its client. Much of this information is pulled out of the marketing information provided in the client&#8217;s or product&#8217;s website. Keep this in mind: most employers don&#8217;t care about the vision of your client organization and the greatness of the product. For the software that you built, only 2 things should be mentioned in the CV: what problem the software solves and what technologies it is built with.  Anything other than that is noise and should go away. For the client, the name and a link to their website are more than enough. For the really rare case that I want to learn more about the client, I will find more information through the provided link (or Google, for heaven&#8217;s sake).</li>
<p></p>
<li><strong>Some CVs mention too trivial projects.</strong> Don&#8217;t get me wrong, it&#8217;s good to demonstrate how much passionate you are about this software engineering by listing things like, say, personal projects but there&#8217;s no point mentioning some trivial toy or university projects in your CVs. Think about it, how much value the employer gains knowing that a developer can code a Tic Tac Toe game or a shopping cart? Absolutely nothing unless you expect us to say to ourselves &#8220;Look, that guy is really cool &#8211; he can code Tic Tac Toe.&#8221;  Save the space for more valuable things instead. If there&#8217;s no such thing, better save us some reading time by removing them from the CV.</li>
<p></p>
<li><strong>Spelling and grammar mistakes in CVs. </strong> I am constantly surprised that many developers don&#8217;t even care to do a quick check to make sure no grammatical and spelling mistakes in their CVs.  After all, it only takes a few minutes for this check to be done with any word processing software.  Without doing this, one risks leaving a bad impression to the recruiter; the impression that the author of this CV is either lazy, doesn&#8217;t care about getting the job, about doing the right things, or about going the last mile to get the work done.  That might be a harsh conclusion one can come up with given just a few spelling mistakes, but given the sheer amount of CVs recruiters have to screen for any particular position, they are not supposed to be very patient and tolerant of poorly written ones. </li>
<p></p>
<li><strong>A bonus tip: don&#8217;t be afraid to list your certifications if you have any. </strong> This is actually not a common mistake, but since there is a rising number of people who suggest that developers should not include certifications in their CVs, I think it&#8217;s worth setting an alarm.  Anyone who have under their belt a few certifications know that it&#8217;s not the papers themselves that have a lot of value but the actual studying process that one usually gets through to get those papers is valuable. Plus, if one spends the time that would otherwise be spent on vacation or gaming to study and achieve some certifications relevant to her work, it means that she cares, if is not passionate, about her job. And that is never a bad thing. Finally, with all things being equal, some companies would prefer to hire developers with one or more certifications than others because that would help with the partnership process with vendors like, say, Microsoft (like it or not, there are obvious benefits to become partner of the big vendors).</li>
</ul>
<p>That&#8217;s it, the top CV mistakes. Am I missing anything?</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=Common%20developers%20CV%E2%80%99s%20mistakes&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fcommon-developers-cvs-mistakes.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Va1hu42pOXI:PZrbMt3euu4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=Va1hu42pOXI:PZrbMt3euu4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=Va1hu42pOXI:PZrbMt3euu4:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/common-developers-cvs-mistakes.html</feedburner:origLink></item>
		<item>
		<title>The impassionate and NNPPs are not that destructive</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/ZJCC8uNqttc/the-impassionate-and-nnpps-are-not-that-destructive.html</link>
		<comments>http://www.buunguyen.net/blog/the-impassionate-and-nnpps-are-not-that-destructive.html#comments</comments>
		<pubDate>Thu, 08 Jan 2009 04:16:58 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[nnpp]]></category>
		<category><![CDATA[project management]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=345</guid>
		<description><![CDATA[I&#8217;ve just read two interesting blog posts this week, Jeff Atwood&#8217;s Programming Love It or Leave It and Jay Fields&#8217; The Cost of Net Negative Producing Programmers.  Jeff Atwood basically thinks that people who don&#8217;t have passion for programming should not go into the field while Jay Fields thinks that poor programmers add significant [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just read two interesting blog posts this week, Jeff Atwood&#8217;s <a href="http:/www.codinghorror.com/blog/archives/001202.html">Programming Love It or Leave It</a> and Jay Fields&#8217; <a href="http://blog.jayfields.com/2009/01/cost-of-net-negative-producing.html">The Cost of Net Negative Producing Programmers</a>.  Jeff Atwood basically thinks that people who don&#8217;t have passion for programming should not go into the field while Jay Fields thinks that poor programmers add significant cost to any project and should not be in the industry as well.  If I were to read these a year ago, I would have wholeheartedly agreed with them.  After all, I too had to maintain the very poor code written by incompetent programmers and couldn&#8217;t help but wishing they were never programmers in the first place.  And I had strong opinion in <a href="http://www.buunguyen.net/blog/on-interviewing-beyond-technical-competence.html">passion being one of the top criteria for hiring programmers</a> and felt bad about those who are not passionate enough to <a href="http://www.buunguyen.net/blog/the-wrong-attitude-of-learning-on-the-job.html">spend extra time learning stuff beyond the work at hand</a>.  But a year working exclusively in a managerial role has changed my view on that quite a lot.  Don&#8217;t get me wrong, I still think passion and talent are important attributes of developers, it&#8217;s just that they are much less important than what I used to believe.</p>
<p>Indeed, when you are in a position to receive projects from clients and responsible for hiring people to accomplish those projects, you&#8217;ll quickly realize one thing: there are just not enough talented or passionate developers, much less those who are both passionate and talented.  Truth be told, I was extremely selective in my hiring to the extent that I was infamously known among the HR department as a &#8220;candidate eliminator&#8221;.  And yet, I think less than 5% of those I selected into onsite interview met both criteria.  That said, if I had rigidly maintained my rules of placing passion and talent before any other, I would never have found enough people for all the projects.  In such situation, there are 2 things one can do: give up and reject the client projects for not being able to find enough members to staff in, or staff the best you can and find ways of accomplishing the projects.  Now, nobody in his or her right mind would go with the first option.  </p>
<p>After spending more than a year working with impassionate and not talented people, I have come to realize that a team which has such developers can still deliver good result.  Now, among those people, I have yet to find a person who is passionate but has poor programming skills, but the remaining categories (impassionate but talented and impassionate and not talented) turned out to add value to the team in one way or another.  Specifically, I realized that impassionate developer can still be good developers.  These developers would rather go home early and spend time taking care of their family or pursuing their real passions.  They never write any blog or participate in any open source projects nor do they have any plan to do so.  And they only learn things as they are needed instead of browsing through latest books and blogs to learn about the trendy things.  But when they do something, they do it with utmost attention and most importantly, they write good code.  That should not be a surprise.  You just need to realize that good developers are, well, good developers regardless of whether they spent 8 or 16 hours per day programming.  (Although the one spending more time may learn more.)  As a matter of fact, two developers in one of the projects I worked on were not passionate about software development at all.  They just realize that programming is something they are good at, so they do it to get the money to spend on the things they really love.  One guy&#8217;s passion is photography, but he is smart enough to know that he can&#8217;t make as much money being a photographer.  He loves it, but he simply has no talent for it.  </p>
<p>I&#8217;ve been talking about good developers who are not passionate.  How about those who are both impassionate and have bad programming skills?  I worked with them too, and I have to say: such people are <a href="http://en.wikipedia.org/wiki/NNPP">NNPPs</a> mostly because they are mismanaged.  A good manager will recognize the strengths and weaknesses of their members to put them into the right position.  Before you laugh at the idea, think about all the work that need to be done for the projects to be successful.  Are you sure that all of such work require really smart developers to do?  Do you need good developers to maintain the project&#8217;s build scripts?  Or setup a build system?  Or evaluate a tool?  How about writing project documentations?  Or migrate one source control system to another?  Simple bugs of well understood components (or even more complex bugs but have the new code reviewed by good developers, but that&#8217;s another story)?  The point is, in just about any software development project, there are always some work which smart and passionate people hesitate to do (and may not do it well if they have to do it) but enthusiastically accepted by others.  Let the latter do such work, they are neither passionate nor smart but they work for the pay in order to do things they really love.  Therefore, they are willing to do so and even feel happy for not being asked to do more than what they are capable of doing.  And you, the passionate and smart developer, can be happy too.  The right-person-for-the-right-job is the name of the game.  </p>
<p>Having said all these, sometimes some people just don&#8217;t fit to your project, then you have to let them go.  But the point remains the same, things would be much easier if we can find all the top guns and put them into the team.  But we simply can&#8217;t.  Sometimes, we have to live with what we get and do the best about it.  Just face it.  And happy programming.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=The%20impassionate%20and%20NNPPs%20are%20not%20that%20destructive&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fthe-impassionate-and-nnpps-are-not-that-destructive.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=ZJCC8uNqttc:kQSivsio1bc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=ZJCC8uNqttc:kQSivsio1bc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=ZJCC8uNqttc:kQSivsio1bc:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=ZJCC8uNqttc:kQSivsio1bc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=ZJCC8uNqttc:kQSivsio1bc:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/the-impassionate-and-nnpps-are-not-that-destructive.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/the-impassionate-and-nnpps-are-not-that-destructive.html</feedburner:origLink></item>
		<item>
		<title>GUI Mockups Made Easy</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/e127r7rHRtg/gui-mockups-made-easy.html</link>
		<comments>http://www.buunguyen.net/blog/gui-mockups-made-easy.html#comments</comments>
		<pubDate>Mon, 08 Dec 2008 03:01:23 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[mockups]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=330</guid>
		<description><![CDATA[I have been using Visio a lot to design GUI mockups.  Visio is a pretty powerful and flexible software except for a few drawbacks and most notably the mockups produced by Visio have the Windows XP looks-and-feel.  This is fine if these are mockups for a Windows desktop application but pretty awkward for [...]]]></description>
			<content:encoded><![CDATA[<p>I have been using Visio a lot to design GUI mockups.  Visio is a pretty powerful and flexible software except for a few drawbacks and most notably the mockups produced by Visio have the Windows XP looks-and-feel.  This is fine if these are mockups for a Windows desktop application but pretty awkward for other types of applications.  Lately, I came across a nice alternative called <a href="http://www.balsamiq.com">Balsamiq Mockups</a>.  Mockups produced by this tool are platform-neutral and thus can be used to sketch GUIs for virtually any kind of applications.  Besides, the control-set provided out of the box include many controls that Visio doesn&#8217;t have like tag cloud, map, browser window etc.  There are a couple of nice features like JIRA and Confluence integration, but the thing I find most notable about Balsamiq is its agility: one can be a lot more productive building most of their GUI mockups with Balsamiq than with Visio.</p>
<p>For example, if I want to sketch a grid populated with some existing data all I need to do is dragging the grid component out of the toolbar and fill in some CSV-formatted text.  (Anyone experiencing drawing data-grids with Visio will know the process is not that straight-forward.)  Or if I want to create a tag cloud, I just simply enter some words and Balsamiq will weight the words randomly and display them in a nice tag cloud picture.  For more complex components like tree or menu, a wiki-like syntax is available to fill in the data and decorate the output (e.g. menu item separator, checked menu item etc.)  This simple process of entering some plain text repeats for all kind of GUI components which need input data.    </p>
<p>Although I am happy with what Balsamiq has to offer, I wish the software has features to allow users to draw arbitrary shapes and add custom images into the mockups.  For now, users are limited to whatever GUI components and icon images provided out of the box.  Regardless, I think these requirements not necessary for a majority of GUI mockups and for most of the rest I think I can resort to my modest photo-editing skills <img src='http://www.buunguyen.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Below is a sample mockup created with Balsamiq.  See more <a href="http://www.balsamiq.com/products/mockups/examples">here</a>.</p>
<p><img width="600" height="600" src="http://www.balsamiq.com/images/mytube.gif" alt="mockup" /></p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=GUI%20Mockups%20Made%20Easy&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fgui-mockups-made-easy.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=e127r7rHRtg:mpOsxb1DrDA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=e127r7rHRtg:mpOsxb1DrDA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=e127r7rHRtg:mpOsxb1DrDA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=e127r7rHRtg:mpOsxb1DrDA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=e127r7rHRtg:mpOsxb1DrDA:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/gui-mockups-made-easy.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/gui-mockups-made-easy.html</feedburner:origLink></item>
		<item>
		<title>Overview of C# 4.0</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/fAjjkLe07xI/new-features-of-csharp-4.html</link>
		<comments>http://www.buunguyen.net/blog/new-features-of-csharp-4.html#comments</comments>
		<pubDate>Thu, 13 Nov 2008 07:02:28 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Technologies]]></category>
		<category><![CDATA[.net 4.0]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[c# 3.0]]></category>
		<category><![CDATA[c# 4.0]]></category>
		<category><![CDATA[dynamic language runtime]]></category>
		<category><![CDATA[dynamic languages]]></category>
		<category><![CDATA[generics]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=274</guid>
		<description><![CDATA[Note: This article is also posted at The Code Project. Refer to this link.  There are quite interesting discussions going on there.
The .NET framework 4.0 CTP has just been released and I think it&#8217;s a good time to explore the new features of C# 4.0.  In this post, I will introduce about the [...]]]></description>
			<content:encoded><![CDATA[<p><em>Note: This article is also posted at The Code Project. Refer to this <a href="http://www.codeproject.com/KB/cs/csharp_4_overview.aspx">link</a>.  There are quite interesting discussions going on there.</em></p>
<p>The .NET framework 4.0 CTP has just been released and I think it&#8217;s a good time to explore the new features of C# 4.0.  In this post, I will introduce about the following features: dynamic lookup, generics covariance and contravariance support, optional and named parameters.<br />
<span id="more-274"></span><br />
<strong>1. Dynamic Lookup</strong><br />
If <code>var</code> in C# 3.0 brings about type inference for local variables with the purpose of saving a couple of key strokes, dynamic lookup adds much more to the dynamicity of the C# language.  When you declare a variable with <code>dynamic</code>, all of its method invocations or member accesses will be resolved at runtime.  For example, let’s look at the following code</p>
<pre name="code" class="csharp">
public static void Main() {
    dynamic obj = “I’m statically System.String”;
    obj.NotExistingMethod(“param”);
}
</pre>
<p>In the code, we create a string object and instead of assigning it to a variable of type <code>string</code>, we assign it to a variable declared as <code>dynamic</code>.  This basically instructs the compiler to not to attempt to resolve any method call or member access of the declared variable.  Instead, all these resolutions will happen at runtime.  That being done, the next line in which we invoke a non-existing method with an arbitrary parameter will compile just fine into CIL.  At runtime, when the method call is resolved and the runtime finds that there’s no such method in the runtime type (which is a <code>System.String</code>), an exception is thrown.   That being said, if we use a valid method then there would be no exception and the code will run fine till completion.  For example:</p>
<pre name="code" class="csharp">
    dynamic obj = “I’m statically System.String”;
    Console.WriteLine(obj.ToLower());
</pre>
<p>Not only that we can declare a variable as dynamic, we can also declare methods&#8217; arguments to be so.  For example:</p>
<pre name="code" class="csharp">
    private static void PrintID(dynamic obj) {
        Console.WriteLine(obj.ID);
    }

    public static void Main() {
        var person = new {ID = 111, Name = "Buu"};
        PrintID(person);

        var account = new {ID = 101, Bank = "Some Bank"};
        PrintID(account);
    }
</pre>
<p>We basically create two anonymous types, for the sake of convenience, both having a property called <code>ID</code> and then instantiate objects out of these types.  We then pass each of these two objects to the method <code>PrintID</code> which accepts a dynamic object and print out the ID property.  The code will print out “111” and “101” respectively.  And yes, we’ve just seen duck typing in action.  In C#.</p>
<p>That example also shows an interesting usage of <code>dynamic</code> in regarding to anonymous types.  Now, we can pass objects of anonymous types out of their declaration scope (e.g. the method) and still be able to invoke their methods or access to their members without resorting to verbose reflection code.  (And in fact, whenever you see any piece of reflection code in your application and regardless of the code&#8217;s purpose, there might be an opportunity to replace it with dynamic lookup to make the code more readable.)</p>
<p>We are not just limited to make statically typed .NET objects become dynamic, we can use this dynamic lookup feature to conveniently interact with “actual” dynamic objects available through the Dynamic Language Runtime (DLR) included in .NET framework 4.0.  In fact, one can implement such dynamic objects in C# by implementing the <code>System.Scripting.Actions.IDynamicObject</code> interface, which is also part of the DLR.  Regardless of the actual receiver of dynamic dispatch, the usage of dynamic lookup is exactly the same from the caller&#8217;s perspective.  </p>
<p>Some of you might wonder what code the compiler generates and whether there is any change to the CLR to support dynamic lookup or not.  To answer that question, let’s look at the CIL generated from the very first code fragment of this post.  (Click on the image to see the full size.)</p>
<p><a href="http://www.buunguyen.net/blog/wp-content/uploads/2008/11/dynamic.jpg"><img src="http://www.buunguyen.net/blog/wp-content/uploads/2008/11/dynamic.jpg" alt="" title="CIL of dynamic keyword" width="620" height="260"/></a></p>
<p>The generated CIL is pretty verbose but a skim through it reveals two important things.  Firstly, our “dynamic variable” turns out to be a plain old CLR <code>System.Object</code> instance.  And secondly, there’s no new CIL directive or opcode to support dynamic lookup.  Instead, dynamic resolution and invocation is completely handled by framework code.  In fact, the above CIL is equivalent to the following C# code, but now without the <code>dynamic</code> keyword.</p>
<pre name="code" class="csharp">
    object obj = &quot;I'm statically System.String&quot;;
    var payload = new CSharpCallPayload(
        RuntimeBinder.GetInstance(),
        false, false, &quot;NotExistingMethod&quot;,
        typeof(object), null);
    var callSite = CallSite&lt;Action&lt;CallSite, object, string&gt;&gt;.Create(payLoad);
    Action&lt;CallSite, object, string&gt; action = callSite.Target;
    action.Invoke(callSite, obj, &quot;param&quot;);
</pre>
<p>(In fact, I simplified the code a bit so that it can fit in one method, the actual CIL generated does have a check at <code>IL_000c</code> which basically looks at the <code>callSite</code> static field of a nested class, which is generated automatically by the compiler, to see if it&#8217;s null or not before going ahead and initializing it.  In order words, the <code>callSite</code> is cached for subsequent invocations of the same method.)</p>
<p>So there&#8217;s really no magic behind the dynamic keyword.  What the compiler basically does is generating some payload containing the information about the invocation so that it can be made at runtime.  If there&#8217;s any magic at all, it would be in the static method <code>CallSite.Create()</code> which uses reflection to invoke the <code>NotExistingMethod</code> on the given object if it’s not an instance of <code>IDynamicObject</code>.  </p>
<p>Now, we know that a “dynamic object” is actually a plain old object; it should explain why method can accept dynamic parameters.  It should also be of no surprise to know that dynamic lookup can also be applied to return value of an instance/static method or an instance/static field.  After all, unlike the var keyword which requires the compiler to infer the exact type at compile time, the compiler in dynamic lookup scenarios can simply pick <code>System.Object</code> as the type.<br />
<br/><br />
<strong>2. Generics Covariance and Contravariance</strong><br />
In previous versions of C#, generic types are invariant.  That is, for any two types <code>GenericType&lt;T&gt;</code> and <code>GenericType&lt;K&gt;</code>, in which <code>T</code> is a subclass of <code>K</code> or <code>K</code> is a subclass of <code>T</code>, <code>GenericType&lt;T&gt;</code> and <code>GenericType&lt;K&gt;</code> have no inheritance relationship whatsoever to each other.  On the other hand, if <code>T</code> is a subclass of <code>K</code> and if C# supports covariance, <code>GenericType&lt;T&gt;</code> is also a subclass of <code>GenericType&lt;K&gt;</code> or if C#  supports contravariance, <code>GenericType&lt;T&gt;</code> is a superclass of <code>GenericType&lt;K&gt;</code>.</p>
<p>To understand why pre-4.0 C# disallows covariance and contravariance, let’s look at some code</p>
<pre name="code" class="csharp">
    var strList = new List&lt;string&gt;();
    List&lt;object&gt; objList = strList; // compile-error, with cast or not
</pre>
<p>If the code in line 2, it can be error-prone.  Consider what we can write after line 2 assuming it is allowed:</p>
<pre name="code" class="csharp">
    // BOOM: we're adding an arbitrary AnyObject to what, at runtime, is a list of strings
    objList.add(new AnyObject());
</pre>
<p>On the other hand, if C# supported contravariance, we could have written the following problematic code:</p>
<pre name="code" class="csharp">
    var objList = new List&lt;object&gt;;
    objList.add(3);
    objList.add(new AnyObject());
    List&lt;string&gt; strList = objList; 

    // BOOM: we're getting an arbitrary object thinking it’s a string
    string element = strList.get(0);
</pre>
<p>Due to this invariant restriction, although for the good purpose, we can&#8217;t easily reuse variables and methods to respectively get assigned to or accepts various generic types.  It’s somewhat unfortunately because the key thing to realize that covariance is fine as long as <code>GenericType&lt;T&gt;</code> does not have any method or member accepting arguments of type <code>T</code> (e.g. if we can&#8217;t add a bunch of objects into the <code>objList</code>, which is indeed an instance of <code>List&lt;string&gt;</code>, we&#8217;ll be safe).  Besides, contravariance is just as safe if <code>T</code> does not appear in any return value from a member or method (e.g., if we can&#8217;t get out any string from <code>strList</code>, which is indeed an instance of <code>List&lt;object&gt;</code>, we&#8217;ll be safe).  </p>
<p>Fortunately, C# 4.0 provides us an option: if a <strong>generics interface</strong> or <strong>generics delegate</strong> which has a <strong>reference type</strong> <code>T</code> as its type parameter and does not have any method or member that take in a parameter of type <code>T</code>, we can declare it to be covariant on T.  On the other hand, if that interface or delegate does not have any method or member that returning T, we can declare it be contravariant on T.  (Notice the emphases, only interfaces and delegates have covariance and contravariance support and the type parameter must be a reference type.  On the other hand, C# arrays have been supporting covariance from the very beginning.)  </p>
<p>Let’s look at an example.  We have a <code>Generator</code> delegate which basically returns random instances of object of certain type (e.g. <code>string</code>).  Its declaration is as follows:</p>
<pre name="code" class="csharp">
    delegate T Generator&lt;out T&gt;();
</pre>
<p>Because this delegate does not take in any <code>T</code> as its argument, we can safely make it covariant on <code>T</code>.  And indeed, that compiler will allow us to do so by adding the modifier <code>out</code> before the type parameter.  However, if this delegate is declared as, say <code>delegate T Generator&lt;out T&gt;(T seed)</code> then the compiler will complain since it&#8217;s no longer safe for covariance.   Now, let’s look at the usage:</p>
<pre name="code" class="csharp">
    Generator&lt;string&gt; strGen = new Generator&lt;string&gt;(StringGenerator);

    // Below line is compiled now because Generator&lt;string&gt; is
    // subclass of Generator&lt;object&gt; under covariant rule
    Generator&lt;object&gt; objGen = strGen; 

    // Downcast is also allowed for the same reason
    strGen = (Generator&lt;String&gt;)objGen; 

    ...

    private string StringGenerator()
    {
        return &quot;I'm a random string&quot;;
    }
</pre>
<p>With contravariance, you need to use the <code>in</code> keyword.  Let&#8217;s look at an example making use of both contravariance and covariance:</p>
<pre name="code" class="csharp">
    delegate K Converter&lt;in T, out K&gt;(T param);
</pre>
<p>This converter takes an object of type <code>T</code> and converts it to an object of type <code>K</code> (e.g. convert <code>String</code> to <code>Object</code>).  Since it does not take in any <code>K</code>, it can safely be declared to be covariant on <code>K</code>.  Similarly, since it exposes no <code>T</code>, it can safely declare to be contravariant on <code>T</code>.  Its usage is as follows:</p>
<pre name="code" class="csharp">
    var converter = new Converter&lt;object, string&gt;( ConvertImpl);
    Converter&lt;string, object&gt; string2ObjectConverter = converter;
    object result = string2ObjectConverter(&quot;A&quot;); 

    ...

    private string ConvertImpl(object o) {
        return o.ToString();
    }
</pre>
<p>Note that although the above examples show how to declare covariance and contravariance for delegate types, it&#8217;s not different to do so with interfaces.  </p>
<p>Before we finish with covariance and contravariance, let’s look at what code the compiler generates.  After all, we know that the compiler must encode something to the CIL to denote covariant and/or contravariant generics types so that they can be consumed properly by client code.  And this is what the definitions of our Generator and Converter delegates viewed from ildasm.</p>
<p><img src="http://www.buunguyen.net/blog/wp-content/uploads/2008/11/generics.jpg" alt="" title="Generics covariance and contravariance"/></p>
<p>Do you notice anything?  Those little minus and addition signs are used to denote contravariance and covariance respectively.  And interesting enough, it turns out that the CLR has been supporting such CIL since the introduction of generics in .NET 2.0.  Therefore, it’s possible to write CIL using covariance and contravariance under .NET 2.0+.  Only by now that it’s possible to do so using C#.</p>
<p>A final thought about this feature, while this is a good enhancement to the language, I like the generics covariance/contravariance implementation, enabled via wildcards, in Java better for its flexibility.  Anyway, let’s just be happy with it for now, we can’t have everything.<br />
<br/><br />
<strong>3. Optional and Named Parameters</strong><br />
The last two features of C# 4.0 that we&#8217;ll discuss about are optional parameters and named parameters.  These features have been with VB.NET since forever and I’m glad they are finally implemented in C#.</p>
<p>With optional parameters, we can provide default values for methods’ and constructors’ parameters.  That way,  we don’t have to write a bunch of overloaded methods and constructors.  For example, we can define a constructor like this:</p>
<pre name="code" class="csharp">
    public Cart(int id, String name = “default cart”, double amount = 0d) {…}
</pre>
<p>Now, you can invoke this constructor with any of these calls:</p>
<pre name="code" class="csharp">
   new Cart(1);
   new Cart(1, “my cart”);
   new Cart(1, “my cart”, 105.5);
</pre>
<p>How exactly does C# implement this feature?  If we look at the CIL generated for this code, we’ll see there’s no magic at all.  Basically the default values will be injected to the call site so that the method invocation happens normally.  Here’s the CIL generated by the compiler: </p>
<p><img src="http://www.buunguyen.net/blog/wp-content/uploads/2008/11/named_param_use.jpg" alt="" title="Optional parameter usage" /></p>
<p>Some might think that the compiler gets the default values in the source code to inject into the caller’s code.  However, that will not work if a method with optional parameters is published as a library.  In that case, there’s no way the compiler can get the default values to inject to the code of the library’s client.  Therefore, what the compiler actually does is to encode the default parameters right into the method itself.  This is what the CIL for <code>Cart</code>’s constructor:</p>
<p><img src="http://www.buunguyen.net/blog/wp-content/uploads/2008/11/named_param_declaration.jpg" alt="" title="Optional parameter definition"/></p>
<p>Notice the <code>.param</code> directive which basically tells the compiler about the default values for the optional parameters.  These parameters are also annotated by the <code>[opt]</code> attribute.</p>
<p>While being a great feature, there’s a caveat when using optional parameters: since the compiler inlines the default values at the caller site, change to default values at the library site won’t be reflected unless the caller is recompiled.  In order words, you should consider default values of parameters as part of the published API of a method and you’d better make them right the first time.</p>
<p>Now, let’s say we want to call the <code>Cart</code>’s constructor with the <code>ID</code> and <code>amount</code> specified but not the <code>name</code>, how would we do that?</p>
<p>To avoid ambiguity (for example when two optional parameters are both strings), C# won’t allow us to simply skip a parameter like this:</p>
<pre name="code" class="csharp">
    new Cart(1, 15.5d); // compile-error
</pre>
<p>An approach C# could take is to allow this syntax:</p>
<pre name="code" class="csharp">
    new Cart(1, , 15.5d);
</pre>
<p>However, this looks terrible enough with just one missing parameter, much less more of them. (How do you like to read this code <code>MethodWithManyFields(,,,15,,”param”,,)</code>?)</p>
<p>For this particular situation, named parameters are excellent solution:</p>
<pre name="code" class="csharp">
   new Cart(1, amount: 15.5d);
</pre>
<p>This is not the only use of named parameters though.  A very important purpose of named parameters is to enhance the readability of code.  Let’s say you have a class having a bunch of fields that are to be initialized in a constructor.  Without name parameters, a constructor of such class will look very ugly and hard to understand without resorting to the documentation, source code, or Intellisense.  </p>
<p>One approach is to create a builder to create instance of such class.  For example:</p>
<pre name="code" class="csharp">
   new BigClass.Builder().attr1(“value”).attr2(“value”)...attrN(“value”);
</pre>
<p>This will make the code more explicit about what values are to be assigned to what fields.  However, the drawback is that we need to implement a builder class, which is quite a tedious task if we have to repeat that for many classes in our application.</p>
<p>With C# 3.0, it’s not that bad because we can use object initializer to do something like this:</p>
<pre name="code" class="csharp">
    new BigClass {Attr1 = “value”, Attr2 = “value”, …, AttrN = “value”}
</pre>
<p>This looks good, but we have to define all the necessary properties for it to work, which is also a tedious thing to do if we don’t really need properties for the class or if the class itself is immutable.</p>
<p>With named parameters, we have a very nice solution without having to write any builder or property if we don’t want to.  (Note the semicolon after the field name.)</p>
<pre name="code" class="csharp">
    new BigClass{attr1: “value”, attr2: “value”, …, attrN: “value”);

    // The below does the same thing
    new BigClass{attrN: “value”, attr1: “value”, …, attr2: “value”);
</pre>
<p>Regarding the implementation of this at the CIL level, the compiler is smart enough to infer the correct argument order and simply perform a plain old method invocation.  </p>
<p>That’s it.  The key features of C# 4.0.  I am personally glad that C# has come to support these.  Some people said that C# has become so complex and started losing its original beauty.  While I can understand that view, I think the situation is not that bad.  While it&#8217;s obvious that C# has more and more constructs to supports functional and dynamic programming, the statically typed nature and the old constructs of the language are still there and no developer is forced to use the new features if they don&#8217;t need to.  On the other hand, these features bring more options for those who need them and I&#8217;d rather have more options than to be handcuffed.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=Overview%20of%20C%23%204.0&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fnew-features-of-csharp-4.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=fAjjkLe07xI:Yxq9iLQssnQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=fAjjkLe07xI:Yxq9iLQssnQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=fAjjkLe07xI:Yxq9iLQssnQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=fAjjkLe07xI:Yxq9iLQssnQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=fAjjkLe07xI:Yxq9iLQssnQ:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/new-features-of-csharp-4.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/new-features-of-csharp-4.html</feedburner:origLink></item>
		<item>
		<title>The 5 Types of Poor Architects</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/UnDRaoFFvTU/the-5-types-of-poor-architects.html</link>
		<comments>http://www.buunguyen.net/blog/the-5-types-of-poor-architects.html#comments</comments>
		<pubDate>Fri, 20 Jun 2008 10:55:32 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Development Processes]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[OOAD]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Technologies]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[muses]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/?p=208</guid>
		<description><![CDATA[I have worked with so many architects in my career, including those who have the &#8220;Architect&#8221; word in their business card and those who play architect role in their projects.  And while I had good fortune to meet very talented people, I am frequently disappointed by poor architects who put their ego, arrogance, fanaticism [...]]]></description>
			<content:encoded><![CDATA[<p>I have worked with so many architects in my career, including those who have the &#8220;Architect&#8221; word in their business card and those who play architect role in their projects.  And while I had good fortune to meet very talented people, I am frequently disappointed by poor architects who put their ego, arrogance, fanaticism (and sometimes, ignorance) before anything else.  Recalling the memories I have about the poor architects, I come up with the following grouping. <span id="more-208"></span></p>
<ul>
<li>
<strong>The nothing-but-nails architects. </strong> These architects have hammer and thus they see everything as nails.  That said, these people are very eagle to apply overkill technologies to solve even the simplest problems.  If the software has web front-end, then a MVC web framework must be used.  If it has to integrate with some back-end system, then an Enterprise Service Bus implementation must be deployed.  Business logic?  We need Enterprise Java Bean, baby.  If there are 100 concurrent users, then the system should be hosted in a farm environment with 2 web servers, 2 application servers and 1 database server.  And architecture design won&#8217;t stop until these architects have put all 23 GoF patterns and one dozen of enterprise architectural patterns which they just learn from a book into their Visio diagrams.
</li>
<p></p>
<li>
<strong>The no-news-is-good-news architects.</strong>  These architects are afraid of new things, those they often insist to be &#8220;unproven&#8221; and &#8220;risky&#8221;.  Some of these architects are of same group as the nothing-but-nail guys, i.e. they are so proud of their bag of tricks that they feel no other technologies are relevant and all problems are the same.  The others are way behind the technological trends that they feel threatened by new technologies and tools.  The arguments these architects often use to turn down new ideas include &#8220;it will never work&#8221;, &#8220;this is not practical&#8221;, &#8220;we already has proven methods, why bother such risky solution?&#8221;, or even the discussion-stopping message &#8220;I have solved this problem before, I know what works and what do not.&#8221;  I remember an occasion in which I observed a senior architect criticized heavily the design of another architect who &#8220;dared&#8221; to suggest the use of Amazon&#8217;s SimpleDB as the storage engine for their new web application.  Arguments used by the former include &#8220;database over HTTP is simply unacceptable&#8221;, &#8220;we don&#8217;t need those thousands of servers in Amazon&#8217;s farm&#8221;, and &#8220;you are bringing extra risk for us by introducing another node of security&#8221;.  The poor latter architect, he did not know he was suggesting something which was radically new to the mind of the former.
</li>
<p></p>
<li>
<strong>The do-as-I-said architects.</strong>  Unlike the no-news-is-good-news group which bashes against new ideas, this group turns down whatever ideas not coming from them.  This type may not necessarily feel threatened by new things, they just feel like their ability is being challenged by ideas they did not think of from the first place.  If they think using Open ESB should be used, then any suggestion about BizTalk, or a home-grown integration solution that does just the job well will be turned down.  Even if they do think the latter two are better ideas.  Similarly, they will turn down any &#8220;RESTful&#8221; ideas because it&#8217;s WS-* that they propose in the first place even if they understand that the REST alternative may save them bunch of implementation efforts.  Just do as they said and all is good.
</li>
<p></p>
<li>
<strong>The silver-bullet-obsession architects. </strong> This group stands on opposite end from the no-news-is-good-news group: they are crazy about new things.  They are so interested in fads and buzzwords that they include these in any presentation they make and any design solution they propose.  To these architects, it&#8217;s just cool to talk about and use new things while completely dismissing the relevancy of such things to the problem at hand.  EJB?  So old-fashioned, let&#8217;s use RoR.  Ajax?  Forget about it, RIA is the future.  RIA by Flex?  Silverlight with managed code is the key.  ORM is the past, it should be LINQ-2-SQL all the way down, baby.  And they keep spending their career looking for more silver bullets.
	</li>
<p></p>
<li>
<strong>The UML-only architects.</strong>  If you have read my essay, <a href="http://www.buunguyen.net/blog/the-code-is-the-design.html">The Code is the Design</a>, you should be able to guess how bad I feel about architects who think coding is only for the wimps.  Indeed, there are architects who think that if they have to write the code then there&#8217;s little distinction between them and the plain old poor developers.  They think that the role is to direct, i.e. draw some diagrams and handle them out to the coders who will &#8220;realize&#8221; the design.  They argue that coding is just a simple step if the design is done right.  Some may go as far as stating that they don&#8217;t even need to know how to code in a language or understand the ins-and-outs of a technology before architecting a solution using those language and technology.  For example I met an architect who admitted that he had not coded any single line of Java code but thought that he would do fine when architecting enterprise JEE applications. &#8220;As long as I have good Java coders to implement my design,&#8221; he concluded.  A joke?  Not at all.  True story!
</li>
</ul>
<p>There, we have seen the 5 groups of architects who have somewhat been successfully in ruining the software architect role in the eyes of other people.  It&#8217;s high time they threw away their arrogance to not look down on others&#8217; opinions, got pass their boosterism to use the most appropriate tools for the problem at hand, and acknowledged their ignorance by continuously learning and keeping up with technological trends.  And last but not least, it&#8217;s high time they started writing code again…  And if the software industry has any luck, 5 or 10 years from now some developers may come across this post and think I was joking.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=The%205%20Types%20of%20Poor%20Architects&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fthe-5-types-of-poor-architects.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=UnDRaoFFvTU:oG-TM4u5Ipw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=UnDRaoFFvTU:oG-TM4u5Ipw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=UnDRaoFFvTU:oG-TM4u5Ipw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=UnDRaoFFvTU:oG-TM4u5Ipw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=UnDRaoFFvTU:oG-TM4u5Ipw:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/the-5-types-of-poor-architects.html/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/the-5-types-of-poor-architects.html</feedburner:origLink></item>
		<item>
		<title>The Story of a Hope-Driven Developer</title>
		<link>http://feedproxy.google.com/~r/BuuNguyensBlog/~3/EoYNoP31Qrk/the-story-of-a-hope-driven-developer.html</link>
		<comments>http://www.buunguyen.net/blog/the-story-of-a-hope-driven-developer.html#comments</comments>
		<pubDate>Mon, 19 May 2008 11:56:05 +0000</pubDate>
		<dc:creator>Buu Nguyen</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[developers]]></category>

		<guid isPermaLink="false">http://www.buunguyen.net/blog/the-story-of-a-hope-driven-developer.html</guid>
		<description><![CDATA[A fictitious story about a fictitious &#8220;hope-driven&#8221; developer&#8230;  In a sense, it&#8217;s fictitious because there&#8217;s probably no one single coder exposes all these behaviors of being hope-driven.  On the other hand, it&#8217;s not hard to find one who frequently displays one or more of these behaviors.  Anyway, let&#8217;s now travel into the [...]]]></description>
			<content:encoded><![CDATA[<p>A fictitious story about a fictitious &#8220;hope-driven&#8221; developer&#8230;  In a sense, it&#8217;s fictitious because there&#8217;s probably no one single coder exposes all these behaviors of being hope-driven.  On the other hand, it&#8217;s not hard to find one who frequently displays one or more of these behaviors.  Anyway, let&#8217;s now travel into the mind of our fictitious hope-driven fellow&#8230;<br />
</p>
<hr />
<br />
<i>I am a hope-driven developer.  I am superior and productive. I love coding and I&#8217;m different from others. </p>
<p>Unlike others, I don&#8217;t write unit test for my code.  I hope my code will work right because I&#8217;m so good at coding.  Even in the rare cases when it doesn&#8217;t, the QA team should be able to catch the defects easily and I will immediately know what happen to make necessary fixes.  I hope I will never have to touch most of the already written code again and if I don&#8217;t have to revisit it, what would unit tests help anyway? </i><br />
<span id="more-207"></span><br />
<i>Unlike others, I don&#8217;t check in compilable code into the source control system very often.  Instead, I code it straight for several days (or weeks) until finishing my module before checking everything in.  I hope my code will not break any code of others and I hope others&#8217; code won&#8217;t cause funny behavior in mine.  Besides, my colleagues should follow the architecture design so carefully that there are no integration defects between their components and mine.  </p>
<p>Unlike others, I don&#8217;t follow coding conventions.  I believe people are different and should be respected for that.  I am not productive following a coding style I&#8217;m not familiar with and it&#8217;s productivity that I am getting paid for.  I hope my peers will understand my code easily because as I mentioned, I&#8217;m so good in coding.  But I hope I never have to read that code of my peers because they seem to employ very cryptic styles.  (Being as tolerant as I am towards people&#8217; uniqueness, I just can&#8217;t understand why somebody does not want to include an &#8220;i_&#8221; prefix for their variables to denote integer type.)</p>
<p>Unlike others, I don&#8217;t write comments.  I hope that my code is so self-explanatory that everybody can easily understand.  How is it possible that one cannot guess from my highly self-explanatory code as to which the pre-conditions of a procedure are, the exceptions thrown by it, and the logic behind it?  After all, it&#8217;s written in a really high-level programming language.  But why should anybody read my code if it is really so perfect?  (Encapsulation and loose-coupling, everyone?)</p>
<p>Unlike others, I don&#8217;t learn and use design patterns.  I hope that my design skill is so good that I don&#8217;t need to learn from any others.  Even if it is not the case (hardly be), I hope that design patterns overkill for all my design problems.  Besides, my problems, which are very challenging and unique, would have no such thing as a proven solution to them.  I also hope that the languages I use are so superior that design patterns are just so irrelevant.  </p>
<p>Unlike others, I can only start writing code when having every detail of the requirement spelled out and a detailed design document in place.  By having comprehensive requirement specifications, I don’t have to change my code frequently mid-course because of requirement misunderstanding or guessing.  I also hope that it would make my customers feel less freely to change their mind because all things having already been written down.  And by having a good and detailed design document in place, my colleagues&#8217; code and mine will work together smoothly and automatically because the code are mostly a one-to-one mapping from a good and detailed design.</p>
<p>Unlike others, I look down on the so-called 15-minutes daily meetings, during which people in turn report what they had done, would do, and any problems faced.  Everyone should be professional enough to know what they are supposed to do for the day and problems should visible to the right people at the right time without requiring a daily teaming-up.  Besides, the works of my colleagues and I are usually so independent that there is no need to communicate so frequently.  (Just follow the design document and code your way through, guys!)</p>
<p>Unlike others, I don&#8217;t learn new things.  I hope that the knowledge that I have gained thus far is sufficient for me to address any coding problem.  And as I am so familiar with the current tools, I am supposed to be highly productive with them than I can ever be with any other tools.  (After all, it&#8217;s a famous person, who I can&#8217;t remember the name and is said to write that there would be no silver bullet upon the next decade in the software engineering field.  I can&#8217;t agree more!)</p>
<p>That&#8217;s how I get by.  Coding productively and passionately.  I typically chunk out a hundred or so lines of code per week and if you take into my multi-year software development career, that is a lot of code.  I can&#8217;t help but feeling so proud of what I have done&#8230;  </p>
<p>I love coding and I&#8217;m different from others.  I am superior and productive.  I am a hope-driven developer&#8230; </i></p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?sitename=Buu%20Nguyen%27s%20Blog&amp;siteurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2F&amp;linkname=The%20Story%20of%20a%20Hope-Driven%20Developer&amp;linkurl=http%3A%2F%2Fwww.buunguyen.net%2Fblog%2Fthe-story-of-a-hope-driven-developer.html"><img src="http://www.buunguyen.net/blog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Save/Bookmark"/></a>

	</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=EoYNoP31Qrk:x4AQRdJ-VYM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=EoYNoP31Qrk:x4AQRdJ-VYM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=EoYNoP31Qrk:x4AQRdJ-VYM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BuuNguyensBlog?a=EoYNoP31Qrk:x4AQRdJ-VYM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BuuNguyensBlog?i=EoYNoP31Qrk:x4AQRdJ-VYM:D7DqB2pKExk" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.buunguyen.net/blog/the-story-of-a-hope-driven-developer.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.buunguyen.net/blog/the-story-of-a-hope-driven-developer.html</feedburner:origLink></item>
	</channel>
</rss>
