The Perils of Object Oriented Spaghetti (or Law of Demeter and Singletons)

Law of Demeter or Principle of Least Knowledge is a simple design style for developing software that purportedly results in a lower coupling between elements of a computer program.  Lower coupling is beneficial as it results in code which is easier to maintain and understand. 

It is the opinion of this programmer however that the Law of Demeter is in fact a load of old toot (rubbish) as it advocates invoking methods on global objects: this is in contradiction to a "Principle of Least Knowledge".  "For pragmatic reasons" are weasel words.  Global variables (non-constants) are bad, period.

On a related matter singletons are an anti-pattern as well as a pattern; use rarely not routinely.  Singletons are little more than disguised global variables and do themselves violate a principle of least knowledge resulting in tighter coupling/hidden dependencies (or object oriented "spaghetti" code) as well as being problematic for multi-threaded designs.  One easy way to avoid singletons is the following:

With Singleton (C++) Without Singleton (C++)

struct model
{
    static model& instance()
    {
        // this is the "Meyers Singleton"
        static model sInstance;
        return sInstance;
    }

    void foo()
    {
        // ...
    }
};

struct client
{
    client() {}

    void bar()
    {
        model::instance().foo();
        /* if this function was not inline it
           would not be obvious that bar()
           depends on model */
    }
};

int main()
{
    client theClient;
    /* not obvious that client
       depends on model */
    theClient.bar();
}

struct model
{
    void foo()
    {
        // ...
    }
};

struct client
{
    model& iModel;
 
    client(model& aModel) : iModel(aModel) {}

    void bar()
    {
        iModel.foo();
    }
};

int main()
{
    model theModel;
    client theClient(theModel);
    theClient.bar();
}

Making your object dependencies and construction order explicit as shown above will save headaches later on as your design increases in complexity.

Of course it is not always possible to avoid singletons; one example is when you have an external entry point into your program other than main (e.g. a C callback function in a DLL) that doesn't provide context information via a parameter.

____━━____┓━╭━━━━━━╮
____━━____┗┓|::::::::^━━━━^
____━━____━┗|:::::::::|。◕‿‿ ◕。|
____━━____━━╰O--O-O--O ╯

18 Dec 2009

You can e-mail comments to the author.

Back to home page