Strongly Typed Primitives


No, I’m not talking about NEANDERTHALS (there’s a joke in there somewhere), but rather a technique that a colleague of mine, Josh Twist, has recently blogged about – “Avoiding Primitive Obsession to tip developers into the pit of success”. I’d always seen a pit as symbolic of failure, so I’m pretty pleased there’s such a thing as a pit of success – improves my odds massively J


I’ve drawn attention to this because it is an approach I discovered a few years back, and I love it. I just use a slightly different implementation to Josh;


public class Command


{


    #region Structure


 


    private string _name;


 


    private Command(string name)


    {


        _name = name;


    }


 


    public string Name


    {


        get


        {


            return _name;


        }


    }


 


    #endregion


 


    #region Instances


 


    public static Command Profile = new Command(“Profile”);


    public static Command WebExecute = new Command(“WebExecute”);


 


    #endregion


}


You can see that I use a single class to encapsulate both the behaviour of the Command class and the static instances of a Command.


I can’t really think of a convincing reason why one of these would be better over the other to be honest – I guess Josh’s approach means you could have different collections of commands (WebCommands, WindowsCommands, SomeOtherCommands), but I’ve never needed to do that. Any other reasons you can think of?


Still – read Josh’s post and see what you think. This kind of pattern is so simple yet so effective at eliminating mistypes, increasing code readability, and improving refactoring (just try deleting a command type and watch that compiler pick up everywhere you need to make a change!).


Good stuff.

Comments (7)

  1. Josh says:

    Thanks Simon,

    “I can’t really think of a convincing reason why one of these would be better over the other to be honest – I guess Josh’s approach means you could have different collections of commands (WebCommands, WindowsCommands, SomeOtherCommands), but I’ve never needed to do that. Any other reasons you can think of?”

    Imagine you write a logging component (generic example again) for use throughout your enterprise and you want to use stongly typed primitives (nice turn of phrase btw). You can’t know now all the possible entries that people would want to use. So the primitive itself lives next to the logging component itself but the instances of the primitives would live in a separate assembly per application that uses the component.

  2. simonince says:

    @ Josh;

    I like it. In fact, come to think of it there are similarities to when I was building a navigation framework targeting both web and windows. I made a vague reference to this with my "Screen" class here;

    http://blogs.msdn.com/simonince/archive/2008/06/16/wcsf-application-architecture-4-environment-abstraction.aspx

    I forget exactly how it worked but I had to create different instances of the class because I wanted to use it to encapsulate information about how to actually navigate to a screen too – which obviously is very different in the web and windows worlds.

    Hmm.

    OK, so I think my approach is the version for beginners, yours is the posh one 🙂

  3. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  4. MichaelGG says:

    You can also make it generic so everything can fit in a small static class:

    public static class Command

    {

       public static readonly Id<Command> Profile = (Id<Command>)"Profile";

       public static readonly Id<Command> WebExecute = new (Id<Command>"WebExecute";

    }

    Now the type name is just a marker so you can do everything with a single class, and just pick the best name (Command versus CommandName). I posted the code I use here:

    http://www.atrevido.net/blog/2008/08/15/Typing+String+IDs.aspx

    (Although, if you don’t care about performance and nullability issues, a class-based inheritance system may provide more benefits.)

  5. simonince says:

    @ Michael;

    nice post, and good point. I think the only thing about using generics is that you can’t use the class to store more information. So although Josh’s example is for strings, I’ve used this approach to store a string name and a string URL together – which makes defining a generic to cover all situations difficult.

    Having said that, I totally agree in a lot of cases it would work.

    One minor point – I’m not sure I like casting to an Id<Command> – I’d always prefer the ‘new Id<Command>("WebExecute")’ syntax, as it seems more explicit. Just personal taste, perhaps!

    Simon

  6. MichaelGG says:

    Ah, yes, keeping multiple items would be a pain right now. More reason to lean on the .NET teams to add tuples as first class citizens :).