<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Tim Barcz - Principles</title>
    <link>http://www.timbarcz.com/blog/</link>
    <description>My Code is My Craft</description>
    <image>
      <url>http://www.timbarcz.com/blog/content/binary/channelImage.jpg</url>
      <title>Tim Barcz - Principles</title>
      <link>http://www.timbarcz.com/blog/</link>
    </image>
    <language>en-us</language>
    <copyright>Tim Barcz</copyright>
    <lastBuildDate>Mon, 09 Mar 2009 18:36:56 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>blog@timbarcz.com</managingEditor>
    <webMaster>blog@timbarcz.com</webMaster>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=c2743618-091a-42f0-86e8-4f883bdbbeee</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,c2743618-091a-42f0-86e8-4f883bdbbeee.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,c2743618-091a-42f0-86e8-4f883bdbbeee.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c2743618-091a-42f0-86e8-4f883bdbbeee</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few months ago I <a href="http://devlicio.us/blogs/tim_barcz/archive/2009/01/05/real-life-single-responsibility-principle.aspx">blogged
about how we're using the single responsibility principle</a> in our application at
work.  I'm going to make an effort here to write more "Real Life" content. 
Often when a developer read principles or ideas in books, there is disconnect between
what he/she is reading and how an implementation would look in the real world. 
The goal of these "Real Life" scenarios is to show areas where I feel I've
reaped some benefit from following a specific pattern or practice.  This does
not mean that my implementation is the only way or always "book correct". 
The goal is to act as a bridge (quite possibly a old rickety bridge) between the book
knowledge and the real world.
</p>
        <p>
Moving along...
</p>
        <p>
One of the purported benefits of OOP has always been the abundant reuse of code. 
However, in my experience many applications fail to realize any amount of reuse beyond
copying and pasting between applications.  To really take advantage of code reuse
you have to have small, concise pieces which you can rearrange in order to make a
new behavior.  As a side note, and I want this be clear, many of the principles
of good software development, ie. SOLID, go hand-in-hand.  You can't do one without
the other and the benefits of one cannot be fully realized without the implementation
of the others.  You'll notice that a few sentences ago I said "small, concise
pieces".  A light bulb may have gone off in your head thinking "Single
Responsibility Principle", and if it did, bonus points for you.
</p>
        <p>
The key to code reuse is to build your components in a very focused way.  By
doing so, you can add functionality by combining different pieces of you application.
</p>
        <p>
Consider the following code used to authenticate a user into a site:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">void</span> btnSubmit_Click(<span style="color: #0000ff">object</span> sender,
EventArgs e)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span>
              <span style="color: #0000ff">string</span> Username
= Server.HtmlEncode(txtUsername.Text);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span>
              <span style="color: #0000ff">string</span> Password
= Server.HtmlEncode(txtPassword.Text);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>
              <span style="color: #0000ff">int</span> nUserID;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span>
              <span style="color: #0000ff">if</span> (Username
!= <span style="color: #006080">""</span> &amp;&amp; Password != <span style="color: #006080">""</span>)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span>
              <span style="color: #0000ff">using</span> (SqlConnection
cnn = <span style="color: #0000ff">new</span> SqlConnection(connectionString))</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span>
              <span style="color: #0000ff">using</span> (SqlCommand
cmd = cnn.CreateCommand())</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span> cmd.CommandText
= <span style="color: #006080">"usp_Login"</span>;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 14:</span> cmd.Parameters.AddWithValue(<span style="color: #006080">"@Username"</span>,
Username);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 15:</span> cmd.Parameters.AddWithValue(<span style="color: #006080">"@password"</span>,
password);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 16:</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 17:</span>
              <span style="color: #0000ff">using</span>(SqlDataReader
reader = cmd.ExecuteReader())</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 18:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 19:</span>
              <span style="color: #0000ff">if</span> (reader.Read())</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 20:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 21:</span> nUserId
= Convert.ToInt32(reader[0]); </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 22:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 23:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 24:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 25:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 26:</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 27:</span>
              <span style="color: #0000ff">if</span> (nUserID
&gt; 0)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 28:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 29:</span>
              <span style="color: #008000">//
if the user has checked the box</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 30:</span>
              <span style="color: #008000">//
store his information so he doesn't have to log in again</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 31:</span>
              <span style="color: #0000ff">if</span> (cbRememberMe.Checked)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 32:</span> FormsAuthentication.SetAuthCookie(nUserID.ToString(), <span style="color: #0000ff">true</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 33:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 34:</span> FormsAuthentication.SetAuthCookie(nUserID.ToString(), <span style="color: #0000ff">false</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 35:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 36:</span> BusinessLogicLayer.User
objUser = <span style="color: #0000ff">new</span> User(nUserID);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 37:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 38:</span>
              <span style="color: #008000">//
store session variables for later reference;</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 39:</span> Session[<span style="color: #006080">"UserID"</span>]
= nUserID;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 40:</span> Session[<span style="color: #006080">"Username"</span>]
= objUser.Username;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 41:</span> Session[<span style="color: #006080">"Password"</span>]
= objUser.Password;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 42:</span> Session[<span style="color: #006080">"AccessLevel"</span>]
= objUser.AccessLevel;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 43:</span> Session[<span style="color: #006080">"AccessLevelName"</span>]
= Enum.GetName(<span style="color: #0000ff">typeof</span>(Utilities.AccessLevel),objUser.AccessLevel);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 44:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 45:</span> Response.Redirect(<span style="color: #006080">"~/admin/admin.aspx"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 46:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 47:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 48:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 49:</span> View
= Views.Failed;</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 50:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 51:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 52:</span> }</pre>
          </div>
        </div>
        <p>
While the code above is functional, it does way too much.  In this button click
event there are:
</p>
        <ul>
          <li>
Call to database explicitly</li>
          <li>
logic to set an authorization cookie</li>
          <li>
Some session variables being set</li>
        </ul>
        <p>
Imagine for a moment that you now want to implement a new piece of functionality,
user impersonation.  In order to accomplish this with the path of least resistance,
which developers commonly take, would be to copy/paste all of the login logic to another
UI event somewhere else in the site.  <strong>The issue copy/paste development
is that any future change to the login logic has to be copied again or else the impersonation
feature isn't really impersonating a users experience.</strong>  <strong>The
insidious nature of copy/paste development is that while often it works, it creates
a brittle application.</strong></p>
        <p>
In a recent application we were wanting to add user impersonation.  Below is
an example of an implementation of user impersonation.  Adding the feature to
the application was gleefully simple.  The ease in adding impersonation was due
entirely to the proper granularity in our application components.  Seriously,
this is all the code it took:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span>
              <span style="color: #0000ff">public</span> ActionResult
ImpersonateUser(<span style="color: #0000ff">int</span> id)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> var
authService = Container.Resolve&lt;AuthService&gt;();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> var
userRepository = Container.Resolve&lt;UserRepository&gt;();</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span> var
userToImpersonate = userRepository.GetById(id);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span>
              <span style="color: #0000ff">if</span> (userToImpersonate
!= <span style="color: #0000ff">null</span>)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span> authService.SignIn(userToImpersonate);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span>
              <span style="color: #0000ff">return</span> RedirectToAction(<span style="color: #006080">"Index"</span>, <span style="color: #006080">"Home"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span> }</pre>
          </div>
        </div>
        <p>
I did not know we were going to want user impersonation for this application when
we started.  However because we developed the site with certain principles in
mind, we were able to reuse pieces of code in ways not originally intended for added
behavior.  As you can see from the code above, there are no "clever hacks"
or tricks to get impersonation to work.  The beauty of the code above is that
if we change the implementation of "SignIn(user)" all appropriate areas
will follow the same rules since all areas use the same code.
</p>
        <p>
As I'm closing I want to challenge those of you who have read this far to stop yourself
the next time you find yourself copying code from one location to another.  Is
there an abstraction or component you're overlooking?  Think about the long term
and ask if you're really making the wisest decision for the long term health of your
application.  It will be through this introspection and honesty that you'll find
areas where you can write smaller component which will allow you to realize the oft
spoken benefit in OOP of code reuse.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=c2743618-091a-42f0-86e8-4f883bdbbeee" />
      </body>
      <title>Real Life - Code Reuse</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,c2743618-091a-42f0-86e8-4f883bdbbeee.aspx</guid>
      <link>http://www.timbarcz.com/blog/RealLifeCodeReuse.aspx</link>
      <pubDate>Mon, 09 Mar 2009 18:36:56 GMT</pubDate>
      <description>&lt;p&gt;
A few months ago I &lt;a href="http://devlicio.us/blogs/tim_barcz/archive/2009/01/05/real-life-single-responsibility-principle.aspx"&gt;blogged
about how we're using the single responsibility principle&lt;/a&gt; in our application at
work.&amp;#160; I'm going to make an effort here to write more &amp;quot;Real Life&amp;quot; content.&amp;#160;
Often when a developer read principles or ideas in books, there is disconnect between
what he/she is reading and how an implementation would look in the real world.&amp;#160;
The goal of these &amp;quot;Real Life&amp;quot; scenarios is to show areas where I feel I've
reaped some benefit from following a specific pattern or practice.&amp;#160; This does
not mean that my implementation is the only way or always &amp;quot;book correct&amp;quot;.&amp;#160;
The goal is to act as a bridge (quite possibly a old rickety bridge) between the book
knowledge and the real world.
&lt;/p&gt;
&lt;p&gt;
Moving along...
&lt;/p&gt;
&lt;p&gt;
One of the purported benefits of OOP has always been the abundant reuse of code.&amp;#160;
However, in my experience many applications fail to realize any amount of reuse beyond
copying and pasting between applications.&amp;#160; To really take advantage of code reuse
you have to have small, concise pieces which you can rearrange in order to make a
new behavior.&amp;#160; As a side note, and I want this be clear, many of the principles
of good software development, ie. SOLID, go hand-in-hand.&amp;#160; You can't do one without
the other and the benefits of one cannot be fully realized without the implementation
of the others.&amp;#160; You'll notice that a few sentences ago I said &amp;quot;small, concise
pieces&amp;quot;.&amp;#160; A light bulb may have gone off in your head thinking &amp;quot;Single
Responsibility Principle&amp;quot;, and if it did, bonus points for you.
&lt;/p&gt;
&lt;p&gt;
The key to code reuse is to build your components in a very focused way.&amp;#160; By
doing so, you can add functionality by combining different pieces of you application.
&lt;/p&gt;
&lt;p&gt;
Consider the following code used to authenticate a user into a site:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; btnSubmit_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender,
EventArgs e)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Username
= Server.HtmlEncode(txtUsername.Text);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Password
= Server.HtmlEncode(txtPassword.Text);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; nUserID;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Username
!= &lt;span style="color: #006080"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &amp;amp;&amp;amp; Password != &lt;span style="color: #006080"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (SqlConnection
cnn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SqlConnection(connectionString))&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (SqlCommand
cmd = cnn.CreateCommand())&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; cmd.CommandText
= &lt;span style="color: #006080"&gt;&amp;quot;usp_Login&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; cmd.Parameters.AddWithValue(&lt;span style="color: #006080"&gt;&amp;quot;@Username&amp;quot;&lt;/span&gt;,
Username);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; cmd.Parameters.AddWithValue(&lt;span style="color: #006080"&gt;&amp;quot;@password&amp;quot;&lt;/span&gt;,
password);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(SqlDataReader
reader = cmd.ExecuteReader())&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (reader.Read())&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; nUserId
= Convert.ToInt32(reader[0]); &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (nUserID
&amp;gt; 0)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
if the user has checked the box&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
store his information so he doesn't have to log in again&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (cbRememberMe.Checked)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; FormsAuthentication.SetAuthCookie(nUserID.ToString(), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; FormsAuthentication.SetAuthCookie(nUserID.ToString(), &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 36:&lt;/span&gt; BusinessLogicLayer.User
objUser = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; User(nUserID);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 37:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 38:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
store session variables for later reference;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 39:&lt;/span&gt; Session[&lt;span style="color: #006080"&gt;&amp;quot;UserID&amp;quot;&lt;/span&gt;]
= nUserID;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 40:&lt;/span&gt; Session[&lt;span style="color: #006080"&gt;&amp;quot;Username&amp;quot;&lt;/span&gt;]
= objUser.Username;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 41:&lt;/span&gt; Session[&lt;span style="color: #006080"&gt;&amp;quot;Password&amp;quot;&lt;/span&gt;]
= objUser.Password;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 42:&lt;/span&gt; Session[&lt;span style="color: #006080"&gt;&amp;quot;AccessLevel&amp;quot;&lt;/span&gt;]
= objUser.AccessLevel;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 43:&lt;/span&gt; Session[&lt;span style="color: #006080"&gt;&amp;quot;AccessLevelName&amp;quot;&lt;/span&gt;]
= Enum.GetName(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Utilities.AccessLevel),objUser.AccessLevel);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 44:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 45:&lt;/span&gt; Response.Redirect(&lt;span style="color: #006080"&gt;&amp;quot;~/admin/admin.aspx&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 46:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 47:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 48:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 49:&lt;/span&gt; View
= Views.Failed;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 50:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 51:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 52:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
While the code above is functional, it does way too much.&amp;#160; In this button click
event there are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Call to database explicitly&lt;/li&gt;
&lt;li&gt;
logic to set an authorization cookie&lt;/li&gt;
&lt;li&gt;
Some session variables being set&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Imagine for a moment that you now want to implement a new piece of functionality,
user impersonation.&amp;#160; In order to accomplish this with the path of least resistance,
which developers commonly take, would be to copy/paste all of the login logic to another
UI event somewhere else in the site.&amp;#160; &lt;strong&gt;The issue copy/paste development
is that any future change to the login logic has to be copied again or else the impersonation
feature isn't really impersonating a users experience.&lt;/strong&gt;&amp;#160; &lt;strong&gt;The
insidious nature of copy/paste development is that while often it works, it creates
a brittle application.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In a recent application we were wanting to add user impersonation.&amp;#160; Below is
an example of an implementation of user impersonation.&amp;#160; Adding the feature to
the application was gleefully simple.&amp;#160; The ease in adding impersonation was due
entirely to the proper granularity in our application components.&amp;#160; Seriously,
this is all the code it took:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult
ImpersonateUser(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; id)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; var
authService = Container.Resolve&amp;lt;AuthService&amp;gt;();&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; var
userRepository = Container.Resolve&amp;lt;UserRepository&amp;gt;();&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; var
userToImpersonate = userRepository.GetById(id);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (userToImpersonate
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; authService.SignIn(userToImpersonate);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; RedirectToAction(&lt;span style="color: #006080"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
I did not know we were going to want user impersonation for this application when
we started.&amp;#160; However because we developed the site with certain principles in
mind, we were able to reuse pieces of code in ways not originally intended for added
behavior.&amp;#160; As you can see from the code above, there are no &amp;quot;clever hacks&amp;quot;
or tricks to get impersonation to work.&amp;#160; The beauty of the code above is that
if we change the implementation of &amp;quot;SignIn(user)&amp;quot; all appropriate areas
will follow the same rules since all areas use the same code.
&lt;/p&gt;
&lt;p&gt;
As I'm closing I want to challenge those of you who have read this far to stop yourself
the next time you find yourself copying code from one location to another.&amp;#160; Is
there an abstraction or component you're overlooking?&amp;#160; Think about the long term
and ask if you're really making the wisest decision for the long term health of your
application.&amp;#160; It will be through this introspection and honesty that you'll find
areas where you can write smaller component which will allow you to realize the oft
spoken benefit in OOP of code reuse.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=c2743618-091a-42f0-86e8-4f883bdbbeee" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,c2743618-091a-42f0-86e8-4f883bdbbeee.aspx</comments>
      <category>Principles</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=89065ec0-8d2d-48b8-8803-ad6942160f2c</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=89065ec0-8d2d-48b8-8803-ad6942160f2c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
The following is an email I wrote to the upper management in our company when asked
about things we can do to improve the process and what are the next steps of things
we need to fix in our application.  It remains mostly unedited and contains my
thoughts on what will make our company better when it comes to the software we're
writing.  It wasn't written as a blog post.  It wasn't until after I finished
with it that I realized that it was decent content for a blog post.  You'll find
a very "XP-ish" theme throughout, and that isn't necessarily an accident. 
Hope you enjoy! Please leave feedback if something moves you.
</p>
        <h2>Overview
</h2>
        <p>
The following contains my thoughts on software development at Super Awesome Company.
While I can address the specifics of the project that I see need to be fixed and modified
(the “what”), I am instead going to focus on how these items get fixed.
I am choosing to do this because over time the new website will have bugs that need
to be fixed, enhancements that need to be made, or new features requested. For the
long term health of the project it does not matter so much “what” is implemented
but rather “how”. For that reason I am avoiding specific project level
tasks in this document and speaking at a higher level.
</p>
        <p>
Software has been being developed for over 30 years. While the internet is relatively
young, software development by comparison is not. Super Awesome Company will benefit
from a commitment to good software development practices. Further, it takes a great
deal of commitment and discipline to reap the benefits these practices can bring.
Many of my suggestions are based on these principles, which are principles I have
committed to learning and adopting over the last several years.
</p>
        <p>
The overarching suggestion I would make is make quality the focus. In order to produce
quality, we must slow down. In order to go fast you must go slowly. Sacrificing quality
should never be an option. Consider a car manufacturer who needs to get 100 cars built
in a single day. If they can only build 80 cars a day, is it better for them in the
long run to get 100 cars out the door but have problems or 80 problem free cars? Building
deficient cars carries more expense that just fixing the broken cars, such diminished
brand reputation. If the goal is 100 cars per day, measures should be sought to increase
production while keeping quality high.
</p>
        <p>
We don't need to look too far to see where in a rush we've done something that we've
had to revisit several more times because we were "going fast". We've been
rushed for nearly a year and I can't say that we are any further along than we would
have been had we approached the project more methodically. In some areas we may be
further behind where we would have been since we "made sacrifices" to get
things done, which have ultimately only put us further behind. Again, to go fast we
must go "slow" (methodical). Put another way, quality breeds speed.
</p>
        <p>
          <b>Any process, principle, practice we choose should have quality at its heart. Regardless
of what process, principles, practices we adopt they will only be successful if we
are disciplined enough to follow them. </b>
        </p>
        <h2>Planning
</h2>
        <h3>Requirements 
</h3>
        <p>
Requirements need to be clear and understood by all parties. Before developers set
out to coding we need to have a clear understanding of what the problem is. The developer
is not able to provide a solution until the problem is fully known and understood.
Often the perceived solution to a problem is not the best solution. Failure to fully
understand the problem/scenario results in rework.
</p>
        <h3>Releases
</h3>
        <p>
We need to have planned releases. The timeframe can be discussed and agreed upon by
the team. In order to have successful releases we need to plan each release. Each
release should be broken down into smaller time frames, iterations. During the iteration
the work should be stable for each developer. In other words, they know what they’re
going to work on and accomplish (see requirements above) for any given time period.
</p>
        <h3>Metrics
</h3>
        <p>
We need to be measuring metrics for the purposes of planning. If we get 10 units of
work done each week on average and we have 20 units of work to do, we can easily figure
out what is left to do. Without any metrics gathering we can’t do any planning
and we’re really flying blind. This will also help with project post mortems.
For example, the “web order manager” project was originally estimated
to take a week worth of development effort. Three months later, it is still not finished.
This is a combination of putting someone with limited knowledge of the business estimating
the project, an overly aggressive developer estimate, and having no metric to pull
from on how long something should take.
</p>
        <h3>Flexibility
</h3>
        <p>
We need to be disciplined in the process of building software, but also realize when
the process needs tweaking that we should respond and not be afraid to tweak the process
to meet the needs of our team
</p>
        <h2>Design
</h2>
        <h3>Simplicity
</h3>
        <p>
We should strive for simplicity in our designs. “Clever hacks” are often
not healthy for the life time of the project. Simple designs are easier to understand
and improve upon. Simple designs also allow other developers ease in working on code.
This is much harder to do in practice but it always pays off in the long run.
</p>
        <p>
Design aspects dovetail with testing (later in this document). Typically complex designs
prove to be hard to test. When we write code based on simpler designs we’ll
find that our code is easier to test. We want both, simple designs and easy-to-test
code.
</p>
        <h2>Coding
</h2>
        <h3>Standards
</h3>
        <p>
We should implement a standard for code development. Right now you can find three
different styles/methods of coding in the code base. This makes it hard for developers
to work on code they did not author. Projects I work on outside of work require all
new code meet the standard, otherwise it is rejected until it meets this standard.
As a consumer of these projects I’m always grateful when I can move through
any of the project pieces and the code always looks the same.
</p>
        <h3>Testing
</h3>
        <p>
Given the environment and complexity of the code, we need to require the developers
to be able to test their code in an automated fashion. Visual verification is orders
of magnitude slower than automated testing. Once an automated test is written, it
runs every time. By having a large collection of tests we can makes changes to certain
parts of the application and use existing tests as a safety net to verify nothing
else has broken. We currently have over 1,150 tests (about 30% of code has tests)
that run whenever someone commits code into source control. Those tests run in about
20 seconds. Imagine how long it would take a user to test each of those cases visually
every time a piece of code changes.
</p>
        <p>
Two weeks ago I sat in a meeting adding functionality to shipping and enhancing rules
around shipping hazardous items to Canada while people were finding issues because
of a solid base of tests. Before the meeting was over both issues discovered were
fixed and tests were added for these specific issues so we would be guarded against
this happening again.
</p>
        <h3>Unit Tests
</h3>
        <p>
All code must have unit tests that can be run in an automated fashion. If the code
cannot be unit tested (tested in isolation from other components) it should be restructured
in such a way that it can be tested. Very few pieces of code are truly not testable.
As such we should have very few areas in our code base which are not tested.
</p>
        <h3>Proving Bug Fixes Through Tests
</h3>
        <p>
When bug is found a test should be written before any attempt to fix the bug. This
test proves to the developer the bug exists but secondly gives the developer a marker
to know when the bug is fixed. As a benefit, this new test acts as a guard against
this particular bug ever happening again. This test, when first written, should fail
because the developer has not fixed the bug yet. The developer should then work to
make the test pass, and by extension fixing the bug. The cost of adding the test is
very small when compared against having the test guard against this condition ever
happening again. 
</p>
        <h3>Code Coverage
</h3>
        <p>
We should implement a standard for new code coverage, code that is tested by an automated
test. I would recommend somewhere in the 80%-90% range for code coverage. In order
to write tests the developers will be forced to think about their code a bit more
thoroughly.
</p>
        <h3>Pair Programming
</h3>
        <p>
We should adopt pair programming as a method to both increase shared knowledge but
also as a means to quality. Pair programming is two developers sitting at one computer
for a period of time while code is written. From the outside it may seem impractical
to devote two developers to a single computer, thinking it is inefficient. Industry
studies however show that code written in a pair has a four-fold benefit:
</p>
        <ol>
          <li>
15% less code– Studies showed that less code is written in order to implement
the same functionality. Less code means less to maintain and understand. Less code
is also typically simpler. 
</li>
          <li>
Less bugs – Developers, when working in pairs, can catch each other’s
bugs before they ever make it to production. We therefore save time that it would
take to fix the bugs that would otherwise go undiscovered. 
</li>
          <li>
Shared domain knowledge – When “pairing”, each developer is training
the other and sharing knowledge and rules around the business. This avoids silos and
situations where only one person knows the code. 
</li>
          <li>
Increased Skill – When “pairing”, design, coding, and testing techniques
are transferred between developers. This is often why many development shops pair
their senior developers with junior developers; to raise the skill level of the junior
developer. 
</li>
        </ol>
        <h3>Collective Code Ownership
</h3>
        <p>
No one person should be a silo/bottleneck for any area of the code. Any person should
be free to make suggestions, fix bugs, or refactor any part of the code. Pair programming
(see above) is one tool which seeks to address this.
</p>
        <h2>Conclusion
</h2>
        <p>
While the above recommendations may seem like a lot, the above items all really go
hand-in-hand. Consider:
</p>
        <ul>
          <li>
            <b>Collective Code Ownership</b> is had through <b>Pair Programming</b></li>
          <li>
            <b>Standards</b> are enforced by developers when <b>Pair Programming</b></li>
          <li>
Writing <b>Unit Tests</b> typically leads to <b>Simple Designs</b></li>
          <li>
A commitment to <b>Code Coverage</b> leads to more <b>Unit Tests</b></li>
          <li>
Gathering <b>Metrics</b> leads to better estimates and <b>Release </b>planning 
</li>
        </ul>
        <p>
Adopting the above will move us in a positive direction and ensure that all projects
coming from our department will be of ever heightening quality. Once the quality bar
is set, then we will begin to see the pace pick up; Remember, quality is a prerequisite
to speed.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=89065ec0-8d2d-48b8-8803-ad6942160f2c" />
      </body>
      <title>Improving Software Process - A Letter to Upper Management</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</guid>
      <link>http://www.timbarcz.com/blog/ImprovingSoftwareProcessALetterToUpperManagement.aspx</link>
      <pubDate>Thu, 05 Mar 2009 18:48:42 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The following is an email I wrote to the upper management in our company when asked
about things we can do to improve the process and what are the next steps of things
we need to fix in our application.&amp;#160; It remains mostly unedited and contains my
thoughts on what will make our company better when it comes to the software we're
writing.&amp;#160; It wasn't written as a blog post.&amp;#160; It wasn't until after I finished
with it that I realized that it was decent content for a blog post.&amp;#160; You'll find
a very &amp;quot;XP-ish&amp;quot; theme throughout, and that isn't necessarily an accident.&amp;#160;
Hope you enjoy! Please leave feedback if something moves you.
&lt;/p&gt;
&lt;h2&gt;Overview
&lt;/h2&gt;
&lt;p&gt;
The following contains my thoughts on software development at Super Awesome Company.
While I can address the specifics of the project that I see need to be fixed and modified
(the &amp;#8220;what&amp;#8221;), I am instead going to focus on how these items get fixed.
I am choosing to do this because over time the new website will have bugs that need
to be fixed, enhancements that need to be made, or new features requested. For the
long term health of the project it does not matter so much &amp;#8220;what&amp;#8221; is implemented
but rather &amp;#8220;how&amp;#8221;. For that reason I am avoiding specific project level
tasks in this document and speaking at a higher level.
&lt;/p&gt;
&lt;p&gt;
Software has been being developed for over 30 years. While the internet is relatively
young, software development by comparison is not. Super Awesome Company will benefit
from a commitment to good software development practices. Further, it takes a great
deal of commitment and discipline to reap the benefits these practices can bring.
Many of my suggestions are based on these principles, which are principles I have
committed to learning and adopting over the last several years.
&lt;/p&gt;
&lt;p&gt;
The overarching suggestion I would make is make quality the focus. In order to produce
quality, we must slow down. In order to go fast you must go slowly. Sacrificing quality
should never be an option. Consider a car manufacturer who needs to get 100 cars built
in a single day. If they can only build 80 cars a day, is it better for them in the
long run to get 100 cars out the door but have problems or 80 problem free cars? Building
deficient cars carries more expense that just fixing the broken cars, such diminished
brand reputation. If the goal is 100 cars per day, measures should be sought to increase
production while keeping quality high.
&lt;/p&gt;
&lt;p&gt;
We don't need to look too far to see where in a rush we've done something that we've
had to revisit several more times because we were &amp;quot;going fast&amp;quot;. We've been
rushed for nearly a year and I can't say that we are any further along than we would
have been had we approached the project more methodically. In some areas we may be
further behind where we would have been since we &amp;quot;made sacrifices&amp;quot; to get
things done, which have ultimately only put us further behind. Again, to go fast we
must go &amp;quot;slow&amp;quot; (methodical). Put another way, quality breeds speed.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Any process, principle, practice we choose should have quality at its heart. Regardless
of what process, principles, practices we adopt they will only be successful if we
are disciplined enough to follow them. &lt;/b&gt;
&lt;/p&gt;
&lt;h2&gt;Planning
&lt;/h2&gt;
&lt;h3&gt;Requirements 
&lt;/h3&gt;
&lt;p&gt;
Requirements need to be clear and understood by all parties. Before developers set
out to coding we need to have a clear understanding of what the problem is. The developer
is not able to provide a solution until the problem is fully known and understood.
Often the perceived solution to a problem is not the best solution. Failure to fully
understand the problem/scenario results in rework.
&lt;/p&gt;
&lt;h3&gt;Releases
&lt;/h3&gt;
&lt;p&gt;
We need to have planned releases. The timeframe can be discussed and agreed upon by
the team. In order to have successful releases we need to plan each release. Each
release should be broken down into smaller time frames, iterations. During the iteration
the work should be stable for each developer. In other words, they know what they&amp;#8217;re
going to work on and accomplish (see requirements above) for any given time period.
&lt;/p&gt;
&lt;h3&gt;Metrics
&lt;/h3&gt;
&lt;p&gt;
We need to be measuring metrics for the purposes of planning. If we get 10 units of
work done each week on average and we have 20 units of work to do, we can easily figure
out what is left to do. Without any metrics gathering we can&amp;#8217;t do any planning
and we&amp;#8217;re really flying blind. This will also help with project post mortems.
For example, the &amp;#8220;web order manager&amp;#8221; project was originally estimated
to take a week worth of development effort. Three months later, it is still not finished.
This is a combination of putting someone with limited knowledge of the business estimating
the project, an overly aggressive developer estimate, and having no metric to pull
from on how long something should take.
&lt;/p&gt;
&lt;h3&gt;Flexibility
&lt;/h3&gt;
&lt;p&gt;
We need to be disciplined in the process of building software, but also realize when
the process needs tweaking that we should respond and not be afraid to tweak the process
to meet the needs of our team
&lt;/p&gt;
&lt;h2&gt;Design
&lt;/h2&gt;
&lt;h3&gt;Simplicity
&lt;/h3&gt;
&lt;p&gt;
We should strive for simplicity in our designs. &amp;#8220;Clever hacks&amp;#8221; are often
not healthy for the life time of the project. Simple designs are easier to understand
and improve upon. Simple designs also allow other developers ease in working on code.
This is much harder to do in practice but it always pays off in the long run.
&lt;/p&gt;
&lt;p&gt;
Design aspects dovetail with testing (later in this document). Typically complex designs
prove to be hard to test. When we write code based on simpler designs we&amp;#8217;ll
find that our code is easier to test. We want both, simple designs and easy-to-test
code.
&lt;/p&gt;
&lt;h2&gt;Coding
&lt;/h2&gt;
&lt;h3&gt;Standards
&lt;/h3&gt;
&lt;p&gt;
We should implement a standard for code development. Right now you can find three
different styles/methods of coding in the code base. This makes it hard for developers
to work on code they did not author. Projects I work on outside of work require all
new code meet the standard, otherwise it is rejected until it meets this standard.
As a consumer of these projects I&amp;#8217;m always grateful when I can move through
any of the project pieces and the code always looks the same.
&lt;/p&gt;
&lt;h3&gt;Testing
&lt;/h3&gt;
&lt;p&gt;
Given the environment and complexity of the code, we need to require the developers
to be able to test their code in an automated fashion. Visual verification is orders
of magnitude slower than automated testing. Once an automated test is written, it
runs every time. By having a large collection of tests we can makes changes to certain
parts of the application and use existing tests as a safety net to verify nothing
else has broken. We currently have over 1,150 tests (about 30% of code has tests)
that run whenever someone commits code into source control. Those tests run in about
20 seconds. Imagine how long it would take a user to test each of those cases visually
every time a piece of code changes.
&lt;/p&gt;
&lt;p&gt;
Two weeks ago I sat in a meeting adding functionality to shipping and enhancing rules
around shipping hazardous items to Canada while people were finding issues because
of a solid base of tests. Before the meeting was over both issues discovered were
fixed and tests were added for these specific issues so we would be guarded against
this happening again.
&lt;/p&gt;
&lt;h3&gt;Unit Tests
&lt;/h3&gt;
&lt;p&gt;
All code must have unit tests that can be run in an automated fashion. If the code
cannot be unit tested (tested in isolation from other components) it should be restructured
in such a way that it can be tested. Very few pieces of code are truly not testable.
As such we should have very few areas in our code base which are not tested.
&lt;/p&gt;
&lt;h3&gt;Proving Bug Fixes Through Tests
&lt;/h3&gt;
&lt;p&gt;
When bug is found a test should be written before any attempt to fix the bug. This
test proves to the developer the bug exists but secondly gives the developer a marker
to know when the bug is fixed. As a benefit, this new test acts as a guard against
this particular bug ever happening again. This test, when first written, should fail
because the developer has not fixed the bug yet. The developer should then work to
make the test pass, and by extension fixing the bug. The cost of adding the test is
very small when compared against having the test guard against this condition ever
happening again. 
&lt;/p&gt;
&lt;h3&gt;Code Coverage
&lt;/h3&gt;
&lt;p&gt;
We should implement a standard for new code coverage, code that is tested by an automated
test. I would recommend somewhere in the 80%-90% range for code coverage. In order
to write tests the developers will be forced to think about their code a bit more
thoroughly.
&lt;/p&gt;
&lt;h3&gt;Pair Programming
&lt;/h3&gt;
&lt;p&gt;
We should adopt pair programming as a method to both increase shared knowledge but
also as a means to quality. Pair programming is two developers sitting at one computer
for a period of time while code is written. From the outside it may seem impractical
to devote two developers to a single computer, thinking it is inefficient. Industry
studies however show that code written in a pair has a four-fold benefit:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
15% less code&amp;#8211; Studies showed that less code is written in order to implement
the same functionality. Less code means less to maintain and understand. Less code
is also typically simpler. 
&lt;/li&gt;
&lt;li&gt;
Less bugs &amp;#8211; Developers, when working in pairs, can catch each other&amp;#8217;s
bugs before they ever make it to production. We therefore save time that it would
take to fix the bugs that would otherwise go undiscovered. 
&lt;/li&gt;
&lt;li&gt;
Shared domain knowledge &amp;#8211; When &amp;#8220;pairing&amp;#8221;, each developer is training
the other and sharing knowledge and rules around the business. This avoids silos and
situations where only one person knows the code. 
&lt;/li&gt;
&lt;li&gt;
Increased Skill &amp;#8211; When &amp;#8220;pairing&amp;#8221;, design, coding, and testing techniques
are transferred between developers. This is often why many development shops pair
their senior developers with junior developers; to raise the skill level of the junior
developer. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Collective Code Ownership
&lt;/h3&gt;
&lt;p&gt;
No one person should be a silo/bottleneck for any area of the code. Any person should
be free to make suggestions, fix bugs, or refactor any part of the code. Pair programming
(see above) is one tool which seeks to address this.
&lt;/p&gt;
&lt;h2&gt;Conclusion
&lt;/h2&gt;
&lt;p&gt;
While the above recommendations may seem like a lot, the above items all really go
hand-in-hand. Consider:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Collective Code Ownership&lt;/b&gt; is had through &lt;b&gt;Pair Programming&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Standards&lt;/b&gt; are enforced by developers when &lt;b&gt;Pair Programming&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
Writing &lt;b&gt;Unit Tests&lt;/b&gt; typically leads to &lt;b&gt;Simple Designs&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
A commitment to &lt;b&gt;Code Coverage&lt;/b&gt; leads to more &lt;b&gt;Unit Tests&lt;/b&gt; 
&lt;/li&gt;
&lt;li&gt;
Gathering &lt;b&gt;Metrics&lt;/b&gt; leads to better estimates and &lt;b&gt;Release &lt;/b&gt;planning 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Adopting the above will move us in a positive direction and ensure that all projects
coming from our department will be of ever heightening quality. Once the quality bar
is set, then we will begin to see the pace pick up; Remember, quality is a prerequisite
to speed.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=89065ec0-8d2d-48b8-8803-ad6942160f2c" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,89065ec0-8d2d-48b8-8803-ad6942160f2c.aspx</comments>
      <category>Agile</category>
      <category>Musings</category>
      <category>Principles</category>
    </item>
    <item>
      <trackback:ping>http://www.timbarcz.com/blog/Trackback.aspx?guid=d4212f64-d401-4ddd-a344-54902927b35f</trackback:ping>
      <pingback:server>http://www.timbarcz.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.timbarcz.com/blog/PermaLink,guid,d4212f64-d401-4ddd-a344-54902927b35f.aspx</pingback:target>
      <dc:creator>Tim Barcz</dc:creator>
      <wfw:comment>http://www.timbarcz.com/blog/CommentView,guid,d4212f64-d401-4ddd-a344-54902927b35f.aspx</wfw:comment>
      <wfw:commentRss>http://www.timbarcz.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d4212f64-d401-4ddd-a344-54902927b35f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
S.O.L.I.D. principles seem to be a hot topic.  The guys over at <a href="http://www.lostechies.com">LosTechies.com</a> explored
it last year in <a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx">March
as their topic of the month</a> and did a great job of it. I know when I read blogs
I enjoy when different authors post on similar topics.  I find that often the
different examples and explanations paint a clearer picture than can be had with only
one example.  I'd like to share an area where we use the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single
Responsibility Principle</a> (SRP) in our application
</p>
        <p>
Note: The "aha" moment won't be some thrilling display of how we averted
some disastrous bug or how we eliminated some thousands of lines of code.  It
will be much more subtle but that's ok.  A good design should strive for an element
of simplicity.  <strong>Great design is asking to hear the answer to a riddle
and then thinking, "duh!  of course"</strong>  When you hear the
answer you realize how "obvious" it was.
</p>
        <h2>Background
</h2>
        <p>
In our application we queue all emails to be handled by a different process since
sending email is a blocking call which slows your response times (Note to BCL junkies:
yes I know there is a SendAsync method).  There are a few instances in our application
where we want email to be sent right away and not queued. An example of this would
be a confirmation email for a new account or a password reset request.
</p>
        <h2>The Fix
</h2>
        <p>
We already had a QueuedEmailService class so adhering to SRP, I built a RealTimeEmailService
class whose job, and only job, it is to send the email right away.  Thinking
of responsibility driven design, classes:
</p>
        <ul>
          <li>
Know things 
</li>
          <li>
Do things 
</li>
          <li>
Make decisions 
</li>
        </ul>
        <p>
With that in mind I needed another class to make the decision to when to send the
email through the RealTimeEmailService or when to use the QueuedEmailService:
</p>
        <blockquote>
          <p>
(At this point some of you might be reading thinking how easy of a problem this would
be to solve and you're quite right.  What I want to point out is not the problem,
but how one solves the problem.  Nearly anyone could've gone into the QueuedEmailService
and added an if statement and sent emails real-time if that is what is needed, thus
ignoring SRP.  By lumping all of the work together you aren't building object
oriented software...sorry.  And while you might be okay with that and you're
software WILL work, you run the risk of more maintenance issues and modularity problems).
</p>
        </blockquote>
        <p>
Here's what a quick summary of what I've got:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 1:</span>
              <span style="color: #0000ff">public</span> QueuedEmailService
: IEmailService</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 3:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> Send(...)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>
              <span style="color: #008000">//
add to some queue</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 7:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 9:</span>
              <span style="color: #0000ff">public</span> RealTimeEmailService
: IEmailService</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 11:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> Send(...)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 12:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 13:</span>
              <span style="color: #008000">//
send right now</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 14:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 15:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 16:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 17:</span>
              <span style="color: #0000ff">public</span> PriorityBasedEmailService
: IEmailService</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 18:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 19:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">void</span> Send(...)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 20:</span> {</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 21:</span>
              <span style="color: #0000ff">if</span> (priority
== MailPriority.High)</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 22:</span>
              <span style="color: #008000">//
send using realtime service</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 23:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 24:</span>
              <span style="color: #008000">//
send using queued service</span>
            </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 25:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 26:</span> }</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">
              <span style="color: #606060"> 27:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 28:</span>  </pre>
          </div>
        </div>
        <p>
I know many people who would look at the code above and think it is possibly overkill. 
I would disagree for a few reasons:
</p>
        <ul>
          <li>
Each class does only one thing.  If we have a problem with some piece of functionality
it is much easier to debug.  Each of the three classes above in their full implementation
will fit on your screen without the need for scrolling.  It's quite refreshing. 
</li>
          <li>
Modular design - since the application only knows that it's dealing with an IEmailService
I can easily swap out implementations.  For example, if we decide that we want
all emails to be sent real-time, I just change how I've configured Windsor (my IoC
container) and it works, because I have a concrete class which sends real-time. 
If you were to combine all of your code into one class, you'd have to go back and
change your code and go through the pain of deployment. 
</li>
          <li>
Open-Closed principle - since each of the classes only have only one thing they do,
I can more easily say they are closed for modification, reducing the chance that I
introduce a bug later on.  If you put this code into one big method, you can
change the code to meet your new needs, but each change introduces the possibility
of introducing a bug. 
</li>
        </ul>
        <p>
There are cases when a design can go overboard, but for the vast majority of cases
this simply isn't the case.  I'd rather see a solution where someone has gone
too far than what I typically see in classes that do it all, with no clear responsibility.
</p>
        <p>
I hope this helps augment your knowledge of SRP.  If you're still a little fuzzy
on SRP and what it is, let me know, I'd love to discuss it with you.
</p>
        <img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=d4212f64-d401-4ddd-a344-54902927b35f" />
      </body>
      <title>Real Life Single Responsibility Principle</title>
      <guid isPermaLink="false">http://www.timbarcz.com/blog/PermaLink,guid,d4212f64-d401-4ddd-a344-54902927b35f.aspx</guid>
      <link>http://www.timbarcz.com/blog/RealLifeSingleResponsibilityPrinciple.aspx</link>
      <pubDate>Mon, 05 Jan 2009 20:32:59 GMT</pubDate>
      <description>&lt;p&gt;
S.O.L.I.D. principles seem to be a hot topic.&amp;#160; The guys over at &lt;a href="http://www.lostechies.com"&gt;LosTechies.com&lt;/a&gt; explored
it last year in &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx"&gt;March
as their topic of the month&lt;/a&gt; and did a great job of it. I know when I read blogs
I enjoy when different authors post on similar topics.&amp;#160; I find that often the
different examples and explanations paint a clearer picture than can be had with only
one example.&amp;#160; I'd like to share an area where we use the &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single
Responsibility Principle&lt;/a&gt; (SRP) in our application
&lt;/p&gt;
&lt;p&gt;
Note: The &amp;quot;aha&amp;quot; moment won't be some thrilling display of how we averted
some disastrous bug or how we eliminated some thousands of lines of code.&amp;#160; It
will be much more subtle but that's ok.&amp;#160; A good design should strive for an element
of simplicity.&amp;#160; &lt;strong&gt;Great design is asking to hear the answer to a riddle
and then thinking, &amp;quot;duh!&amp;#160; of course&amp;quot;&lt;/strong&gt;&amp;#160; When you hear the
answer you realize how &amp;quot;obvious&amp;quot; it was.
&lt;/p&gt;
&lt;h2&gt;Background
&lt;/h2&gt;
&lt;p&gt;
In our application we queue all emails to be handled by a different process since
sending email is a blocking call which slows your response times (Note to BCL junkies:
yes I know there is a SendAsync method).&amp;#160; There are a few instances in our application
where we want email to be sent right away and not queued. An example of this would
be a confirmation email for a new account or a password reset request.
&lt;/p&gt;
&lt;h2&gt;The Fix
&lt;/h2&gt;
&lt;p&gt;
We already had a QueuedEmailService class so adhering to SRP, I built a RealTimeEmailService
class whose job, and only job, it is to send the email right away.&amp;#160; Thinking
of responsibility driven design, classes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Know things 
&lt;/li&gt;
&lt;li&gt;
Do things 
&lt;/li&gt;
&lt;li&gt;
Make decisions 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
With that in mind I needed another class to make the decision to when to send the
email through the RealTimeEmailService or when to use the QueuedEmailService:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
(At this point some of you might be reading thinking how easy of a problem this would
be to solve and you're quite right.&amp;#160; What I want to point out is not the problem,
but how one solves the problem.&amp;#160; Nearly anyone could've gone into the QueuedEmailService
and added an if statement and sent emails real-time if that is what is needed, thus
ignoring SRP.&amp;#160; By lumping all of the work together you aren't building object
oriented software...sorry.&amp;#160; And while you might be okay with that and you're
software WILL work, you run the risk of more maintenance issues and modularity problems).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Here's what a quick summary of what I've got:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; QueuedEmailService
: IEmailService&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Send(...)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
add to some queue&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; RealTimeEmailService
: IEmailService&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Send(...)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
send right now&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; PriorityBasedEmailService
: IEmailService&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Send(...)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (priority
== MailPriority.High)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
send using realtime service&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
send using queued service&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
I know many people who would look at the code above and think it is possibly overkill.&amp;#160;
I would disagree for a few reasons:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Each class does only one thing.&amp;#160; If we have a problem with some piece of functionality
it is much easier to debug.&amp;#160; Each of the three classes above in their full implementation
will fit on your screen without the need for scrolling.&amp;#160; It's quite refreshing. 
&lt;/li&gt;
&lt;li&gt;
Modular design - since the application only knows that it's dealing with an IEmailService
I can easily swap out implementations.&amp;#160; For example, if we decide that we want
all emails to be sent real-time, I just change how I've configured Windsor (my IoC
container) and it works, because I have a concrete class which sends real-time.&amp;#160;
If you were to combine all of your code into one class, you'd have to go back and
change your code and go through the pain of deployment. 
&lt;/li&gt;
&lt;li&gt;
Open-Closed principle - since each of the classes only have only one thing they do,
I can more easily say they are closed for modification, reducing the chance that I
introduce a bug later on.&amp;#160; If you put this code into one big method, you can
change the code to meet your new needs, but each change introduces the possibility
of introducing a bug. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There are cases when a design can go overboard, but for the vast majority of cases
this simply isn't the case.&amp;#160; I'd rather see a solution where someone has gone
too far than what I typically see in classes that do it all, with no clear responsibility.
&lt;/p&gt;
&lt;p&gt;
I hope this helps augment your knowledge of SRP.&amp;#160; If you're still a little fuzzy
on SRP and what it is, let me know, I'd love to discuss it with you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.timbarcz.com/blog/aggbug.ashx?id=d4212f64-d401-4ddd-a344-54902927b35f" /&gt;</description>
      <comments>http://www.timbarcz.com/blog/CommentView,guid,d4212f64-d401-4ddd-a344-54902927b35f.aspx</comments>
      <category>Principles</category>
    </item>
  </channel>
</rss>