Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#

Words Of Wisdom For The Single Developer

Rate me:
Please Sign up or sign in to vote.
3.97/5 (28 votes)
25 May 2010CPOL8 min read 54.1K   29   47
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)


Written By
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? Pin
MichP1-Jun-10 11:29
MichP1-Jun-10 11:29 
AnswerRe: How About Adding Comments? Pin
Richard Blythe2-Jun-10 5:32
Richard Blythe2-Jun-10 5:32 
AnswerRe: How About Adding Comments? Pin
MichP2-Jun-10 5:42
MichP2-Jun-10 5:42 
Generalexcellent Pin
Donsw28-May-10 16:34
Donsw28-May-10 16:34 
excellent article

Well written and concise,
cheers,
Donsw
My Recent Article : CDC - Change Data Capture

GeneralRe: excellent Pin
Richard Blythe29-May-10 17:05
Richard Blythe29-May-10 17:05 
GeneralSingle developer seeks single female Pin
Qwertie26-May-10 18:24
Qwertie26-May-10 18:24 
GeneralRe: Single developer seeks single female Pin
Richard Blythe27-May-10 5:22
Richard Blythe27-May-10 5:22 
GeneralExcellant Topic. But too short actually Pin
Som Shekhar18-May-10 20:01
Som Shekhar18-May-10 20:01 
GeneralRe: Excellant Topic. But too short actually Pin
Richard Blythe19-May-10 5:49
Richard Blythe19-May-10 5:49 
GeneralRe: Excellant Topic. But too short actually Pin
Som Shekhar19-May-10 7:46
Som Shekhar19-May-10 7:46 
GeneralRe: Excellant Topic. But too short actually Pin
rjmoses25-May-10 3:01
professionalrjmoses25-May-10 3:01 
GeneralRe: Excellant Topic. But too short actually Pin
Richard Blythe25-May-10 4:47
Richard Blythe25-May-10 4:47 
Questionwhat about me? Pin
techind-hhh18-May-10 19:38
techind-hhh18-May-10 19:38 
AnswerRe: what about me? Pin
WoleTall24-May-10 13:19
WoleTall24-May-10 13:19 
GeneralNice Subject Pin
Khaniya18-May-10 19:37
professionalKhaniya18-May-10 19:37 
GeneralMy vote of 2 Pin
SledgeHammer0118-May-10 18:56
SledgeHammer0118-May-10 18:56 
GeneralRe: My vote of 2 Pin
Som Shekhar18-May-10 19:50
Som Shekhar18-May-10 19:50 
GeneralRe: My vote of 2 Pin
SledgeHammer0119-May-10 5:08
SledgeHammer0119-May-10 5:08 
GeneralRe: My vote of 2 Pin
Som Shekhar19-May-10 5:22
Som Shekhar19-May-10 5:22 
GeneralRe: My vote of 2 Pin
SledgeHammer0119-May-10 9:24
SledgeHammer0119-May-10 9:24 
GeneralRe: My vote of 2 Pin
Som Shekhar19-May-10 10:03
Som Shekhar19-May-10 10:03 
GeneralRe: My vote of 2 Pin
Civilised Barbarian31-May-10 11:10
Civilised Barbarian31-May-10 11:10 
GeneralRe: My vote of 2 Pin
Richard Blythe19-May-10 6:07
Richard Blythe19-May-10 6:07 
GeneralRe: My vote of 2 Pin
SledgeHammer0119-May-10 9:25
SledgeHammer0119-May-10 9:25 
GeneralRe: My vote of 2 Pin
Corey Fournier19-May-10 6:44
Corey Fournier19-May-10 6:44 

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

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