"a place for my stuff..." -- a blog by John Nelson

 

 
 

Frankly, I’m surprised that it took until page 12 of the jQuery Cookbook to mention putting JavaScript at the bottom of the page before the closing </body> tag.  Pages load faster with the JavaScript at the bottom, and it removes the need to use the ready() function.  This is great advice.  Using a ContentPlaceHolder helps keep the scripts in their optimal location.

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
  <title>
    <asp:ContentPlaceHolder ID="TitleContent" runat="server" />
  </title>
</head>
<body>
  <div>
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
  </div>
  <script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
  <!-- ScriptContent for putting JavaScript at the bottom of every page -->
  <asp:ContentPlaceHolder ID="ScriptContent" runat="server" />
</body>
</html>

Then, I’m able to include an <asp:Content> element inside of my View and use it freely.  Notice that I was able to include jquery.min.js above the ContentPlaceHolder, which means jQuery will already be warm for any JavaScript in my ScriptContent.

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
  About
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
  <h2>About</h2>
  <div class="about-message"></div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ScriptContent" runat="server">
  <script type="text/javascript">
    $('.about-message').text("This is the About Page!");
  </script>
</asp:Content>


Another added perk to this ContentPlaceHolder approach is that it lets me include other JavaScript libraries that individual Views might depend on.  Pretty simple, but I hope you enjoy it!

Thursday, January 21, 2010 10:00:41 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.NET MVC | JavaScript | jQuery

cookbook I received an email today, notifying me that I have won the mega millions.  All I have to do is send my social security number, all credit card numbers, bank account numbers, a photo copy of my driver’s license and birth certificate, and viola!

Okay so it wasn’t mega millions, but I did actually win something.  A couple of days ago I saw tweet about a contest to win a free copy of the jQuery Cookbook.  Winners were to be chosen at random, and all I had to do to enter was reply to a blog post with something silly about why I wanted the jQuery Cookbook.  The winners were announced, and I was one of the lucky five selected at random.

That’s one more book on my list to read.  I can’t wait.

Friday, December 11, 2009 10:25:18 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Books | jQuery

Craig Shoemaker posted a blog entry yesterday, and point number six was about using a custom attribute to ease QueryString pains.  At my current job I work with ASP.NET WebForms, and I knew exactly what he was talking about.  I thought this was an awesome idea, and followed his link to a VB article on code project.  I converted the VB code to C#, and made some slight changes.

The Goal

Eliminate “keyboard slapping” and provide some robust functionality at the same time.  In other words, we’re trying to solve the following problems:

  1. Try to eliminate the need to access Request.QueryString directly.
  2. Try to make the implementation as streamlined as possible.
  3. Account for some possible use cases like:
    • Special Parameter Names
    • Synonymous Parameter Names

Out With The Old

As Craig pointed out in his blog, we’ve all written the same mindless QueryString code over and over.  It always amounts to the same boiler plate code, which involves indexing into the Request.QueryString object using a string key and safeguarding the entire operation.  Don’t repeat yourself.

protected string UserName

{

    get

    {

        if (Request.QueryString["UserName"] != null)

            return Request.QueryString["UserName"].ToString();

        return string.Empty;

    }

}


Would become:

[QueryStringValue]

public int UserName { get; set; }


AutoValueAttribute

I started with an abstract base class for this implementation.  The idea is that the attribute will have keys, and a way to get a value from those keys.  The idea behind using an abstract base is that we may implement other versions of the AutoValueAttribute later on.

//-----------------------------------------------------------------------------

/// <summary>

///     AutoValueAttribute

/// </summary>

public abstract class AutoValueAttribute : Attribute

{

    //-------------------------------------------------------------------------

    /// <summary>

    ///     Gets a collection of Keys to be used for

    ///     retrieving a value for the property.

    /// </summary>

    public abstract ICollection<string> Keys { get; protected set; }

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///     Uses its keys to find a value.

    /// </summary>

    /// <returns></returns>

    public abstract object GetValue();

}


The QueryStringValue Attribute

Any property we wish to set from a QueryString parameter can be decorated with a QueryStringValue attribute.  The implementation is simple, supporting three specific use cases.  This attribute just holds onto values that we can use for processing later.

//-----------------------------------------------------------------------------

/// <summary>

///        QueryStringValue Attribute

/// </summary>

public class QueryStringValueAttribute : AutoValueAttribute

{

    #region Properties

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///        Gets a collection of Keys

    /// </summary>

    public override ICollection<string> Keys { get; protected set; }

 

    #endregion

 

    #region Constructors

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///        Constructor;  Defaults to property name

    /// </summary>

    public QueryStringValueAttribute()

    {

        Keys = new List<string>();

    }

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///        Constructor;  Specifies a single key

    /// </summary>

    /// <param name="key"></param>

    public QueryStringValueAttribute(string key)

    {

        Keys = new List<string> { key };

    }

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///        Constructor;  Specifies many keys

    /// </summary>

    /// <param name="keys"></param>

    public QueryStringValueAttribute(string[] keys)

    {

        Keys = new List<string>(keys);

    }

 

    #endregion

 

    #region Methods

 

    //-------------------------------------------------------------------------

    /// <summary>

    ///     Iterates through all of the Keys, and returns the first match

    /// </summary>

    /// <returns></returns>

    public override object GetValue()

    {

        object value = null;

 

        foreach (string key in Keys)

        {

            value = HttpContext.Current.Request.QueryString[key];

 

            if (value != null)

                break;

        }

 

        return value;

    }

 

    #endregion

}


I expanded on the concept of Keys while converting the VB code.  It originally used a string property named QueryStringParameter.  While this was straight forward, I thought it might be beneficial to build in the ability to handle many parameter names by using a list instead.  A simple use case is changing the parameter name, but wishing to maintain backwards compatibility.

The default constructor doesn’t specify a name.  Instead, the target property’s name will be used as the QueryString parameter key.  A second constructor accepts a single string.  The last constructor accepts an array of strings.  In this case, the first match is the one that will be used.

Calling the GetValue method will iterate through the list of keys, indexing into Request.QueryString until it finds a value.  There is one important caveat to be aware of, and that is if the default constructor was used, the list of keys will be empty.  If only attributes knew exactly which property they were decorating, it wouldn’t be a problem.  The code that consumes this method must add the property name if the attribute contains no other keys (more on that shortly).

Processing The Attributes Via Reflection

In order to make this widely available in an ASP.NET application, I created the processing method as a generic extension method.  The method is called ProcessAttributes.  It uses a constraint to limit it to System.Web.UI.Control objects.

//---------------------------------------------------------------------

/// <summary>

///     Processes all attributes

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="ui"></param>

public static void ProcessAttributes<T>(this T ui)

    where T : System.Web.UI.Control

{

    const BindingFlags flags = BindingFlags.NonPublic

        | BindingFlags.Public | BindingFlags.Instance;

 

    PropertyInfo[] properties = ui.GetType().GetProperties(flags);

 

    foreach (PropertyInfo property in properties)

    {

        var att = property.GetCustomAttributes(true)

                          .OfType<AutoValueAttribute>()

                          .FirstOrDefault();

 

        if (att == null)

            continue;

 

        object value = GetValue(property, att);

 

        SetValue(ui, property, value);

    }

}


BindingFlags are used to get the properties of the Page.  Then, we iterate through each one.  Using the first QueryStringValueAttribute of each property,  we proceed to get the QueryString value, and set the property.

//---------------------------------------------------------------------

/// <summary>

///     Gets a value from the AutoValueAttribute

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="ui"></param>

/// <param name="request"></param>

/// <param name="field"></param>

/// <param name="att"></param>

/// <returns></returns>

private static object GetValue(PropertyInfo property, AutoValueAttribute att)

{

    if (att.Keys.Count == 0)

        att.Keys.Add(property.Name);

 

    return att.GetValue();

}


As previously noted, there is a caveat for calling the GetValue method.  It iterates the attribute’s Keys property until it can get a value out of the QueryString.  If no key was specified in the attribute constructor, it will have a Keys.Count of 0.  In this case, we need to add the property’s name to the list of Keys.

//---------------------------------------------------------------------

/// <summary>

///     Sets the property with the extracted value

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="ui"></param>

/// <param name="property"></param>

/// <param name="value"></param>

private static void SetValue(System.Web.UI.Control ui, PropertyInfo property, object value)

{

    try

    {

        object convertedValue = Convert.ChangeType(value, property.PropertyType);

        property.SetValue(ui, convertedValue, null);

    }

    catch

    {

        // Log the error and continue gracefully

        // Allow business logic to care about the real value.

        // The job here is to make the best possible effort to

        // set values from the QueryString.

        return;

    }

}


The the SetField method attempts to convert the value to the property’s data type.  There’s a strong chance that this conversion can fail.  While this is probably the most arguable aspect of the whole endeavor, I think that validation is not necessary at this point, and would be better suited for later in the life cycle of the page.  The main goal of this code is to set properties on the page to values in the QueryString.  It seems a little silly to absorb an exception, but it was meant to keep the attribute from getting in your way.

Conclusion

The barrier to entry is really small for making this feature completely streamlined.  I created a new class to derive my Pages from, called PageBase (creative, right?).  It descends from System.Web.UI.Page, and overrides OnPreInit.

//--------------------------------------------------------------------------

/// <summary>

///        Some Page Base Class

/// </summary>

public class PageBase : Page

{

    protected override void OnPreInit(EventArgs e)

    {

        base.OnPreInit(e);

        this.ProcessAttributes();

    }

}


By calling ProcessAttributes in OnPreInit, derived classes get this functionality almost completely for free.  Even if you find a need to override OnPreInit in a descending class, base.OnPreInit(e) will keep that going.  The nice part about all of this is how it finally works:

[QueryStringValue]

protected string Value1 { get; set; }

 

[QueryStringValue]

protected string Value2 { get; set; }

 

[QueryStringValue("ThirdValue")]

public string Value3 { get; set; }

 

[QueryStringValue(new[] { "FourthValue", "Value4" })]

public string Value4 { get; set; }

 

[QueryStringValue]

public int Value5 { get; set; }

 

//-------------------------------------------------------------------------

/// <summary>

///        Page Load Event

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    Label1.Text = string.Format("Value1: [{0}], Value2: [{1}], Value3: [{2}], Value4: [{3}], Value5: [{4}]", Value1, Value2, Value3, Value4, Value5);

}


Using this approach to QueryStrings greatly reduces the amount of code you need to write each time a property needs to access the QueryString.  It’s robust because it supports multiple keys, and even works against public and protected properties.  It does its best to stay out of your way while you’re coding, and hopefully shaves off a few keystrokes here and there.

Going The Extra Mile

Craig pointed out that there are other possible uses for this approach, like Form Elements, Cache and Session.  I have looked at trying this out, but found it to be much more difficult.  Things get hairy when you need to save values.  I played with the idea of a [SessionValue] attribute, and even had some success.  I could provide an identical experience to the [QueryStringValue] attribute, where values are automatically assigned.  The problem is that Session variables often change over the course of a request.  If you’re using auto properties, the value just sits there.  That’s where I came up with a PersistableValueAttribute, deriving from AutoValueAttribute.  It added to the AutoValueAttribute functionality, because it provided a Persist method for saving off the value.  I tried to use this in the OnPreRenderComplete event, and it worked.  So it worked, what’s the problem?

Sometimes it is unavoidable, but you just have to tuck your ego in your back pocket and do what you have to do.  The situation I’m talking about is when the request comes in, you change a session variable, more code runs, and then other code uses the same session variable (knowing that it was changed) during the same request.  In the effort I described in the previous paragraph the [SessionValue] property isn’t persisted until the very last second.  That creates a problem when another code depends on that value before it’s persisted.  Oops.  Added complexity isn’t very fun.  I haven’t given up on the thought, but it’s a problem for another day.

Saturday, December 05, 2009 11:12:13 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.NET | Attributes | AutoValueAttribute | C# | Craig Shoemaker | QueryString

imageProps go to Rob Conery and all of the folks at TekPub.  I think what they are doing with learning videos is a great effort, and will go a long way in spreading the word and know-how to the developer community.  Most of the videos require a subscription, with the occasional free series.  The first video in the Concepts series covers Dependency Injection and Inversion of Control.

The video introduces Ninject, “…the illegitimate brainchild of Nate Kohari.”  In all seriousness, it’s a great framework for Dependency Injection.  The first part of the video walks through a simple example, and then refactors it for Dependency Injection by extracting interfaces.  This is great, but the real trick is the Inversion of Control.  Using Ninject, a constructor can be decorated with an [Inject] attribute.  This allows Ninject to know where to use its magic.

The DI framework uses a concept of Kernels, which are instantiated with Modules, and Modules are where dependencies are defined.  In the example, a new class is created that inherits from NinjectModule.  The Load method is overridden, and some neat syntax is used to describe relationships and injections.

I won’t ruin the video, so go check it out!

Concepts: #1 Dependency Injection and Inversion of Control

Saturday, October 24, 2009 12:11:21 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Dependency Injection | Inversion of Control | Ninject | TekPub

Last Saturday, Steve and I attended Philly.NET Code Camp 2009.2. There were about 475 attendees and 12 separate tracks, each with 5 sessions. Here is the list of tracks that I attended:

8:30 AM – Len Smith, “Test Driven Development and Dependency Injection”

10:00 AM – Jess Chadwick, “What’s New and Hot in .NET 4.0”

12:30 PM – Al Katawazi, “Enterprise ASP.NET MVC Application Development”

2:00 PM – Steve Bohlen, “Refactoring to a S.O.L.I.D. Foundation”

3:30 PM – Sara Chipps, “Making Your Personal Projects a Reality”

Overall, the tracks were great. I felt like I was able to get something out of each one. My interests were split, attending two new and upcoming topics and two craftsmanship* topics.

On the topic of all things new and exciting, here are some .NET 4.0 points of interest:

  • DLR (Dynamic Language Runtime)
  • Lazy (lazy instantiation of the generic type)
  • Code Contracts, with Runtime and Compile time checking
  • Covariance and Contravariance
    • IEnumerable b = new IEnumerable();
    • DoSomething(Action func); DoSomething(Base b => b.Value);
  • Named & Optional Parameters
    • A(B b, int i = 0); A(i: 5, b: new B());
  • PLINQ
    • Parallel.ForEach, parallelizes a task across a collection
  • MEF (Managed Extensibility Framework)
    • Provides Extensibility, and Dependency Management
    • Similar to IoC, but not quite there.

Enterprise ASP.NET MVC was interesting because it demonstrated true reuse of components in an MVC application. I was particularly interested in how he set up the MVC application, separating it into several projects. Each project had an extremely specific task:

  • Demo
  • Communication
  • QA
  • Security
  • Static Content

The presenter, Al Katawazi also mentioned referencing a separate project for all Static Content. He referenced a post by Nick Berardi about the Google App Engine that I found very interesting.

More bloggy goodness to come…

Monday, October 19, 2009 11:22:06 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
.NET 4.0 | ASP.NET MVC | Code Camp | Philly.NET

I must say that being able to use the Routing engine in ASP.NET MVC is liberating.  In the traditional web model, your browser is making a request for a file on some remote web server.  The server looks for that file, processes it, and makes a response.  This model works great, but what if you don’t want “.aspx” on the end of your Url?  Beyond that, relative paths on the server can take away from any readability your Urls may have had.  Ever tried explaining query string parameters to the average user?  Painful.

Routing isn’t a new thing by any means, but has recently become a reality in the world of .NET.  There’s a whole namespace dedicated to it in System.Web.Routing.  It allows you to create cognitive, user friendly, and meaningful Urls.  Time for an example.

Sam is on a project, and his program manager instructs him to create a user profile page for their application.  With some special permission, Sam is able to try out ASP.NET MVC.  Does he start coding at the drop of a hat?  Never.  Ever.  Requirements first!  One of the general requirements says “The average user knows what page the Url represents.”  Sam is a good programmer, so his gut reaction is a question: “How would the user know that a Url points to their own profile?”  He writes out on his whiteboard (because all good programmers write things out on a whiteboard):

Traditional ASP.NET Web Forms Way:

http://localhost:1234/Users/UserProfile.aspx?UserID=1&Username=johncoder
http://localhost:1234/Users/UserProfile.aspx?UserID=1

Ideal Ways in ASP.NET MVC:

http://localhost:1234/Users/1/johncoder
http://localhost:1234/Users/1
http://localhost:1234/Users/johncoder <- Possible naming conflicts, but previous two work fine.

Now that Sam knows how he wants to accomplish his goal.  He fires up Visual Studio and creates a new ASP.NET MVC Web Application.  He uses his company’s existing data access layer, which uses LINQ to SQL classes.  Routes point to Action Methods on Controllers, which means that Sam needs a UsersController:

public class UsersController : Controller
{
    public ActionResult Details(int id)
    {
        UserRepository repository = new UserRepository();
        User user = repository.FindUserById(id);
        return View(user);
    }
}


The Details Action Method finds the target User, and a View for the user model.  By default, it will use “Views\Users\Details.aspx”.  There’s more!

public class MyMvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = "" }
        );
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}


The above code appears in the Global.asax.cs file an MVC application by default.  “Default” is the name being assigned to this given route, and “{controller}/{action}/{id}” is the Url.  The anonymous object in the next line serves as the default values for this route.  Using this route, the Url to a user would look like this:

http://localhost:1234/Users/Details/1

This isn’t quite what he had in mind.  Sam needs to create a new route to facilitate his need.  Here’s what he came up with:

routes.MapRoute(
    "UserProfile",
    "Users/{id}/{username}",
    new { controller = "Users", action = "Details", username = "" }
);


There's a little trickery going on here. Notice that he made no mention of a controller, or even an action method in the Url. Instead, he is taking advantage of the default parameter values by using an anonymous type. Since he didn’t include “{controller}” in his Url, the anonymous object needs to specify which controller to use.  MVC is built to look for "controller" and "action" keywords, and allows you to add your own. In this case, he added "id" and "username" parameters. If the user does not specify an "id" value, the request will not match against this route, and continue searching the RouteCollection until it finds a match.  Since he specified a default “username” as an empty string, the user is not required to enter a username.  The Url in this route has “Users” hard coded into it.  That literally means that the Url has to have “Users” in it.

Another feature of the Routing engine is that it can be used to generate Urls, too.  Sam can change any View in his application to use an HtmlHelper method like so:

<%= Html.RouteLink(user.FullName, "UserProfile", new { id = user.Id, username = user.Username } ) %>


The first parameter is the anchor text. The second is the name of the Route that the engine should use. The properties of the anonymous object are the parameters in the Url.

Don’t you agree that this is much more flexible than relying on the file system to create Urls?  It is my honest opinion that attention to usability details (even as transparent as a Url) produces a professional, high quality product.  By taking advantage of newer features, like the Routing engine, we can escalate our standards to the next level.

Thursday, October 08, 2009 12:11:37 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
ASP.NET MVC | C# | Routing | Usability

How often are you “in the zone?” Is it a couple of times each day? Once a day? Once a week? Once a Month? Regardless of how often, I would be willing to bet that your best work is done while in the zone. Recognize this phenomenon and savor every juicy second.

Being in the zone means that time is irrelevant, and you are coding up a storm; absolute genius is flowing from your fingertips. All of your concerns take a back seat, and productivity rides shotgun.

[insert sound effect here]

clip_image002

Talk about instant buzz-kill! There are few things more sobering than an interruption while in the zone. It is a fragile state of Zen, and any interruption borders on personal offense.

Getting in the zone is like falling asleep. Some people are good at it while others have to work hard. It generally requires silence and an environment void of distractions. A leaky faucet stands between you and a good night’s sleep. You are a programmer, so naturally you have debugged the situation and come to the following conclusion: that faucet is going to die a horrible death. Thankfully, you have a meeting with the true head of the household (the wife), and decide that you should outsource the project to a specialist. A plumber fixes the leaky spout and you can once again examine the inside of your eyelids for holes.

Much like the faucet example, a developer must deal with distractions in the same way.

1. Diagnose the problem (Who wants what, and why?).

2. Solve it (Give them what they want so they will go away!).

3. Try to get back in the zone.

What’s more is the net effect of these interruptions.

“Consider that it takes 15 minutes for a developer to enter a state of flow. If you were to interrupt a developer to ask a question and it takes five minutes for them to answer, it will take a further 15 minutes for them to regain that state of flow, resulting in a 20 minute loss of productivity. Clearly, if a developer is prevented from flowing several times during the day their work rate declines substantially.” – Software Nation

Zone management seems impossible. To some degree, it is. Email is a raging river that will never end. Coworkers will always have questions. People around you will always chat and gossip. Silence is underrated. Even discomfort can jostle the flow.

Rest assured there is a point to this rant. Take control over what is yours, and protect your zone by any means necessary. If that means you need a $200 pair of comfortable headphones to drown out the world, so be it. If it means only allowing emails to break the floodgates once or twice an hour, go for it. Find what works for you and exploit it, because being in the zone is our number one secret to productivity.

Monday, September 28, 2009 10:14:53 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Productivity

I can’t help but question functional specification methodology.  It’s a crucial part of the development process, but how can you be sure it is adding the right kind of value to your process?  I don’t deny that specs are important; it is often the developer’s first line of defense for answering questions.  Some specs look and read like a loosely worded form letter, hardly communicating any concrete requirements for the project.  With that said, let’s get something clear.  Should the spec “know” everything?  If not, that’s okay.  The sooner we can reach a consensus the better.  For the purposes of this blog post, I’ll say the spec doesn’t have all of the answers.

Think about the goals of a finished project.  They are to meet high expectations in terms of quality, performance, accuracy, and reliability.  Should the spec be treated the same way?  If so, how does that happen?  My expectations are probably higher than the average person, but on some level I would like to think that they’re reasonable.

I expect a functional specification to be somewhat enjoyable to read, but useful above all else.  Rather than take the easy way out, I would like to clarify my expectations with a checklist of questions about functional specifications:

  • Is the document high quality?
    • Is the document human readable (spelling and grammar)?
    • Is the vocabulary clearly defined, and used consistently throughout?
  • Does the document perform well?
    • Does the document answer as many of the obvious questions as possible; actively trying to predict all possible road blocks along the way?
    • Is the document well organized?
    • Can information be quickly located?
  • Are the details of the document accurate?
    • Have all points of design been thoroughly researched?
    • Has anyone else peer reviewed its contents?
  • Is the document reliable?
    • Is all information within absolutely relevant?
    • Are the images or screenshots useful?
    • Are all details inline, and not between the lines?
    • Is the spec maintained in a timely fashion?
    • Are updates to the spec properly documented in detail?
    • Does the spec have some way of tracking changes?

All of these things pave the way for a well written functional spec.  Aside from a checklist, it might be helpful to further elaborate on my expectations by identifying common problems:

Yes.  Punctuation, spelling, and grammar all count.  Much like meeting someone, first impressions matter.  Think of grammar as a textual handshake; weakness in spelling and grammar gives the writer less credibility.  Writing is hard, but there are ways to make it easier.  At the very least, try adjusting spelling and grammar rules in your favorite word processor for extra strict practice.  Try not to ignore the omniscient squiggly lines. 

Ditch ambiguity—writing in the passive voice is the safe way out.  It’s like saying “the system might work this way.”  Use the active voice to instill confidence in the reader’s mind that there is some certainty to the outcome of the project.  Personally, learning to write in the active voice has been challenging, but absolutely worthwhile.

If I have to read between the lines, I’m already digging too deep.  Programmers are literal thinkers.  We tend to take everything at face value.  If it’s not put in plain English, don’t expect us to grok it.  Try to leave no stone unturned, and be explicit about implied knowledge and reap the benefits.  To some extent, assumed knowledge is like assuming we are all exceptionally gifted mind readers.

Cater to the drive-by reader.  Structure the document in ways that are easy to navigate.  It shouldn’t take any longer than fifteen to twenty-five seconds to find something in the spec.  Make the spec only as long as it needs to be.  Just like emails, people will naturally skip the body and go for the punch line.  Use lists to break up steps or detail oriented explanations.  Ancillary data can go into text, but keep the key parts visible to the scrolling eye.  Page breaks are a good way to clearly delimit autonomous sections.

Copy + Paste = Fail.  Period.  Keep things DRY (Don’t Repeat Yourself).  If you had to copy and paste, it probably wasn’t worded clearly enough the first time.  Plus, changes to the pasted text only mean more work.  Pasting paragraphs, even pages of text (really?) into a spec is counterproductive.  In some situations, jilted sections of pasted text could possibly be taken at face value.  That’s a risk I’m not willing to take.

Find an effective way to communicate changes to the spec in detail with everyone involved.  Whether it’s writing emails, checking into version control, or including it in the document itself—it’s bound to be helpful to someone.  A one line history summary is not sufficient.  Try sending an email that includes a summary of the latest changes, snippets from updated sections, page numbers, and a preview of what is in store for the next update.

Joel Spolsky posted a sample functional spec, and it’s worth skimming as a point of comparison.  I also recommend his series of essays entitled “Painless Functional Specifications.”  While I won’t argue that functional specifications are necessary, I believe that poor execution is equally destructive.  For them to truly add value to a project, they need some tender love and care.

Sunday, August 30, 2009 11:36:19 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Functional Specifications | Writing

While catching up on some podcasts, I listened to Hanselminutes #169 with Roy Osherove.  Scott and Roy discuss the art of unit testing.  I’m a fan of unit testing, but specifically in writing high quality unit tests.  A few of the points Roy made were so good, I had to jot them down.  This post is my summary of the podcast.

What is a unit?

Understanding what a unit is helps cut down meta-test time.  Define a unit that makes sense to your particular framework.  Some people say to “Test only the smallest piece of code.”  Roy was a little more specific in providing the following list of criteria for unit testable candidates:

  • Must run only in memory
  • Must run fast
  • Does not touch any external state (database, file system, etc.)
  • Is Repeatable
  • May touch multiple classes/methods

The 3 Pillars of Unit Testing

Roy describes the 3 pillars of unit testing with the following questions:

Trustworthiness.  Are you able to run your test and trust the results?  Do you watch your test pass, and then debug it anyway?  If you don’t trust the test, it’s not saving you time.  Mixing integration tests with unit tests reduce trust.

Maintainability.  Maintenance is abandoned because maintaining costs are too high.  Tests that are not run or maintained are no longer useful, which leads to decreased trustworthiness over time.

Readability.  Do the unit tests conform to naming conventions?  Are they organized logically?  Readability is a factor that can deter maintenance and trustworthiness.  If the person working with the test cannot read it easily, they might not understand what the test is for or what the results are meant to signify.

“Remove one of these pillars, and the rest will fail.”

The Blurry Line:  Unit Testing Versus Integration Testing

In lieu of the integration test versus unit test dilemma, I defer to this StackOverflow question.  It really depends on the situation, and what kinds of boundaries are being crossed within the test in question.

Integration tests come in handy for things the require state.  Testing a Data Access Layer should be done with an integration test, as opposed to a unit test.  Use a real database in the tests, and let the DAL be the test for the database.  Integration tests can be used to test several aspects of state dependent functionality.  Given a logging scenario, the integration test would verify that logging occurred, and assert that the result was the expected outcome, and then cleanup.  Unit tests would test the interaction without the actual logging functionality.

Get the Terminology Right

So often in unit testing you need setup methods and tear down methods.  In order to reduce the scope of what the test is actually using, other incorporated functionality of the framework must be used artificially.

  • Fakes look like an object, but is fake for the test.
  • Mocks are fake objects that decide if the test passes.  Assert against mocks to pass or fail tests.
  • Stubs help your test run.  Don’t assert against them, they just mimic the system.

Assertions

One assert is plenty for any unit test.  However, you might have more than one assert for a unit test if an object result needs to have a specific combination of property values.  That still boils down to being one assertion because the combination of assertions dictate a single expected result.

Test Names

Name unit tests with the Name of the Method, Scenario, and Expected Behavior.   Including this kind of information helps reduce the amount of time a programmer would have to spend figuring out what the unit test is supposed to do, and furthermore encourages the test to stay on track; it keeps intentions clear.

Related Links:

The Art of Unit Testing: with Examples in .NET — http://www.amazon.com/Art-Unit-Testing-Examples-NET/dp/1933988274/ref=sr_1_1?ie=UTF8&qid=1249321351&sr=8-1

Monday, August 03, 2009 1:45:24 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
Hanselminutes | Integration Testing | Roy Oscherove | Scott Hanselman | Unit Testing

I just saw a tweet about the new Applet Tablet, and immediately thought of my good buddy Martin.  He’s one of those people who actually like Macs (shhh…. I’ve thought about getting one… don’t tell anybody…).  He said to me:

“The only thing I’m worried about is that it’s too much like a large iPhone, because that would be weird.”

This was too good to let go, so can I get away with a few jokes?  Maybe it’s a jumbo iPhone, for use with your jumbo calculator.

No, no, maybe it’s more like a foam finger.

 

To be fair, I think Apple has a really good thing going.  Pick one thing, and do it really well.  They already have probably THE best phone on the market with tons of people using them.  Touch screen on the iPhone is unmatched.  I own a Samsung Omnia, and the damn thing frustrates me to no end.  I usually close my eyes and try to trick myself into thinking I’m using an iPhone.

 

Sunday, August 02, 2009 9:52:12 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] -
iPhone | Martin Carlson

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
John Nelson
Sign In
Statistics
Total Posts: 22
This Year: 0
This Month: 0
This Week: 0
Comments: 1
 
  All Content © 2010, John Nelson