Click here to Skip to main content
Click here to Skip to main content
Go to top

Words Of Wisdom For The Single Developer

, 25 May 2010
Rate this:
Please Sign up or sign in to vote.
Helpful tips and insights from one single developer to another.

Table Of Contents

 

Introduction

Since the release of the .Net Framework in February 2002, the software industry has seen a huge increase in single developers entering the field.  Microsoft (with all of it's problems) has changed the landscape for software development.  Most low level details have nothing to do with business logic, which is what most developers are hired to do.  Jeffery Richter's thoughts on the .Net Framework are: "...after using the .Net Framework for several years...I would never go back to the old ways of software development...I just can't believe that we programmers put up with it for as long as we did."

Okay, so much for my soapbox speech.  Needless to say that if someone is wondering whether or not to learn a .Net language, I have a bit of advice: "Embrace the future".

With all of operating costs that are saved by being a single developer, there are also some disadvantages.  The primary reason being that you are the entire creative engine for your company.  If you're having a bad day, the whole company is having a bad day!  Also, it's easy to get complacent, or the bad one: "sloppy" when no other developer is using your code directly.

I say these things because as a single developer, I have experienced these challenges many many times.  Over the years, I have picked up tips and tricks that have been invaluable to my career.  Please keep in mind that I'm not writing a syllabus on how things must be done.  It's only my intent to pass along some wisdom, and if you see things differently, we can agree to disagree.
 

The Imaginary Audience

While writing code, it's easy to keep everything organized in your head. Just remember that a year from now, you WILL forget how you structured today's code.
Tip: Write code that targets an outside audience.  If you think that another software company would not be able to understand it, there is a huge possibility that you won't understand it a year from now.  Let's look at a "customer information" data structure that I have written for myself:

public struct Cust
{
    public string Address;
    public string Date;
    public string ContactAddress
    //...
}
  • The Address field stores the: Street, City, State and Zip Code.  (It's compact right?)
  • The Date field stores the customer's date of birth.  (Why bother with a name like DateOfBirth when I know what it means?)
  • The ContactAddress field stores the customer's email address.  (Anybody can differentiate between Address and ContactAddress right?)

All of this "makes sense" to me now but we all know that this design would not pass the first meeting in a developer group.  To target an outside audience I would need to make some obvious changes.

public struct CustomerInfo
{   
    public string   Address;
    public string   City;
    public string   State;
    public string   Zip;
    public DateTime DateOfBirth;
    public string   ContactEmail;
    //...
}

In one glance, any developer could grasp the scope of this structure.  This also saves me time in future, should I need to review/edit this structure. 

Code Dust

Sometimes I encounter a code section that's difficult to wrap my brain around.  When that happens, I have learned that I save much more time by initially coding "dirty" (lengthy), figuring out the appropriate algorithm with the debugger by "stepping through" the code, then cleaning up my code.  For example, if you are working on a line of code that has a complex calculation, break the calculation into several lines of code with separate variables so you can see how each line works with the other.  The term "debugger" is actually a very narrow term when you can work on complex code in real time.  (Just remember to clean up the dust)

Centralize and Generalize

Bill Gates once said: "...The number of lines of code is your enemy."  What does that mean? The more untested code that you write will lead to longer debug sessions. (and more bottles of aspirin)  This is simply because NO ONE has ever written a perfect app on the first round.  In the past two years, I have developed of rule of thumb called: Centralize and Generalize.

Centralize
If a block of code is used more than twice, centralize it into a method or function.  This rule would also apply to short but complicated algorithms.  By centralizing, you are reducing the amount of code that must be debugged. 

In the example below, I had been developing a text editor that allowed the user to specify the font in a variety of ways: popup dialogs, tool bar buttons, etc.  With all of this code, I found myself using the same code block for each one.  With the code below, I centralized that block into a function that returns a new font based on three parameters.

public Font BuildFont(FontFamily fontFamily, float size, FontStyle style)
{
    if (fontFamily == null)
	throw new ArgumentException("FontFamily cannot be null!");
    if (size <= 0)
	throw new ArgumentException("size must be greater than zero!");

    bool errorCreatingFont = false;
    FontStyle styles = FontStyle.Regular;
    FontFamily ff = fontFamily;

    if (((style & FontStyle.Bold) == FontStyle.Bold) && ff.IsStyleAvailable(FontStyle.Bold))
        styles |= FontStyle.Bold;
    if (((style & FontStyle.Italic) == FontStyle.Italic) && ff.IsStyleAvailable(FontStyle.Italic))
        styles |= FontStyle.Italic;
    if (((style & FontStyle.Underline) == FontStyle.Underline) && ff.IsStyleAvailable(FontStyle.Underline))
        styles |= FontStyle.Underline;

    //if no style has been applied, we make sure that a default style is set the current font accepts.
    if (((style & FontStyle.Regular) == FontStyle.Regular) && !ff.IsStyleAvailable(FontStyle.Regular))
    {
        if (ff.IsStyleAvailable(FontStyle.Bold))
            styles |= FontStyle.Bold;
        else if (ff.IsStyleAvailable(FontStyle.Italic))
            styles |= FontStyle.Italic;
        else if (ff.IsStyleAvailable(FontStyle.Underline))
            styles |= FontStyle.Underline;
        else
            errorCreatingFont = true;
    }


    if (errorCreatingFont)
        throw new Exception("Error creating font type: " + ff.Name + "!");

    return new Font(ff, size, styles);
}

Since I have tested the BuildFont() function, I can reference it with the same confidence as any other .Net method.

Generalize

To generalize, write a function that can work in a variety of scenarios.  Let me give you an example.  Let's say that you are developing a function that filters the last name of your customers.

public string[] FilterCustomer(string[] lastNames)
{
    if (lastNames == null || lastNames.Length == 0) 
        return new string[0];

    List<string> filtered = new List<string>(lastNames.Length);
    for (int i = 0; i < lastNames.Length; i++)
    {
        if (lastNames[i] != null && lastNames.Length > 0 && 
	    lastNames[i].ToUpperInvariant().StartsWith(someInternalVar))
        {  filtered.Add(lastNames[i]); }
    }
    return filtered.ToArray();
}
I hope you can see that the function above is painfully restrictive.  Primarily because it does not allow the caller to specify which names that should filtered.  There is also some other things that we could change to make this a better generalized function.  For example, the lastNames parameter restricts the caller to use an string array.  To generalize this, we could use IEnumerable as accepted input. Also, it would be good to allow the caller to specify if the filter should include or exclude the filter criteria.  Let's take a look at the generalized version:
/// <summary>
/// Filters a customer by their last name.
/// </summary>
/// <param name="lastNames">The unfiltered list.</param>
/// <param name="startsWith">Filter criteria.</param>
/// <param name="excludeMatch">If true, returns a list that does 
/// not contain the filter criteria. If false, returns a list 
/// that contains the filtered criteria.</param>
public string[] FilterCustomer(IEnumerable<string> lastNames, string startsWith, bool excludeMatch)
{
    if (lastNames == null)
        return new string[0];

    //ensure that we are case insensitive...
    startsWith = startsWith.ToUpperInvariant();
    bool blnStartsWith;
    List<string /> filtered = new List<string />();
    foreach (string str in lastNames)
    {
        blnStartsWith = (str != null && str.Length > 0 &&
        str.ToUpperInvariant().StartsWith(startsWith));
        if (blnStartsWith != excludeMatch)
          filtered.Add(str); 
    }
    return filtered.ToArray();
}

The lastNames parameter can now accept any input that implements IEnumerable.  That means that if the caller decides to use a generic List<string> instead of an array, we won't have to change the function's parameter definition.   The important startsWith parameter allows the caller to specify the starting character(s).  And finally, a powerful little parameter that allows the caller to choose what type of filtering results are returned. (Read xml comments for excludeMatch) 
Obviously, there are many other things that could be done to generalize this even more but hopefully you get the idea. 

By the way, let me give you a tip concerning: startsWith.ToUpperInvariant().  I learned from a Microsoft insider that ToUpperInvariant() executes faster than ToLowerInvariant().
 

Stability Over Speed

I know that we must all be conscious of writing bloated/slow code, but I can tell you that your customers will give you much more grief over bugged software than slow software.  Only write unmanaged code when you are certain of it's necessity!  Writing unmanaged code is like diving into shark infested waters so be sure that you're a good swimmer!   The .Net Framework is certainly not perfect but advances are being made every day to make it better.

By All Means Make It Look Good!

One of my pet peeves is poorly formatted code.  It may execute perfectly but if you have to be the compiler to read it, it's not formatted right.  Here's a simple example of poorly formatted code.  (My apologies if this is your coding style)

if (blnEditingInfo == false)
{
    editButton1.Text = "Edit Customer";
}
else
{
    editButton1.Text = "Save Changes";
}
//... 

What a waste of valuable screen space when it could be written like this:

editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes";
//...

While there is a lot of debate on the value of using "shorthand", I personally feel that it's a great way to condense several lines of code into one.

Don't Forget To Live

This rule has to be the hardest for me to follow.  Being the boss and the employee, it's easy to create slave out of yourself.  Just remember: "There will always be deadlines".  It doesn't matter how hard and long you work to "get ahead" because another deadline will be waiting in line to demand your attention.  This can quickly lead to "burnout", in which you have little motivation and nearly zero creativity!  My advice is to give yourself a responsibility free day once a week.  Sound like too much?  I can assure you that the benefits are far worth it!  If you feel like you're already suffering from burnout, take a look at this article.  If you can't relate to it, your not in the software industry!


Final Thoughts

  There are many other things that we could discuss but I feel that we have covered/uncovered some important areas that will make your programming career better.   As a single developer, you never know when you may land a consulting job that requires you to work with a third party developer.  The code concepts that we discussed will save you (and the third party) a lot of grief. 

The software industry in certainly not a dead end street!  There is always something new to discover and I welcome any tips or tricks that you have to share.  Okay! I'm out of here.  I'm going to try and work on that last topic...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Richard Blythe
Software Developer Unity3 Software
United States United States
Richard Blythe is founder and CEO of Unity3 Software.
In his spare time he enjoys flying Cessna 172s, reading, playing his Taylor acoustic guitar and recording music. He's latest non-computer endeavor is to learn violin. (Ouch)

Comments and Discussions

 
QuestionHow About Adding Comments? PinmemberMichP1-Jun-10 11:29 
AnswerRe: How About Adding Comments? PinmemberRichard Blythe2-Jun-10 5:32 
AnswerRe: How About Adding Comments? PinmemberMichP2-Jun-10 5:42 
Generalexcellent PinmemberDonsw28-May-10 16:34 
GeneralRe: excellent PinmemberRichard Blythe29-May-10 17:05 
GeneralSingle developer seeks single female PinmemberQwertie26-May-10 18:24 
GeneralRe: Single developer seeks single female PinmemberRichard Blythe27-May-10 5:22 
GeneralExcellant Topic. But too short actually PinmemberSom Shekhar18-May-10 20:01 
GeneralRe: Excellant Topic. But too short actually PinmemberRichard Blythe19-May-10 5:49 
GeneralRe: Excellant Topic. But too short actually PinmemberSom Shekhar19-May-10 7:46 
Hi,
 
I am sorry for sounding extremist Smile | :) Your article is good and I also understand that writing all topics in one article won't be doing justice to reader's patience Smile | :)
 
All I was trying to say was that you should consider writing Part 2 Wink | ;)
GeneralRe: Excellant Topic. But too short actually Pinmemberrjmoses25-May-10 3:01 
GeneralRe: Excellant Topic. But too short actually PinmemberRichard Blythe25-May-10 4:47 
Questionwhat about me? Pinmembertechind-hhh18-May-10 19:38 
AnswerRe: what about me? PinmemberWoleTall24-May-10 13:19 
GeneralNice Subject PinmemberKhaniya18-May-10 19:37 
GeneralMy vote of 2 PinmemberSledgeHammer0118-May-10 18:56 
GeneralRe: My vote of 2 PinmemberSom Shekhar18-May-10 19:50 
GeneralRe: My vote of 2 PinmemberSledgeHammer0119-May-10 5:08 
GeneralRe: My vote of 2 PinmemberSom Shekhar19-May-10 5:22 
GeneralRe: My vote of 2 PinmemberSledgeHammer0119-May-10 9:24 
GeneralRe: My vote of 2 PinmemberSom Shekhar19-May-10 10:03 
GeneralRe: My vote of 2 PinmemberCivilised Barbarian31-May-10 11:10 
GeneralRe: My vote of 2 PinmemberRichard Blythe19-May-10 6:07 
GeneralRe: My vote of 2 PinmemberSledgeHammer0119-May-10 9:25 
GeneralRe: My vote of 2 PinmemberCorey Fournier19-May-10 6:44 
GeneralRe: My vote of 5 PinmemberSledgeHammer0119-May-10 9:26 
GeneralGoing postal PinmemberElrondCT24-May-10 16:45 
GeneralRe: Going postal PinmemberRichard Blythe25-May-10 4:59 
GeneralNice Article. PinmemberGaurav Dudeja India18-May-10 18:47 
GeneralNice advice Pinmemberdwilliss18-May-10 15:38 
GeneralRe: Nice advice PinmemberRichard Blythe18-May-10 15:57 
GeneralGood topic for discussion PinmemberStephen F. Heffner18-May-10 11:15 
GeneralRe: Good topic for discussion PinmemberRichard Blythe18-May-10 13:14 
GeneralRe: Good topic for discussion PinmemberStephen F. Heffner18-May-10 13:36 
GeneralRe: Good topic for discussion PinmemberRugbyLeague19-May-10 2:08 
GeneraleditButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberPaulo Zemek18-May-10 9:58 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberRichard Blythe18-May-10 13:01 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberWoleTall24-May-10 13:49 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberDrew Stainton18-May-10 15:43 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberSeishin#18-May-10 21:53 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberCivilised Barbarian31-May-10 12:07 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; Pinmembersupercat919-May-10 5:36 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberPaulo Zemek19-May-10 7:22 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; Pinmembersupercat920-May-10 5:21 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberWoleTall24-May-10 14:01 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; Pinmembersupercat925-May-10 5:53 
GeneralRe: editButton1.Text = !blnEditingInfo ? "Edit Customer" : "Save Changes"; PinmemberMP325-May-10 0:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 25 May 2010
Article Copyright 2010 by Richard Blythe
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid