<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>The Software Devotional</title>
    
    
    <link rel="alternate" type="text/html" href="http://www.thesoftwaredevotional.com/" />
    <id>tag:typepad.com,2003:weblog-1773462</id>
    <updated>2011-02-07T20:31:00-06:00</updated>
    <subtitle>Not All Who Wander Are Lost</subtitle>
    <generator uri="http://www.typepad.com/">TypePad</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/typepad/TheSoftwareDevotional" /><feedburner:info uri="typepad/thesoftwaredevotional" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://hubbub.api.typepad.com/" /><feedburner:emailServiceId>typepad/TheSoftwareDevotional</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry>
        <title>Dice's 2010-11 Tech Salary Survey Results</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typepad/TheSoftwareDevotional/~3/2Hcijx7Weow/dices-2010-11-tech-salary-survey-results.html" />
        <link rel="replies" type="text/html" href="http://www.thesoftwaredevotional.com/2011/02/dices-2010-11-tech-salary-survey-results.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a01053602891a970c0147e26341d0970b</id>
        <published>2011-02-07T20:31:00-06:00</published>
        <updated>2011-02-09T10:32:03-06:00</updated>
        <summary>Dice released their 2010-2011 Tech Salary Survey Results. If you have a technical job, take a look and see how you rank. As you read through it, don't get too bummed by all the average results shown. The numbers generally...</summary>
        <author>
            <name>Michael Jones</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="Professional Development" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Software Development" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.thesoftwaredevotional.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://jeauxnes.typepad.com/.a/6a01053602891a970c0148c873f54b970c-pi" style="float: left;"><img alt="Barchart" class="asset  asset-image at-xid-6a01053602891a970c0148c873f54b970c" src="http://jeauxnes.typepad.com/.a/6a01053602891a970c0148c873f54b970c-200wi" style="margin: 0px 5px 5px 0px; width: 200px;" title="Barchart" /></a> <br />Dice released their <a href="http://marketing.dice.com/pdf/Dice_2010-11_TechSalarySurvey.pdf" target="_blank">2010-2011 Tech Salary Survey Results</a>. If you have a technical job, take a look and see how you rank.</p>
<p>As you read through it, don't get too bummed by all the average results shown. The numbers generally show a single axis of data, meaning that all the other values are simply average values. An example: In the "Average Salary By Experience" section, the average salary during the 2010-2011 reporting period was $95,399. That's kinda wacky in my experience for someone with more than 15 years of experience. But you have to remember something when you see that number - it is the average across all of the other axes: company size, employment type, region of the country, job title, industry, skill set, education level, etc.</p>
<p>The real numbers for you would be an average of all the respondents' salaries that match your number of years of experience, company size, employment type, region of the country, etc. You get the picture. Due to the simple laws of supply and demand, some areas of the country pay disproportionately more for J2EE developers or good DBAs.</p>
<p>Still, the number are useful. The year-over-year values show where your job is headed in terms of salary across all the axes shown. Compare your current job title or skills to a different title or set of experience to find out if the job change you were mulling over makes sense financially.</p>
<p>All that said, the biggest impact on your salary is likely to be YOU. Are you <a href="http://www.amazon.com/gp/product/1590598385?ie=UTF8&amp;tag=theintendevel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1590598385" target="_self">Smart and Gets Things Done</a>? Do you observe and promote the <a href="http://www.amazon.com/gp/product/097451408X?ie=UTF8&amp;tag=theintendevel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=097451408X" target="_self">Practices of an Agile Developer</a>? Do you do what you can to <a href="http://www.thesoftwaredevotional.com/2009/07/suggestions-for-keeping-your-net-skills-current.html" target="_self">keep your development skills current</a>? Does your boss (and his boss) value what you do? Are you a valuable member of your team (would your team members agree)? Are you seen as a leader by your peers? Not a supervisory leader (that's different), but the guy that people go to when they can't figure something out, or when they need a suggestion for solving a problem. My point here is that unless you work for a company where there just isn't room for higher salaries or career advancement, your salary will be governed mostly by what you do - by making yourself invaluable to the company.</p></div>
</content>



    <feedburner:origLink>http://www.thesoftwaredevotional.com/2011/02/dices-2010-11-tech-salary-survey-results.html</feedburner:origLink></entry>
    <entry>
        <title>IE Is Being Mean to Me</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typepad/TheSoftwareDevotional/~3/R6Y_yvGp5so/ie-is-being-mean-to-me.html" />
        <link rel="replies" type="text/html" href="http://www.thesoftwaredevotional.com/2010/04/ie-is-being-mean-to-me.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a01053602891a970c01347fbcacd1970c</id>
        <published>2010-04-08T18:03:00-05:00</published>
        <updated>2010-04-08T12:43:29-05:00</updated>
        <summary>As of late, my job has turned into lots of interface work and I have come to really appreciate this artist's sentiments about how IE is mean to him. Check it out. Also, if you ever get in the mood,...</summary>
        <author>
            <name>Michael Jones</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="Humor" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Web/Tech" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.thesoftwaredevotional.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><a href="http://nexus404.com/Blog/2007/10/26/make-your-own-internet-explorer-voodoo-doll-a-step-by-step-guide/"><img alt="Make an IE Voodoo Doll" border="0" src="http://www.thesoftwaredevotional.com/images/IEVoodooDoll.jpg" style="margin: 3px; float: left;" title="Make an IE Voodoo Doll" /></a></p>

<p>As of late, my job has turned into lots of interface work and I have come to really appreciate this artist's sentiments about how IE is mean to him. Check it out.</p>

<p>Also, if you ever get in the mood, I have included instructions on how to <a href="http://nexus404.com/Blog/2007/10/26/make-your-own-internet-explorer-voodoo-doll-a-step-by-step-guide/" target="_blank" title="make an IE voodoo doll">make an IE voodoo doll</a> (it really works).</p>

<p><object height="270" width="440"><param name="movie" value="http://www.youtube.com/v/vTTzwJsHpU8&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><embed allowfullscreen="true" allowscriptaccess="always" height="270" src="http://www.youtube.com/v/vTTzwJsHpU8&amp;hl=en_US&amp;fs=1&amp;color1=0x3a3a3a&amp;color2=0x999999&amp;border=1" type="application/x-shockwave-flash" width="440" /></object></p></div>
</content>



    <feedburner:origLink>http://www.thesoftwaredevotional.com/2010/04/ie-is-being-mean-to-me.html</feedburner:origLink></entry>
    <entry>
        <title>Highest Specificity Query - Database Query Pattern</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typepad/TheSoftwareDevotional/~3/J4q1aeQD44U/highest-specificity-query-database-query-pattern.html" />
        <link rel="replies" type="text/html" href="http://www.thesoftwaredevotional.com/2009/08/highest-specificity-query-database-query-pattern.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a01053602891a970c0120a501df7b970b</id>
        <published>2009-08-21T00:35:18-05:00</published>
        <updated>2009-08-21T00:33:35-05:00</updated>
        <summary>I don't know a better name to call it, but a database query pattern I have used *A LOT* is what I call a 'highest specificity query'. The best way to describe it is to provide a simple example. You...</summary>
        <author>
            <name>Michael Jones</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="Design Patterns" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="SQL" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.thesoftwaredevotional.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><img alt="Highest Specificity Query" border="0" src="http://www.thesoftwaredevotional.com/images/SQLTableLayout.jpg" style="margin: 3px; float: left;" title="Highest Specificity Query" /></p>

<p>I don't know a better name to call it, but a database query pattern I have used *A LOT* is what I call a 'highest specificity query'. The best way to describe it is to provide a simple example.</p>

<p>You have an application used by staff members in a hospital. All of the staff members use the application, but a configuration option in a central database is used to determine each user's level of security inside the application. The level of security, for the purpose of this example, is expressed as an integer value from 0-9, but could take any form required by the application. Since there are potentially thousands of users at each facility, you want to be able to configure a default value at the system level, and then override the value at the facility, department, and user levels. The application is designed such that a value specified at the user level would override department and facility settings and a setting at the department level will override a setting at the facility level.</p>

<p><img alt="SQL Table Layout" border="0" src="http://www.thesoftwaredevotional.com/images/SecurityLevels.gif" style="margin: 3px; float: right;" title="SQL Table Layout" /></p>

<p>I like to keep things simple, so I use a single table to host this configuration data. Check out the SQL Server view of the table configuration to the right. </p>

<p>Here is how the SQL table works. If you want to make an assignment at a facility level, set only the facility ID and securityLevel for the row (leave departmentID and userID Null) - any users associated with that facility that don't have a more specific securityLevel setting (set at the department or user level) will get that securityLevel value. Similarly, the securityLevel can be set for all users of a department by setting the facilityID and departmentID (leave the userID NULL). Check out the sample table below.</p>

<p style="text-align: center;"><img alt="Sample Table" border="0" src="http://www.thesoftwaredevotional.com/images/SQLTableConfiguration.gif" style="margin: 3px;" title="Sample Table" /></p>

<ul>
<li>rowID 1 provides a base security level for any users who aren't configured with a more specific securityLevel vaule.</li>
<li>rowID 2 overrides rowID 1 and sets a security level of 1 for all users of facilityID 1. In this example, this would provide a default securityLevel for all users at the facility of 1. A security level of 1 is a low level that might provide only read-only access to non-sensitive information.</li>
<li>rowID 3 overrides rowIDs 1 and 2 and sets a security level of 5 for all users of department 20 inside facility 1. This might represent a clinical department that requires write access to clinical areas of the application.</li>
<li>rowID 4 overrides rowIDs 1, 2, and 3 and sets a security level 3 for user 345 inside departmentID 20 and facilityID 1. In this case, a new employee at the facility has a lower level of access than everyone else in the department.</li>
<li>rowID 5 overrides only rowID 1 and sets a very high securityLevel for facilityID 2. This facility asked to keep security simple and give everyone a high level of access.</li>
</ul>

<p>The SQL query used is shown below. It is written with the assumption that the query is running inside a stored procedure with parameters named @p_facilityID, @p_departmentID, and @userID. When the query is run, the values for facility, department, and user are provided by the calling application, and only the most specific row is returned from the query. Take a look at the query below.</p>

<blockquote><pre>SELECT TOP 1 securityLevel <br />FROM SecurityLevels <br />WHERE <br />	(facilityID = @p_facilityID OR facilityID IS NULL) <br />	AND <br />	(departmentID = @p_departmentID OR departmentID IS NULL) <br />	AND <br />	(userID = @userID OR userID IS NULL)<br />ORDER BY <br />	userID DESC, departmentID DESC, facilityID DESC<br /></pre></blockquote>

<p>Some notes about the query:</p><ul>
<li>TOP 1 is included to force the single most specific row to be returned by the query.</li>
<li>The mildly complex WHERE clause filters rows where the row either matches the value for the field or is set to NULL. This allows instances where none (or perhaps only a portion) of the criteria match rows in the table. For example, using the example table above, suppose a query is run where the following parameter values are provided: facilityID = 2, departmentID = 100 and userID = 300. The WHERE clause will return only the row where rowID = 5, because it was the only row where even a partial match of the search criteria was found.</li>
<li>The ORDER BY clause puts the most specific row at the top of the results (the TOP 1 ensures that only the results from this row are returned). In the example, we want settings at the user level to override any other settings. The priority then falls to department and then facility. Therefore, we sort in the order of userID, departmentID, facilityID. The DESC argument ensures that non-NULL values sort ahead of NULL values, ensuring that the top record in the result set is the most specific row for the given search criteria. In the example table above, searching using facilityID = 1, departmentID = 20, and userID = 214 would return rowID 3, since that row is the best match.</li>
</ul>
<p>You probably noticed that I used a NULL value to represent a value that isn't assigned in the table. It's also possible to use a zero for unassigned values. It's a trade-off either way: if you use NULL values then you need a surrogate primary key since NULLable columns are not candidates for primary keys. My example above uses rowID for the surrogate key. However, if you use zeros then you either can't use referential integrity or you need to add bogus rows (with zero values) to the primary key tables.</p><p>This type of table and the highest specificity SQL query that goes with it has been an indispensable pattern in building enterprise software solutions. In the example above, I used only 3 fields for search criteria (facilityID, departmentID, and userID), but the pattern supports any number of search criteria necessary for your needs - simply add the columns to the table and modify the SQL query accordingly. Further, since the bulk of the configuration in these tables will be in the higher-order fields (that's been my experience) such as facilityID or departmentID, the tables remain very small even for very large implementations and perform very well.<br /><span style="font-size: 14px;" /></p></div>
</content>



    <feedburner:origLink>http://www.thesoftwaredevotional.com/2009/08/highest-specificity-query-database-query-pattern.html</feedburner:origLink></entry>
    <entry>
        <title>Suggestions for Keeping Your .NET Skills Current</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typepad/TheSoftwareDevotional/~3/b_o6-W13oDk/suggestions-for-keeping-your-net-skills-current.html" />
        <link rel="replies" type="text/html" href="http://www.thesoftwaredevotional.com/2009/07/suggestions-for-keeping-your-net-skills-current.html" thr:count="1" thr:updated="2009-09-21T17:05:43-05:00" />
        <id>tag:typepad.com,2003:post-65162279</id>
        <published>2009-07-15T07:00:00-05:00</published>
        <updated>2009-08-17T00:37:53-05:00</updated>
        <summary>I got caught in a flypaper conversation a while back during which one of my fellow developers asked for suggestions on how to keep his .NET skills current. Professional development, as it is generally called, isn't something I think about...</summary>
        <author>
            <name>Michael Jones</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term=".NET" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Professional Development" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.thesoftwaredevotional.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><p><img alt="Training and Professional Development" border="0" height="224" src="http://www.thesoftwaredevotional.com/images/books.jpg" style="margin: 0px 5px 5px 0px; float: left;" title="Training and Professional Development" width="168" /></p>

<p>I got caught in a flypaper conversation a while back during which one of my fellow developers asked for suggestions on how to keep his .NET skills current. Professional development, as it is generally called, isn't something I think about often. I read a lot, read lots of blogs, speak and write about .NET development, and experiment with lots of new technologies as they become available. Professional development is only a side-effect of my curiosities and interests.</p><p>If my observations are anything close to reality, I find that most developers do not spend nearly enough time sharpening their saws. Steven Covey, who coined the phrase in his book <em><a href="http://www.amazon.com/gp/product/0743269519?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0743269519" target="_blank" title="7 Habits of Highly Effective People">7 Habits of Highly Effective People</a></em>, describes sharpening the saw as "having a balanced program for self-renewal in the four areas
of your life: physical, social/emotional, mental, and spiritual", with the mental area concisely described as "learning, reading, writing, and teaching." The part of the saw that I am talking about is in the mental department.</p><p>Other than the 'soft' skills required for advancing in any team environment, a developer must constantly be sharpening his skills in software development in order to continue to be a successful software developer. Developers need to be knowledgeable enough about a broad range of topics to bring the right tool to the table when a need arises. Even if you aren't an expert with the tool, or even very proficient, you need to know where to start. For developers who make a habit of keeping their saws sharp, not everything will look like a nail just because they know a lot about hammers.</p><p>Back to the question of skills. So I thought about the things I do. Here is a brief list of the things I do that I think help keep my .NET skills current.</p><h1>Magazines</h1><p>Unfortunately, there don't seem to be many mainstream magazines that specifically cover .NET development. However, we have some pretty good ones. If you are on a budget, you will find that you can find the content of most magazines available online.</p><p><em><a href="http://msdn.microsoft.com/en-us/magazine/default.aspx" target="_blank" title="MSDN Magazine">MSDN Magazine</a></em> is probably the most well known .NET/Microsoft development magazine, although it isn't my favorite. In my opinion, the articles are too long and detailed (does that sound backward?). In most cases, I am looking for bite-sized, ADHD-friendly, articles that cover the "why, what, and so what" questions along with enough technical detail to get me started on a project. I would prefer more articles that dive deep on more narrowly focused subjects so that I can pick the topics I am interested in. Nonetheless, it is still a very good magazine for staying current with Microsoft technologies - especially the new and yet-to-be released technologies.</p><p><em><a href="http://visualstudiomagazine.com/" target="_blank" title="Visual Studio Magazine">Visual Studio Magazine</a></em>, while it almost faded out of existence several years ago, is experiencing somewhat of a revival. Good authors have been contributing some great content and the magazine has become something I read more regularly. </p><p>Along the same lines, <em><a href="http://www.code-magazine.com/" target="_blank" title="CoDe Magazine">CoDe Magazine</a></em> provides some pretty good .NET technical content as well, but hasn't made it into the group of sources I consult regularly for .NET content (no can explain). One very nice feature that I love about CoDe's website is their topical index. Click any one of numerous topics such as WCF, AJAX, XML, etc. to see a list of articles covering the topic (similar to a tag cloud on a blog).</p><p /><h1>Find It Online</h1><p>In addition to reading magazines, preferable online versions, you will find that there are lots of web sites devoted to .NET development topics. I will suggest some, but there really are too many to try to list here. My suggestion is to find several that focus on the area of programming that you want to learn about, and check back with the site regularly for content of interest. Most of them allow you to subscribe to a syndication (RSS/Atom) or email feed to have regular updates pushed to you when new content hits the site. Subscribe to a few and spend a little time each week reviewing the new content and reading/skimming the articles that interest you.</p><p>Before getting to the online-only sites, keep in mind that most print magazines (including <em><a href="http://msdn.microsoft.com/en-us/magazine/default.aspx" target="_blank" title="MSDN Magazine">MSDN Magazine</a></em>, <em><a href="http://visualstudiomagazine.com/" target="_blank" title="Visual Studio Magazine">Visual Studio Magazine</a></em>, and <em><a href="http://www.code-magazine.com" target="_blank" title="CoDe Magazine">CoDe Magazine</a></em>, all mentioned above) can be read online.</p><p>One of my favorite programming web sites has always been <a href="http://www.devx.com/" target="_blank" title="DevX">DevX</a>. &lt;FullDisclosureStatement&gt;I must point out that I also write periodically for DevX, but that is only because after searching around several years ago, DevX was the online publication I liked the most.&lt;/FullDisclosureStatement&gt; DevX is a very broadly scoped programming site - it does not specialize in any single type of development and they generally don't dive overly deep on any single topic. Instead, DevX offers a very broad set of content for software developers of all types and ranges of experience. Subscribe to their email digest in the programming areas you are interested in.</p><p><a href="http://www.codeproject.com/" target="_blank" title="The Code Project">The Code Project</a> is also a favorite of mine. The Code Project is a site where developers go to post how-tos, sample code and articles about software development. Like DevX, The Code Project serves a very diverse audience. However, there are so many new contributions every week that you can typically find several different articles on any subject (most with sample code) you are searching for.</p><p>Two others that I follow very closely are <a href="http://www.infoq.com" target="_blank" title="InfoQ">InfoQ</a> and <a href="http://www.theserverside.net" title="TheServerSide.NET">TheServerSide.NET</a>. InfoQ is a very broadly based architecture and development community news site. It covers everything from Java and open source development to .NET development. If you consider your role to encompass that of architecture, make sure you keep up with the news flowing out of InfoQ.  TheServerSide.NET is slanted more towards boots-on-the-ground developers practicing the art of .NET development. Both are good places to keep up with the world of development.</p><p>Even better than reconnoitering the web site on a regular basis, which you are likely to forget to do on a regular basis, sign up for the periodic emails from the sites. It pushes the content right under your nose. If you spend the time to read through these messages, you will have no trouble staying on top of the goings on in the industry. </p><p /><h1>Blogs</h1>
<p>Blogs might initially seem similar to online magazine articles, but after reading through them for a while you will find that they are generally much different. Blogs are typically more narrowly focused streams of content. You will find authors blogging about things they come across in their jobs: programming VB.NET, software architecture, WinForms control development, etc. What's better, most blogs support subscriptions so you can not only be notified of new content, but also so you can read the content at your leisure from any of a number of great blog readers (if you don't have one you already LOVE, try <a href="http://www.google.com/reader" target="_blank" title="Google Reader">Google Reader</a>). The idea here is to pick lots of blogs from authors that post about topics that interest you. Plan to add more blog subscriptions as you find more content and to unsubscribe from blogs that go stale.</p><p>If you are a .NET developer, check out <a href="http://weblogs.asp.net/scottgu/default.aspx" target="_blank" title="Scott Guthrie's Blog">Scott Guthrie's blog</a>. He posts on lots of topics of general interest to .NET developers.</p><p>Do a <a href="http://www.google.com/search?q=.net+programming+blogs" target="_blank" title="Google Search for .NET Programming blogs">Google search</a> for ".net programming blogs". Subscribe to the ones that interest you. I find it helpful to browse the actual blog web site occasionally to find links to other interesting blogs. Do this periodically to keep your list of blogs fresh and interesting to you.</p><p>Although not of specific interest to .NET developers, one of my favorite techy blogs is <a href="http://www.codinghorror.com/blog/" target="_blank" title="Coding Horror, By Jeff Atwood">Coding Horror</a>, hosted by Jeff Atwood. The topic isn't always about programming, but Jeff normally writes about topics that are of interest to developers with a sense of humor that is sure to please all but my wife, who doesn't seem to find humor funny.</p><h1>Books</h1>
<p>There really aren't a lot of general purpose .NET programming books that I can recommend, since a good book has a narrow focus on a particular subject area. However, I have listed a few good places to start below.</p><p><em><a href="http://www.amazon.com/gp/product/0735619670?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0735619670" target="_blank" title="Code Complete">Code Complete</a></em>, by Steve McConnell, is one of the most widely read books about solid coding practices that exists. It is now in its second edition (I own both) and has been revised to include more .NET coverage.</p><p>A topic that ALL developers should know more about is design patterns. The best book on the market for learning design patterns is <em><a href="http://www.amazon.com/gp/product/0596007124?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596007124" target="_blank" title="Head First Design Patterns">Head First Design Patterns</a></em>. It is one of a number of books from the Head First series, which takes a narrative and almost <a href="http://en.wikipedia.org/wiki/Socratic_method" target="_blank" title="Socratic">Socratic</a> approach to teaching design patterns. After reading <em>Head First Design Patterns</em> and when you have come to understand when a design pattern is useful and how it works, you can pick up <em><a href="http://www.amazon.com/gp/product/1590592743?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1590592743" target="_blank" title="Professional Design Patterns in VB.NET">Professional Design Patterns in VB.NET</a></em> or purchase download-able code for each of the patterns from the <a href="http://www.dofactory.com" target="_blank" title="Data &amp; Object Factory">Data &amp; Object Factory</a>. While I don't recommend it because it is more academic that most developers need, I will get beat up (no, seriously) if I don't also mention the so-called gang of four design patterns book: <em><a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201633612" target="_blank" title="Design Patterns: Elements of Reusable Object-Oriented Software">Design Patterns: Elements of Reusable Object-Oriented Software</a></em>.</p>
<p>Another great way to stay fresh is to get certified as a <a href="http://www.microsoft.com/learning/en/us/certification/mcpd.aspx" target="_blank" title="Microsoft Certified Professional Developer">Microsoft Certified Professional Developer</a>. While <a href="http://www.thesoftwaredevotional.com/2009/05/do-certifications-matter.html" target="_blank" title="I don't value certification">I don't value certification</a> for most developers, it is a big help for either new developers or developers getting out in the job market. A MCPD line on your resume can stand out when large numbers of resumes are being reviewed. If you are happily employed, the training can yield lots of nuggets of new information you didn't previously know and, in some cases, get you a small bonus or bump in pay.</p>
<p>There are lots of other books you can consider. There are only a few that I can recommend to a broad audience:</p><p><em><a href="http://www.amazon.com/gp/product/097451408X?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=097451408X" target="_blank" title="Practices of an Agile Developer">Practices of an Agile Developer</a></em> should be required reading for developers. Even if your development group doesn't practice agile development, read this book. It should have been named <em>Practices of a Professional Developer</em>.</p><p><a href="http://www.amazon.com/gp/product/0932633439?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0932633439" target="_blank" title="Peopleware">Peopleware</a> and <a href="http://www.amazon.com/gp/product/0201835959?ie=UTF8&amp;tag=thesoftdevo-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201835959" target="_blank" title="The Mythical Man-Month">The Mythical Man-Month</a> are age-old favorites that seasoned software developers know and bring up, often in a passing way, in hallway conversations. They are good bedside reading because they will put you to sleep and because there are sound management principles covered throughout both books.</p><p>Also, as a general rule of thumb, don't shy away from management books. Having noodled over some of the issues faced by managers might be a benefit one day when you have the opportunity to lead a group of developers. Management books are also good because they can help a developer to be more self-aware of himself when it comes to how managers view developers.</p><h1>Conferences/Training</h1>
<p>The most popular conferences are the large national conferences hosted around the country. The biggest conference with the broadest diversity of content available is <a href="http://www.devconnections.com/" target="_blank" title="DevConnections">DevConnections</a>, held twice a year: Orlando in the Spring and Las Vegas in the Fall. This conference draws the best speakers every time. </p><p>Another big conference to check out is <a href="http://www.vslive.com/" target="_blank" title="VSLive">VSLive</a>. VSLive is very similar to DevConnections, except on a smaller scale. VSLive travels to more venues so you might find one closer to home.</p><p>I am very happy to see that there are smaller locally hosted conferences popping up all over the country. These are often non-profit and often hosted by a local user group. They don't have nearly as many nationally recognized speakers, but are LOTS cheaper, don't require travel, and last only 1-3 days. These factors make local conferences easy to get approved by your manager. Ask around at a local user group or check out <a href="http://communitymegaphone.com/" target="_blank" title="Community Megaphone">Community Megaphone</a> to find a conference near you. If you live in or near Nashville or Knoxville (Tennessee), check out <a href="http://www.devlink.net/" target="_blank" title="DevLink">DevLink</a> (Nashville) or <a href="http://www.codestock.org" target="_blank" title="CodeStock">CodeStock</a> (Knoxville) - both are great examples of local conferences offering great content at unbeatable prices.</p><p>Microsoft hosts events in lots of cities all over the country to promote their servers and development tools. Don't miss the free training and an opportunity to network with other developers in your area. Check the <a href="http://www.msdnevents.com/" target="_blank" title="MSDN Events">MSDN Events</a> site regularly.</p><p>Another avenue you can pursue is focused developer training from one of many training providers. In most big cities, you will probably find several training providers that offer a wide range of training. Be careful though - many training providers simply choose to use the Microsoft-authored training curriculum, which is good enough to get you started if you are starting near zero. The best training providers that I know of are <a href="http://www.pluralsight.com/main/" target="_blank" title="Pluralsight">Pluralsight</a> and <a href="http://www.develop.com/" target="_blank" title="DevelopMentor">DevelopMentor</a>. Both have written top-notch custom training programs covering many .NET subject areas. Pluralsight edges out DevelopMentor (seems to me that most of the best talent from DevelopMentor moved to Pluralsight several years back) in terms of high-power talent teaching and authoring the courses, but DevelopMentor has considerably broader course offerings, more training locations, it offers each course much more often, and offers several courses in Guerrilla format (10-12 hours per day for 5 days).</p><h1>Conclusion</h1>
<p>I have undoubtedly missed some important points because I pulled this together very quickly. If I have missed something you think important to mention, leave me a comment.</p></div>
</content>



    <feedburner:origLink>http://www.thesoftwaredevotional.com/2009/07/suggestions-for-keeping-your-net-skills-current.html</feedburner:origLink></entry>
    <entry>
        <title>*VERY* Simple Example of Loose Coupling</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typepad/TheSoftwareDevotional/~3/lcKcc3YD_ng/very-simple-example-of-loose-coupling.html" />
        <link rel="replies" type="text/html" href="http://www.thesoftwaredevotional.com/2009/07/very-simple-example-of-loose-coupling.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a01053602891a970c011570fae9d5970c</id>
        <published>2009-07-11T15:59:18-05:00</published>
        <updated>2009-07-11T16:01:33-05:00</updated>
        <summary>I have preached here once or twice before about the virtues of loose coupling. I will not belabor the point much more here, except to say that I get lots of emails from people asking about specific examples of loose...</summary>
        <author>
            <name>Michael Jones</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="Loose Coupling" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Software Development" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Unit Testing" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://www.thesoftwaredevotional.com/">
<div xmlns="http://www.w3.org/1999/xhtml"><br /><p><img alt="Bug" border="0" height="86" src="http://www.thesoftwaredevotional.com/images/BinaryNumbers.jpg" style="margin: 0px 5px 5px 0px; float: left;" title="Visual Studio" width="144" /></p>

<p>I have preached here <a href="http://www.thesoftwaredevotional.com/2009/02/loose-coupling-is-good-tight-coupling-is-the-devil.html" target="_blank" title="Loose Coupling is Good - Tight Coupling is the Devil">once</a> or <a href="http://www.thesoftwaredevotional.com/2009/04/zen-and-the-art-of-loose-coupling.html" target="_blank" title="Zen and the Art of Loose Coupling">twice</a> before about the virtues of loose coupling. I will not belabor the point much more here, except to say that I get lots of emails from people asking about specific examples of loose coupling in their corporate projects. It seems everyone is feeling the same pains. I have also received a fair number of emails that go like this: "I am working on a project and was wondering if you could help me understand loose coupling by showing me how to make my code more loosely coupled." Attached to those messages is a zip file containing their Visual Studio project. I apologize if you are the sender of an email that went unanswered or worse, I answered your email and said that I couldn't spend enough time to give you a good answer. The truth is, it is somewhat difficult to look at a large body of unfamiliar code and quickly offer meaningful guidance. I have said <a href="http://www.thesoftwaredevotional.com/2008/03/how-i-do-it-uni.html" target="_blank" title="How I Do It: Unit Testing with NUnit">before</a> that a good rule of thumb is that vigilant use of good coding practices makes code easier to test - loose coupling is a paramount example of this principle.</p><p>Recently, I have come across code that is more tightly coupled than necessary, making unit testing more difficult than need be.  Here is one very simple example - consider the code below.</p>

<blockquote><p>
<strong>Figure 1: Tight Coupling of Method to Complex Parameter Type</strong></p>
<pre style="background-color: #eaf2ff;">Private Sub DoSomeLogging( _<br /> ByVal p_ApplicationState As ApplicationState)<br /><br /> With p_ApplicationState<br /><br /> '...<br /><br /> End With<br /><br />End Sub<br /></pre>
</blockquote>

<p>Nothing looks amiss initially, but try to write a unit test for this method. Do you see it? The DoSomeLogging method is tightly bound to the ApplicationState object. The method isn't useful at all without an ApplicationState object. Also, as you can see, to test this method you must manually construct an ApplicationState object to pass into the DoSomeLogging method. The problem with passing big classes and structures into a method like this is that it can be very time consuming (and potentially dangerous in your production environment) to manually construct such objects.</p><p>The boss says write the unit test and ship it, so you do. You build bunches of private methods to manually construct an ApplicationState object. You see that your unit tests pass and everyone's happy. You get to keep your job.</p><p>Two weeks later, you make a small change to your code, and start running your unit tests. Many of them are failing. What happened? Someone changed the ApplicationState class and/or the classes that consume it, and now your manual construction of the ApplicationState object is stale. You research the changes that were made, make changes to your ApplicationState construction code, and then deploy your changes. You see that your unit tests pass and everyone's happy.</p><p>Two weeks later (yes, it happens again), you make a small change to your code, and start
running your unit tests. Many of them are failing. What happened?
Someone changed the ApplicationState class and/or the classes that
consume it, and now your manual construction of the ApplicationState
object is stale. You research the changes that were made, make changes to your ApplicationState construction code, and then deploy your changes. You see that your unit tests pass and everyone's happy.</p><p>Two weeks later ... you get the point. The simple feedback I have for this method is that (since the ApplicationState object is difficult to construct and fragile to build manually) it is very likely easier to just pass into DoSomeLogging the data it needs rather than passing in the entire ApplicationState object.  It will absolutely lead to longer parameter lists for your methods and some refactoring will be required, but it is worth the effort. Your testing will go more smoothly and your method will be more useful.</p><p>The new and improved DoSomeLogging method will look like the code in Figure 1.

</p><blockquote><p>
<strong>Figure 2: Loosely Coupled Version of Method</strong></p>
<pre style="background-color: #eaf2ff;">Private Sub DoSomeLogging( _<br /> ByVal p_Parm1 As String, _<br /> ByVal p_Parm2 As String, _<br /> ByVal p_Parm3 As String, _<br /> ByVal p_Parm4 As String)<br /><br /> '...<br /><br />End Sub<br /></pre></blockquote>

<p /><p>Not only is this method easier to test, but it is easier to write, it is more likely to be shorter, it is more likely to have a lower <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity" target="_blank" title="Wikipedia: Cyclomatic Complexity">cyclomatic complexity</a>, and it is more likely to be reused.</p><p>If you read either of my previous articles, you will know that there is more to consider than just loose versus tight coupling. Consider the following.</p>
<ul>
<li>What if this method is an overload of another DoSomeLogging method (like the one shown in Figure 2) and its only purpose in life is to
make it simple to call the DoSomeLogging method without having to
specify all the parameters in every location where the DoSomeLogging
method is called. Good call, I think passing ApplicationState as a
parameter is a good move. </li>
<li>What if this method was intended to be used only with ApplicationState objects.
My gut tells me that perhaps the DoSomeLogging should have been a
method on the ApplicationState class. Even if it isn't, it is still
worth considering the pros/cons of decoupling the DoSomeLogging method
from the ApplicationState object. You will need to consider how often
DoSomeLogging is called (see bullet above), how fool-proof you want to
make the DoSomeLogging (you might want to prevent someone from passing
in the wrong parameters), and lots of other things before knowing which
way is the right way to go: loose versus tight coupling.</li>
<li>Keep it simple. One look at the code in Figure 1 tells you what the method does and its likely consumers. Readability is a paramount goal of mine and only egregious problems are likely to trump readability.<br />
 </li>
</ul>

<p>If you use the difficulty-of-unit-testing method of judging code smell, you would have caught this one right off. Luckily, I think this type of coupling is relatively easy to fix and even easier to avoid.</p></div>
</content>



    <feedburner:origLink>http://www.thesoftwaredevotional.com/2009/07/very-simple-example-of-loose-coupling.html</feedburner:origLink></entry>
 
</feed><!-- ph=1 -->

