Button’s Law of Design Maturity

The prevalence of Singletons in a design is inversely proportional to the maturity of the design, and the designers.

Be it known, that from this day forward, this shall be known as Button’s Law. (Just kidding)

There is a note a truth here, however. I’ve talked to a lot of the best designers that I know in the field, and we all share a common opinion. (Not that I’m putting myself in the same class as these developers. I’m merely stating that we share the same opinion!!!) Singletons can be a useful pattern, but they are also the most abused pattern seen in the wild. You can read about my personal feelings about singletons in Scott Densmore’s blog.

Joshua Kerievsky has written an excellent summary of this point of view in his new book, Refactoring to Patterns. Reading this chapter in his book is what brought this rant to mind.

I now return you to your regularly scheduled programming.

— bab

11 thoughts to “Button’s Law of Design Maturity”

  1. I agree with most of what’s already been said, but I do see some uses like HttpContext.Current that are pretty handy. Then again global vars are pretty handy and so is coffee. šŸ™‚

    You’re preference would either be reference by pass (ctor/method) or, minimally, exposing the singleton as only IHttpContext (e.g.)?

  2. The problem with creating a singleton is that when you create it it makes design sense, but it leaves you open to problems down the road. Say you have a singleton for all the parameters of your system and you use that in a servlet handler.

    ApplicationResources messages = ApplicationResources.getInstance();



    messages.getMessage("date.format");

    where getInstance() returns a static instance of ApplicationResources.

    Then, sometime down the road you decide to implement a convience method for the date format.

    Date myDate = messages.parseDate("date.format", date);

    The problem is that parseDate will look like a thread safe method but every so often myDate will be totally wrong, because it isn’t thread safe and myDate will by yourDate. I would say just avoid the singleton.

    Tim

  3. In fact, this is why in the entire .NET Framework (v.1.1) there are just 3 singleton classes: System.DBNull, Microsoft.JScript.Empty and Microsoft.JScript.Missing. šŸ™‚

    But version 2.0 of the Framework will add another 7: System.Empty, System.Reflection.Missing, System.Data.Odbc.OdbcFactory, System.Data.OleDb.OleDbFactory, System.Data.ProviderBase.DbConnectionPoolIdentity, System.Data.SqlClient.SqlClientFactory and System.Data.OracleClient.OracleClientFactory.

  4. Nothing to do with singletons, but coincidentally I also noticed an anti-metric (i.e. one to be minimized) yesterday: ifs/kloc (i.e. # of if statements per 1000 lines of code). It was just a "gut feel" initially, but I guess my reasoning was that too many ifs suggest either too little, or incorrect, usage of OO features.

  5. Good stuff. I’ve looked at singletons, but the only one I ever wanted to implement (and got a friend to implement) was a client-side app where I didn’t want my hotkey (winkey!) to keep creating new instances of the app and instead bring it to the front.

  6. Grant,

    <pre>

    I agree with most of what’s already been said, but I do see some uses like HttpContext.Current that are pretty handy. Then again global vars are pretty handy and so is coffee. šŸ™‚

    You’re preference would either be reference by pass (ctor/method) or, minimally, exposing the singleton as only IHttpContext (e.g.)?

    </pre>

    The way I usually use singletons when I have to is to put access to them at the head of a thread of control, and then pass them into my code to where ever they are needed beneath there. That gives me the advantages of the singleton (global access and limited creation), but still gives me the ability to pass one into a particular method call during unit testing, etc. So, my preference is, in deed, to pass them where they are needed.

  7. Paul,

    I love that metric! I read another blog entry about that a few days ago where the author was talking about if statements that check stuff internal to your code were missed opportunities for polymorphism, and the only valid reason for having them was in checking things that were outside in your environment.

    Maybe we saw this in the same place???

    — bab

  8. Nice one. Some say singletons are bad because they are glorified global variables. But they get better when folks:

    1. Have derived singleton classes that share state with base classes.

    2. Have destory methods. (After which others can recreate them indirectly.)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.