DaedTech

Stories about Software

By

Comments: Here’s my Code and I’m Sorry

Heavily Commented Code: The Awful Empathy

Imagine a feeling–that empathy you get when you’re watching someone fail in front of an audience. Perhaps its a comedian relying on awful puns and props or a person in a public speaking course that just freezes after forgetting some lines. Ugh. It’s so awkward that it hurts. It’s almost like you’re up there with them. You start mumbling to yourself, “please, just be funny,” or, “please, just remember your lines.”

BanjoAccordionThe agony of sustained failure in such a situation doesn’t come on all at once. It creeps up on you in a crescendo of awful empathy and becomes memorable as it approaches the crest. But it starts subtly, before you realize it. There are warning signs that the train is unstable before it actually pops off of the rails. A classic warning sign is the “pre-excuse.”

Think of how you feel when someone gets up to talk at a meeting or give a presentation, and they start off with something like, “okay, this isn’t really finished, and Jones was supposed to help, but he got assigned to the Smith contract, and I did things in here that I’m not proud of, and…” With every clause that the speaker tacks onto the mounting lists of reasons that you’re going to hate it, you feel your discomfort mounting–so much so that you may even get preemptively angry or impatient because you know he’s going to bomb and you’re about to feel that tooth-grinding failure-empathy.

Okay. Now that the stage is set and we’re imagining the same feeling, know that this is how I feel when I open code file and see the green of comments (this is the color of comments in all my IDEs) prominently in a file. It’s as though the author of the code is on a stage in front of me, and he’s saying, “okay, so this is probably not very clear, and some of this is actually completely wrong, and changing this would be a nightmare, and you might want a beer or two, heh heh, but really, this will make more sense if you’re drunk, and, you know what, I’m sorry, really, really sorry because this is just, well, it’s just… it’s complete garbage. Sorry.”

That might seem a bit harsh, but think of what you’re looking at when you see code with a comment to actual code ratio approaching 1:1. You’re looking at a situation where someone needed to spend as much space and probably as much time trying to tell you what the code says as writing the code. Why would someone do that? Why would someone write a bunch of code and then write a bunch of English explaining to someone fluent in code what the code does? This is like me sending you an email in Spanish and putting the English equivalent after every sentence. I would do it if one of the two of us didn’t speak Spanish well or at all. And that’s how I feel when I see all those comments–either you don’t speak code very well or you think that I don’t speak code very well. The former occurs a lot with people who program haphazardly by coincidence. (“I better write this down in a comment because I had no idea that’s what an array was for. Who knew?”) The latter generates mind-numbing comments that rot. (“Declares an int called x and initializes it to 6.”) If you aren’t being forced to write comments by some kind of style policy and you’re not Zorro, you’re writing things in English because you’re not bothering to write and illuminate them in Code (I’m using the uppercase to distinguish simply writing some kind of compiling code from writing Code that communicates).

Self-Fulfilling Prophecy

There’s a substantial cross section of the developer world that thinks diligently commenting code is not only a best practice, but also table stakes for basic caring and being good at your craft. As I’ve previously explained, I used to be one of those people. I viewed writing comments in the same way that I view shutting drawers when I’m done using them or making my bed–just grunt work that’s unavoidable in life if you want to be a person that’s organized. Interestingly, I never really viewed them as particularly communicative, and, since adopting TDD and writing tiny methods, I viewed them largely as superfluous except for occasionally explaining some kind of political decision that transcended code (documenting APIs that you’ll release for public consumption are also an exception as this becomes part of your deliverable product). But I started to get increasingly disillusioned with the way comments would look in group code.

I would return to a method that I’d written six months earlier and for which I’d put a very clear doc comment, only to see something like this:

/// Do something with X
/// Never ever ever ever accept a negative value X
/// or millions of the most adorable puppies you've ever seen
/// will be senselessly butchered!!!!!!!
private void DoSomethingWithX(int x)
{
    //if(x < 0)
    // throw new ArgumentException("x", "You monster.");

    int y = x; //No matter what, do not let y be 15!!!!
    y = 15;
    PossibleDoom(y);
    PossibleDoom(x);
}

Holy crap! We're clearly playing Russian Roulette here. Did the requirements change and we're no longer endangering puppies? Is this code causing terrible things to happen? Who wrote that comment about 15? Hopefully not the same person that wrote the next line! And what should this code do--what the various comments say or what it actually does? Do the people responsible even work here anymore?

I'm pretty sure that anyone reading is chuckling and nodding sympathetically right now. You can only return to a method that you've written and see this sort of thing so many times before you come to a few conclusions:

  1. People almost never read your comments or any comments--they're just a step above contract legalese as far as pointless noise in our lives goes.
  2. Even if someone does read your comments, they certainly won't fix them along with the code they're changing.
  3. On a long enough timeline, your comments will all become dirty, confusing lies.
  4. If you want to minimize the degree to which you're a liar, minimize the comments that you write.

Surely this isn't really news to anyone, and it's probably answered with admonishments and mental notes to be more diligent about updating comments that everyone knows won't actually happen. So why is it then considered good form and often mandated to put lies into source control for the later 'benefit' of others? Why do we do this, discounting the bed-making/diligence/good-citizen motivation?

To answer that question, think of the kind of code where you see comments and the kind of code where you don't. If you see a four-line functional method with a single nested loop and no local variables, do you generally see comments in there? Probably not. How about a fifty line method with so many nested control structures that you need some kind of productivity add-in to know if you're scoped inside that else you saw earlier or another if, or maybe a while loop? Bingo--that's where comments go to hang out. Giant methods. Classes with lots of responsibilities and confusing internal state. Cryptically-named local variables. These things are all like cool, dank yards after a storm, sprouting explanatory comments like so many mushrooms. They sit there in mute testimony to the mildew-ridden, fungus-friendly conditions around them.

To put it another way, comments become necessary because the author isn't speaking Code well and punts, using English instead of fixing the code to be clear and expressive. Thus the comments are compensation for a lack of clarity. But they're more than that. They're an implied apology for the code as well. They're an apology for writing code and not Code. They're an apology for the fact that writing code and not Code results in the project being a legacy project before it's even done being written. They're an implied apology for big, lumbering classes, winding methods, confusing state, and other obfuscations of intent. But most of all, they're the preemptive, awkward-empathy-inducing, "hang onto your hat because what I'm doing here is actually nuts" pre-apologies/excuses to anyone with the misfortune of reading the code.

So please, I beg you--next time you find yourself thinking, "dude, nobody's ever going figure this wackiness out unless I spend a few sentences explaining myself," don't bother with the explanation. Bother instead to correct the "nobody's ever going to figure this out" part. Good Code speaks for itself so that you can focus on more important things.

By

One Singleton to Rule Them All

I would like to preface this post by saying that I don’t like the Singleton design pattern at all. There are some who love it, others who view it as a sometimes-useful, often-abused tool in the toolbox, and then there are people like me who believe that it’s extremely rare to see a use of it that isn’t an abuse — so rare that I consider it better to avoid the pattern altogether. I won’t go into much more detail on my thoughts on the Singleton (stay tuned for that when I get to this pattern in my design patterns series), but here is some further reading that expounds a lot on reasons not to like this pattern:

  1. Scott Densmore: Why Singletons are Evil
  2. Misko Hevery: Singletons are Pathological Liars
  3. Alex Miller: Patterns I Hate
  4. Steve Yegge: Singleton Considered Stupid

With all of those arguments against Singleton in mind, and considering the damage that abuse (and I would argue use) of the pattern causes in code bases, I found myself thinking of code bases I’ve heard of or encountered where the code was littered with Singletons. In these code bases, refactoring becomes daunting for a variety of reasons: the hidden dependencies, the complex temporal dependencies, the sheer volume of references to the Singleton instances, the almost obligatory Law of Demeter violations, etc. Singletons cause/encourage a rich variety of problems in code bases. But I think that something could be done about two such problems: the redundant Singleton implementation logic and the Single Responsibility Principle (SRP) violation of which Singleton classes are prima facie guilty.

Take a look at how the Singleton is implemented (as recommended by Microsoft, here). The basic implementation initializes the static instance in the property accessor while variants use field initializing syntax and introduce thread safety.

The basic implementation is here:

public class Singleton
{
     private static Singleton instance;

     private Singleton() {}

     public static Singleton Instance
     {
          get
          {
               if (instance == null)
                    instance = new Singleton();
               return instance;
          }
     }
}

More specific even to C# is James Michael Hare’s implementation using the Lazy<T> class to eliminate the redundant if-instance-null-instantiate logic needed in each Singleton class. But that still leaves the redundant Instance property, the redundant _instance field, and the awkwardness (SRP violation) of an object managing its own cardinality. What if we got rid of both of those issues?

public static class Singleton where T : new()
{
     private static readonly Lazy _instance = new Lazy();

     public static T Instance { get { return _instance.Value; } }
}

public static class SingletonClient
{
     public void Demonstrate()
     {
          Singleton.Instance.Write("Look!! Logger isn't a Singleton -- it's a real class!!");
     }
}

Using generics, this implementation allows an instance of every Singleton to be expressed in the code of a single class. In this fashion, any type can be implemented as a Singleton without the type being coupled to an internal Singleton implementation. It also standardizes the Singleton implementation by making sure it exists only once in the code base. With this pattern, there is a similar feel to IoC containers — classes can be implemented without concern for who will instantiate them and how.

Here is my take on the disadvantages and potential disadvantages of this approach:

  1. You still have Singletons in your code base.
  2. This might actually encourage more Singleton usage (though fewer actual Singleton implementations) by removing responsibility for implementation.
  3. Since constructor of object in question must have public default constructor, removes the Singleton gimmick of making the constructor private and thus the safeguard against additional instances being created is also removed.
  4. A natural extension of the previous item is that it remains a matter of documentation or convention to use Singleton<T> and not instantiate rather than it being impossible to instantiate.

But the advantages that I see:

  1. Only one class implements cardinality management, meaning refactoring away from Singleton is nominally easier.
  2. No Singleton SRP violations
  3. Singleton implementation (initialization, lazy load, thread-safety) is standardized to prevent inconsistent approach.
  4. I actually consider preventing the private constructor gimmick to be a plus — particularly where potential refactoring may be needed (and it pretty much always is when Singletons exist).
  5. With this pattern in your code base developers are less likely to be come comfortable/familiar with implementing the Singleton pattern.
  6. No need to introduce interfaces for Singletons to inject instance into classes using dependency injection — just inject a non-Singleton managed instance.
  7. A code base with nothing but normal instances is very easy to reason about and test, so the closer you get to that, the better.

I would like to reiterate that I’m not suggesting that you run out and start doing this everywhere. It mitigates some of the natural problems with the Singleton design pattern but “mitigates some” is a long way from “fixes all”. But, if you have a code base littered with Singletons this could potentially be a nice intermediate refactoring step to at least standardize the singleton implementation and provide slightly more friendly seams to testing legacy code. Or if you’re faced with and outvoted by a group of other developers that love their global variables (er, excuse me, Singletons), this might be a decent compromise to limit the damage they cause to the code’s maintainability. On balance, I’d say that this is an interesting tool to add to your arsenal, but with the caveat that something is probably wrong if you find that you have a use for it.

I’d be curious to hear others’ takes on this as well. I just kind of dreamed this up off the top of my head without taking a lot of time to explore all potential ramifications of it use. If you’ve implemented something like this before or if you have opinions on the advantages/disadvantages that are different than mine or if you see ways it could be improved, I’d be interested to hear about it in the comments.

By

Hilarious Conditional Bloopers!

For this Friday, I thought I’d do something a little more lighthearted and, in the tradition of bad television (or Robot Chicken’s satire thereof) post some programming bloopers. These are actual things that I’ve personally seen in source code as opposed to some kind of specific sampling of CodeSOD from the Daily WTF. Doing this series of posts about Boolean algebra made me think conditional logic fails I’ve seen both recently and long in the past.

For each one, I’ve tried my best to give it a catchy name, an explanation of the problem, an example of what it translates to in simple English (i.e. why it doesn’t “read like well written prose”), and what it ought to look like. So, without further ado, here are the bloopers:

The Ingrown Branch

private int _numberOfMilkCartons;
private bool _amIOutOfMilk;

public void FigureOutWhatToDo()
{
    if(_numberOfMilkCartons != 12)
        _numberOfMilkCartons = 12;
}

I call this The Ingrown Branch because of what it does. It introduces a conditional — a fork in the road, if you will — and it winds up in the same spot no matter which branch you take. In conversational English, this says “if the number of milk cartons is not 12, make it 12”. While this doesn’t sound ridiculous in the same way that others here will, consider what’s being done. If x is equal to 12, well, then do nothing because x is equal to 12. Otherwise, if it’s not equal to 12, set it to 12. What would be a simpler way to do this?

private int _numberOfMilkCartons;
private bool _amIOutOfMilk;

public void FigureOutWhatToDo()
{
    _numberOfMilkCartons = 12;
}

The Tautology

private bool _amIOutOfMilk;

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk || !_amIOutOfMilk)
        GoToTheStore();
}

In conversational English, a tautology is something that is vacuously true or redundant. In logic, this is something that is always true, ipso facto, such as “A or NOT(A)”, for instance. In terms of conversational English, this is like saying “If I’m out of milk or if I’m not out of milk, I’m going to go buy some milk.” Why not drop the spurious conditionals and get to the point:

public void FigureOutWhatToDo()
{
    GoToTheStore();
}

The Contradiction

private bool _amIOutOfMilk;

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk == !_amIOutOfMilk)
        GoToTheStore();
}

The opposite of a tautology, a contradiction is something that is vacuously false, such as primitive type not being equal to itself. With instances like this and the tautology, I usually see more complex incarnations that are harder to spot or else I give the benefit of the doubt and assume that manipulation of a more complex conditional occurred in the past and the thing was accidentally left in this condition. But this doesn’t alter the fact that I have seen code like this and that, in plain English, this would translate to “If I’m both completely out of milk and I have some milk, I’m going to buy milk.” It’s mind-bending nonsense that would best be described as:

//Yep, nothing at all

The Double Negative

private bool _amINotOutOfMilk;

public void FigureOutWhatToDo()
{
    if(!_amINotOutOfMilk)
        GoToTheStore();
}

I realize that this may be largely a product of speaking English as a first language, since double (and more) negatives are acceptable in some other languages. But you have to look at code like this and think, did anyone read this to themselves? “If I it’s false that I’m not out of milk, I will go to the store.” Wat? Okay, so not out of milk means that you have it, so if it’s false that you’re not out of milk, it’s false that you have it, and you are out of milk… aha! Why didn’t you just say so:

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk)
        GoToTheStore();
}

Ifception

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk)
        if(_amIOutOfEggs)
            if(_amIOutOfBeer)
                GoToTheStore();
}

An if within an if within an if… (credit to Dan Martin for this term). This is another mind-bending way of writing things that is rather jarring to the reader of the code, like saying “If I’m out of milk if I’m out of eggs if I’m out of beer, then I’m going to the store.” Dude, wat? Oh, you mean “If you’re out of milk AND you’re out of eggs AND you’re out of beer, then you’re going to the store? Well, nice to see what your breakfast priorities are, but at least that doesn’t read like the mumblings of a lunatic.”

The Robot

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk == true)
        GoToTheStore();
}

Perhaps this is a little nitpicky, but this explicit formation of Boolean conditionals bothers me. “If it equals true that I am out of milk, I will go to the store” sounds like some robot helper from the Jetsons or one of those shows that features a preposterous token “genius” whose intelligence is conveyed by having him speak like some robot helper from the Jetsons. Why not “If I’m out of milk, I will go to the store?”

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk)
        GoToTheStore();
}

The Yoda

private Milk _theMilk;

public void FigureOutWhatToDo()
{
    if(null == _theMilk)
        GoToTheStore();
}

If program in C you do, sense this makes and a clever trick to avoid assignment instead of comparison errors this is. If program in C you don’t, annoying and indicative that you’re not adopting the thinking of the language you’re working this is. When you speak English and try to sound like a native speaker, you don’t say “If missing is the milk, go to the store”. You say “If the milk is missing, go to the store.”

public void FigureOutWhatToDo()
{
    if(_theMilk == null)
        GoToTheStore();
}

The Existential No-Op

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk)
    {
        //GoToTheStore();
    }
}

Or, see variations where the comment is replaced by “return;” or some other similar thing. This is a conditional where, true or false, you do nothing. It sort of makes you question the very nature of (its) existence. This is like me saying to you “If I’m out of milk…” When you wait patiently for a moment and say “yes…?” I then say “nothing — that was all.” What should this be replaced with? How about just deleting the whole bit of nonsense?

Growing Pains

public void FigureOutWhatToDo()
{
    if(_amIOutOfMilk && _amIOutOfEggs && _amIOutOfBeer && _amIOutOfCheese && _amIOutOfChips && _amIOutOfMilk)
        GoToTheStore();
}

See what’s going on here? This conditional is growing so unwieldy that you forget by the end of it that you already mentioned being out of milk again. “If I’m out of milk, eggs, beer and milk, I’m going to the store.” “You said milk twice.” “I like milk.” How about dividing it up a bit and saying “If I am out of staples and I’m out of snacks, then I’m going to the store.”

public void FigureOutWhatToDo()
{
    if(AmIOutOfStaples() && AmIOutOfSnacks())
        GoToTheStore();
}

private bool AmIOutOfSnacks()
{
    return _amIOutOfBeer && _amIOutOfChips;
}

private bool AmIOutOfStaples()
{
    return _amIOutOfMilk && _amIOutOfEggs && _amIOutOfCheese;
}

The Mad Scoper

public void FigureOutWhatToDo()
{
    if(((AmIOutOfStaples())) && (AmIOutOfSnacks()))
        GoToTheStore();
}

I think we’ve all seen one of these — someone on the team or in the group has a few too many cups of coffee and really goes to town on the old 9 and 0 keys. This is probably done to make sure that order of operations is being followed when you don’t understand the order of operations. Conversational equivalent? “If I am out of staples, and I mean staples and not whatever is coming next until I’m ready to talk about that and now I’m ready so I’m going to talk about that and that is snacks and not staples we’re not talking about staples anymore we’re talking about snacks which if I’m out of I’m also not going to the store, okay done.” Let’s dial it back to the last solution:

public void FigureOutWhatToDo()
{
    if(AmIOutOfStaples() && AmIOutOfSnacks())
        GoToTheStore();
}

The Fly Swallower (aka The Train Wreck)

public class OldWoman
{
    public Horse _horse = new Horse();

    public object WhatDidYouSwallow()
    {
        if (_horse != null && _horse.Cow != null && _horse.Cow.Hog != null && _horse.Cow.Hog.Dog != null &&
            _horse.Cow.Hog.Dog.Cat != null && _horse.Cow.Hog.Dog.Cat.Bird != null &&
            _horse.Cow.Hog.Dog.Cat.Bird.Spider != null &&
                _horse.Cow.Hog.Dog.Cat.Bird.Spider.Fly != null)
            return _horse.Cow.Hog.Dog.Cat.Bird.Spider.Fly;

        return null;
    }
}

This is formally known as design with violations of the Law of Demeter, but it’s easier just to think of it as a train wreck. But the name I’m giving it comes from a nursery rhyme, which is how this starts to sound in conversational English. “There was an old lady who if she swallowed a horse who if it swallowed a cow who if it swallowed a hog who if it swallowed a dog…” How should this sound? There’s no easy fix. You need a different object model.

And with that, I’ll conclude my fun Friday post. This is meant to be light-hearted and in jest, but I’d say there’s definitely a good bit of truth here. You may not agree entirely with my assessment, but I think we’d all be well served to do the occasional double check to make sure we’re not leaving conditional bloopers in the code for others to read, triggering pointing and laughter. If you have other names for these or other conditional bloopers to mention (or you think I’m completely off base with one of these) please feel free to chime in.

By the way, if you liked this post and you're new here, check out this page as a good place to start for more content that you might enjoy.

By

The Code that Cried Wolf: Proving that Comments are Unneeded

I spent a lot of years diligently commenting my code. I wrote what the code did next to the statements themselves and I wrote method headers and sometimes I even kept a journal of edits in that header as if there were no such thing as source control. As I mentioned in an earlier post, I’ve since drifted further and further from this approach to the point of almost never commenting my code if left to my own devices. The reason for this gradual but near-complete reversal is that I’ve come to view comments as a crutch that prevents code from standing on its own from a readability perspective.

For instance, consider the following class (and before we go any further, I would just like to mention that the relationship between the “Prepper” and “Employee” is not actually how I would design this — this is just an example for demonstrating a point):

public class EmployeePrepper
{
    private readonly IEnumerable _employees;

    public EmployeePrepper(IEnumerable employees)
    {
        _employees = employees;
    }

    public void SetupEmployees()
    {
        foreach (var employee in _employees)
        {
            if (string.IsNullOrEmpty(employee.FirstName))
                throw new Exception();
            if (string.IsNullOrEmpty(employee.LastName))
                throw new Exception();

            if (employee.LastName.Length < 3)
                employee.LoginName = employee.FirstName + employee.LastName;
            else
                employee.LoginName = employee.FirstName[0] + employee.LastName;
        }
    }
}

Imagine that you've asked for a code review and someone says "well, it's a little hard to read and follow -- you've got some magic numbers in there and it's not all that readable." What suggestion is coming next? Or, if none is forthcoming, what do you do to address this? Something like the next code snippet?

/// 
/// This class takes a bunch of employees that the user entered and sets up derived properties on them
/// 
public class EmployeePrepper
{
    /// 
    /// This is a collection of employees that the constructor will pass in
    /// 
    private readonly IEnumerable _employees;

    /// 
    /// This constructor takes the class's dependency and initializes it
    /// 
    /// The employees this class will work on
    public EmployeePrepper(IEnumerable employees)
    {
        _employees = employees;
    }

    /// 
    /// Sets up the employees by setting derived properties
    /// 
    public void SetupEmployees()
    {
        //Cycle through the employees
        foreach (var employee in _employees)
        {
            //Make sure a valid first name and last name are entered
            if (string.IsNullOrEmpty(employee.FirstName))
                throw new Exception();
            if (string.IsNullOrEmpty(employee.LastName))
                throw new Exception();

            //If the employee has a very short last name, then use first concatenated to last
            if (employee.LastName.Length < 3)
                employee.LoginName = employee.FirstName + employee.LastName;
            else //Otherwise, use first initial concatenated to last name
                employee.LoginName = employee.FirstName[0] + employee.LastName;
        }
    }
}

Ah, much better, right? From the outside looking in, with IntelliSense, I learn that (1) the class takes a collection of employees and sets their derived properties, (2) the constructor takes a dependency and initializes itself, and (3) the setup employee method sets up the employees with their derived properties. Of course, I could learn that by (1) inspecting the constructor, (2) common sense, and (3) see item (1).

Okay, so maybe I don't learn all that much of interest from IntelliSense, but there's a lot of clarity in the method itself. I learn that (1) I'm going to cycle through records, (2) I'm going to check properties for validity and (3) a descriptive business rule for setting up login names. Of course, I could learn (1) by knowing what foreach() is and (2) by basic inspection. (3) is interesting in that it's the first comment that isn't just pointless filler. It actually explains something that I need to know.

So 1 out of 6 comments is helpful, but isn't that still a net gain? Well, it is if we assume that there is no downside to having commented code. But there is a downside. Specifically, the addition of comments to the file means extra artifact that must be maintained or else the comments drift from noise to lies. For example, what if we add a constructor parameter and don't pay attention to the doc comments (which pretty much no one does when editing classes)? Suddenly that comment about taking a single employee dependency is nonsensical. So you have 5 liabilities and 1 asset in terms of comments here, which seems like a poor tradeoff (although I'm not going to attempt to place an actual measurable value on the concept of misleading comments versus helpful, explanatory comments -- even if I could, it wouldn't matter much since it's pretty unlikely I'll read your comments anyway :) ).

Okay, I've sold you on my premise, but what do you say to the architects/leads/coworkers/project managers/etc who aren't buying what I'm selling? How do you convince them that this activity is somewhere between pointless and detrimental? Well, prove to them that the comments are pointless. Take away the crutch and make your class names, method names, variable names, and logic flow so clean and so self documenting that the comments look preposterous. Take the original code and turn it into this:

public class EmployeeDerivedPropertySetter
{
    private const int LastNameMinimumLength = 3;

    public class FirstNameEmptyException : Exception { }

    public class LastNameEmptyException : Exception { }

    private readonly IEnumerable _employeesPassedInFromConstructor;

    public EmployeeDerivedPropertySetter(IEnumerable employees)
    {
        _employeesPassedInFromConstructor = employees;
    }

    public void SetupDerivedProperties()
    {
        foreach (var employee in _employeesPassedInFromConstructor)
            SetupDerivedProperties(employee);
    }

    private static void SetupDerivedProperties(Employee employee)
    {
        ValidateFirstAndLastName(employee);
        SetLoginName(employee);
    }

    private static void ValidateFirstAndLastName(Employee employee)
    {
        if (string.IsNullOrEmpty(employee.FirstName))
            throw new FirstNameEmptyException();
        if (string.IsNullOrEmpty(employee.LastName))
            throw new LastNameEmptyException();
    }

    private static void SetLoginName(Employee employee)
    {
        if (IsEmployeeLastNameVeryShort(employee))
            employee.LoginName = ConcatenateFirstAndLastNames(employee);
        else
            employee.LoginName = ConcatenateFirstInitialAndLast(employee);
    }

    private static bool IsEmployeeLastNameVeryShort(Employee employee)
    {
        return employee.LastName.Length < LastNameMinimumLength;
    }

    private static string ConcatenateFirstAndLastNames(Employee employee)
    {
        return employee.FirstName + employee.LastName;
    }

    private static string ConcatenateFirstInitialAndLast(Employee employee)
    {
        return employee.FirstName.ElementAt(0) + employee.LastName;
    }
}

Now, small factored methods might not be your thing, particularly if you love debugger (or just love big methods and classes for some reason). But I think you'd be hard pressed to argue that this isn't quite readable and self explanatory. There's no method here that you'd look at, then squint at, then rub your head and say, "what the...?" You have things like "If the last name is very short, set login name to first concatenated to last." This class reads like an instruction manual or... kinda like the version with a bunch of comments. Except unlike that version, your code is actually the comments, so it's impossible for it to become obsolete and misleading.

But I'm not trying to tell you how to code -- I'm trying to tell you how to sell this. I'm trying to tell you how to prove that comments are unnecessary. "How," you ask? Well, put the comments back in and see how completely obtuse they now look:

public class EmployeeDerivedPropertySetter
{
    /// 
    /// The minimum length of the last name
    /// 
    private const int LastNameMinimumLength = 3;

    /// 
    /// Thrown when the first name is empty
    /// 
    public class FirstNameEmptyException : Exception { }

    /// 
    /// Thrown when the last name is empty
    /// 
    public class LastNameEmptyException : Exception { }
    /// 
    /// This is a collection of employees that the constructor will pass in
    /// 
    private readonly IEnumerable _employeesPassedInFromConstructor;

    /// 
    /// This constructor takes the class's dependency and initializes it
    /// 
    /// The employees this class will work on
    public EmployeeDerivedPropertySetter(IEnumerable employees)
    {
        //Set the employee variable to the passed in value
        _employeesPassedInFromConstructor = employees;
    }

    /// 
    /// Sets up the employees by setting derived properties
    /// 
    public void SetupDerivedProperties()
    {
        //Cycle through the employees
        foreach (var employee in _employeesPassedInFromConstructor)
            SetupDerivedProperties(employee);
    }

    /// 
    /// Setup the derived properties
    /// 
    /// Employee to set them up for
    private static void SetupDerivedProperties(Employee employee)
    {
        //Make sure a valid first name and last name are entered
        ValidateFirstAndLastName(employee);
        //Set the employee's login name
        SetLoginName(employee);
    }

    /// 
    /// Validate the first and last name of the employee
    /// 
    /// The employee to validate
    private static void ValidateFirstAndLastName(Employee employee)
    {
        //If first name is null or empty throw an exception
        if (string.IsNullOrEmpty(employee.FirstName))
            throw new FirstNameEmptyException();
        //If last name is null or empty, throw an exception
        if (string.IsNullOrEmpty(employee.LastName))
            throw new LastNameEmptyException();
    }

    /// 
    /// Set the employee's login name
    /// 
    /// Employee whose login name to set
    private static void SetLoginName(Employee employee)
    {
        //If the employee has a very short last name, then user first concatenated to last
        if (IsEmployeeLastNameVeryShort(employee))
            employee.LoginName = ConcatenateFirstAndLastNames(employee);
        else //Otherwise, use first initial concatenated to last name
            employee.LoginName = ConcatenateFirstInitialAndLast(employee);
    }

    /// 
    /// Returns true if the employee last name is very short
    /// 
    /// Employee to check for a short last name
    /// True if the last name is very short, false if not
    private static bool IsEmployeeLastNameVeryShort(Employee employee)
    {
        //Returns whether or not the last name's length is shorter than the minimum length of the last name
        return employee.LastName.Length < LastNameMinimumLength;
    }

    /// 
    /// Concatenate an employee's first and last name
    /// 
    /// Employee whose first and last name to calculate
    /// The concatenated first and last name
    private static string ConcatenateFirstAndLastNames(Employee employee)
    {
        //Concatenate the first and last names of the employee
        return employee.FirstName + employee.LastName;
    }

    /// 
    /// Concatenates the first initial and last name of the employee
    /// 
    /// Employee whose first initial and last name to concatenate
    /// The concatenated first initial and last name
    private static string ConcatenateFirstInitialAndLast(Employee employee)
    {
        //Concatenate the first initial and last name of the employee
        return employee.FirstName.ElementAt(0) + employee.LastName;
    }
}

I think you'd be hard pressed to find someone who thought that this level of commenting on this self-describing code made any sense. That's the beauty of this demonstration -- more even than just the self documenting code, adding comments next to it demonstrate that there's really nothing left to say. And hey, if this gambit backfires and you find someone who thinks this is a good idea, you've learned a valuable piece of information about someone to bear in mind when considering which projects to work on and where to work in the future. In all seriousness, though, I think this will do a fairly good job of demonstrating that you can express the vast majority of what you would express in comments with the code itself.

There is another very practical benefit to proving this and the resulting Spartan approach to comments beyond the fact that the comments and code tend not to get out of sync; when comments are a rarity, you're more likely to read them. Think of heavily commented code as "The Code that Cried Wolf." If you see a lot of code that looks like the code in this snippet immediately above, don't you start to just kind of tune out the comments? They appear in some other color than the main code, and rather than information, they become comforting white noise, separating your methods and fields from one another the way a little bit of margin/padding separates a bunch of text boxes on the form from one another. You don't study the buffering space -- you just take it for granted. This is how it works with over-commented code bases. If you find yourself in code bases like this, do an exercise and ask yourself when the last time you paid attention to a comment was. Yesterday? Last week? Last month? Now ask yourself how many times you've looked at the code since then? A hundred? A thousand? Ten thousand? That's a pretty low percentage of time that you pay attention to comments.

But imagine a code base with almost no comments. You're flipping between classes and looking at methods, and there's no extras -- just code. Now, you open some class and there's a big, fat, 10 line comment. Betcha notice it immediately and, what's more, betcha read it. And, I'm also willing to wager it's worth reading. If a code base has an absence of noise comments, the developer that wrote this one probably has something important to say: why he chose to do it this way even though it seems obtuse or where she found a template/inspiration for this code via google and why she chose to use it.

Method, parameter, class, and variable names can tell you a lot about what the code elements are. Source control checkin comments can tell you a lot about why various changes were made. Unit tests/BDD Tests/Integration tests can tell you a lot about business rules and requirements. None of these things require adding redundancy to the code itself. Comments in your code should be the exception rather than the rule. And you can prove it.

By

How Not to Be Blocked

In a recent post, I talked about how demoralizing it can be to sit around with nothing to do while waiting for someone else to finish a task that you need, fix something that you need, assign you something, etc. I think this is fairly universally known as “being blocked”. It seems nice to have an excuse to do nothing, but I think it makes anyone conscientious a little nervous that someone is going to come along and judge them for malingering, which is rather stressful.

I didn’t really go into details there, but there are many ways to be active, rather than reactive, about being blocked (I think most would have said “proactive”, but I think I kind of hate that word for seeming bombastically redundant — but don’t mind me if you use it because I’m weirdly picky and fussy about words). Taking action not to be blocked has a variety of benefits: alleviates boredom, helps your company, boosts your reputation, opens up potential additional opportunities, etc. The way I see it, being blocked is something that you can almost always manage and opt out of. When I worked in retail many years ago, there was an adage of “if there’s time to lean, there’s time to clean.” I would say the equivalent in the world of software development is “if you’re blocked, you aren’t trying hard enough.”

Things to do when you’re blocked:

  1. Start a wiki or sharepoint site. There’s no company or domain out there that can’t use more documentation and information for onboarding and general reference. And these collaboration mechanisms are perfect since they’re designed to be imperfect at first and refined over the course of time.
  2. Get a subscription to pluralsight and polish your skills. Whether for the sake of the company or the sake of your own career, there’s no engineer that couldn’t use a few new useful tidbits.
  3. Get ahold of a backlog of defects or nettlesome issues for one of the pieces of software your group writes/maintains, create a playpen, and dive in. You’ll learn more about the code and you might even solve one or more issues that have plagued the team for a while.
  4. Identify a pain point for your fellow developers and do something about it. For instance, if merges constantly mess up a file in your code base, write a utility they can use to validate that file. It’s a lot more useful to the company than reading reddit or slashdot and it’ll boost your cred with your fellow developers as well (that is, help you pass “the second test“).
  5. Ask the people around you if they need a hand with anything. There are often people willing to offload a task or two, especially if it’s grunt work or if they’re stressed and you’re keeping yourself busy and earning some pennies in heaven doing this.
  6. Offer to go through an existing code base, adding or creating documentation for it. This has the useful dual purpose of improving documentation and helping you learn the code. When you know something well enough to explain it to others, you know it pretty well.
  7. Abstract, abstract, abstract. If it’s a development task, make an assumption about the info you’re waiting on, and code the rest of the system as if this assumption were true. Then code the system in such a way that changing your assumption is simple. For instance, don’t say “I can’t work until we decide what RDBMS to use — just write some kind of CRUD interface that your system uses with no implementation and go on your merry way.

I think that’s more than enough ammunition to ensure that you’ll always have some non-loafing task to do at the office. If you can find a situation where none of those things is an option, then my hat’s off to you or, perhaps more appropriately, my sympathy goes out to you because you probably need to find a new job. But maybe you can take steps to avoid being blocked in the first place. This list is a bit more abstract and a much less foolproof, but I’d suggest the following practices to avoid being blocked in general.

  1. Seek out situations where you have multiple assignments at once. This requires managing expectations and good organization and prioritization skills, but the end result is that you’ll have approved, productive work to fall back on even when waiting for answers.
  2. Cultivate a healthy knowledge of the problem domain you’re working on. In my experience, a lot of blocking results from needing someone to tell you what “Taking the EBE out of the PHG with the ERBD” means. The more domain knowledge you have, the more chance you have of deciphering cryptic acronyms and jargon code that prevents you from figuring out what to do next.
  3. Seek out areas in which you’re the main decision maker, however small they may be. I understand that you cant’t exactly promote yourself to VP of Engineering, but if you seek out being in charge of something, even if it’s just a small, low priority tool or something ancillary, you
    are unlikely to be truly blocked.
  4. Become resident expert in some technology, product, facet of the business or tool that matters. Generally people who are expects (e.g. the database expert or the source control expert) are in high demand and can fill any lulls with meetings and cooperative sessions with those seeking their expertise.

If you have other ways to avoid being blocked, I’d be interested to hear about them in the comments. I think avoiding blockages is critical not only for preserving your reputation, but preserving your sense of purpose and, on a long enough timeline, your engagement and work ethic. Don’t fall into the trap of checking out due to lack of stuff to do. Make sure you have stuff to do. And, if all else fails, move on. Or, to adapt an aphorism I’ve heard from enough places so as to be unsure of the original source, “change your work circumstances or… change your work circumstances.”