Domain Object Model and the Law of Demeter. RRS feed

  • Question

  • Hey folks, first of all thanks everyenu for contributing to my last question; not sure how to mark it off except to make it a discussion. Thanks though. Helped a lot.

    Another issue has raised it's head and this always seems to come about when I develop and the clue is in the posts title. Here is the situation.

    I create an object model, usually a hierarchy of object with a top level root object going down levels into child object that themselves have child objects. Here is a small example from my current project.

        public class Input
            public ProjectInformation ProjectInformation { get; set; }

            public Options Options { get; set; }

            public Plant Plant { get; set; }

            public Load DesignLoad
                get { return this.loads.Where(load => load.IsDesignLoad).First(); }

    Ok so you can see the Input class, the root object, is made up of other child classes ProjectInformation, Options, Plant and Load.  Ok lets look at some of the Load class.

        public class Load
            public string Name { get; set; }

            public Fuel Fuel { get; set; }
            public CombustionHeat CombustionHeat { get; set; }
            public CombustionAir CombustionAir { get; set; }

    Ok the Load class is made up some other child objects Fuel, Heat, and Air. Lets look at the Fuel class.....

         public class Fuel
            public Coal Coal { get; set; }

            public Gas Gas { get; set; }

            public Oil Oil { get; set; }

    ... ok so you seeing the idea...


    If you have any immediate comments about this design approach them let me know. Most of the software I write tends ta have this sort of tree of objects and if it's wrong or if there is a better way then please please let me know.


    Ok so I have this tree of objects that represents Input and this is where the information comes from when doing processing... calculations...

    What I'm finding, and it tends to happen, is I write code like this....

                double[] airFlowRatesExc = input.DesignLoad.AirFlow;
                double[] coalFlowRates = input.DesignLoad.Fuel.Coal.FlowRates.PARate;

    See the train crash?!

    Law of Demeter does not apply and I have a horrible feeling it's going to bite me some day in the not to distant future.

    The last thing I want to do is have a host of methods on the root Input object that return data from the lowest level in the object tree, well I say the last thing but what I mean by that is if there was an easy way to do it then I would but ... I'm sure you know what I'm getting at.


    What's going through your mind right now reading this?

    What's your opinion of creating the tree of objects like that? in there an alternative, or a suitable alternative approach that you would recommend and have used?

    How about the law of demeter; is it a law?

    Anything you have to say folks.


    "The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination." - Fred Brooks
    Friday, June 10, 2011 8:35 AM

All replies

  • You seem to have a lot of levels there mate.

    Why is there an input class at all?

    Next thought is why are your calculations carried out way up there in the top class.


    Are these objects you have there really objects or are they just classifications of input?

    Could you just have regions rather than classes for some of them?


    I tend to apply the rule of 4 effs.

    That's the four fan fold fingers rule.

    It dates back to when I used to work in cobol and read fan fold printouts.

    Going down a level to a different procedure ( object/class) I'd stick a finger in the fan fold where I was going from.

    About the time I ran out of fingers I'd have completely lost track of all the levels I had come down to get wherever I was.

    Not a hard and fast rule but something to consider.

    Friday, June 10, 2011 10:03 AM
  • Hey Andy, thanks for your post.

    Yeah there are a few child levels in the object tree. 

    Been thinking of what you posted about whether the classes that are listed are regions or classes and for some places they could be considered regions. ProjectInformation and Configuration are not real work objects and yeah could be considered more of a classification / region.  Well ... configuration could be real world, the configuration of the thing. But most of the classes in the code are real world objects or represent real world things and their relationships.

    For example Fuel is a real tangable thing in they system and it's composed of a mixture of Coal, Oil and Gas, which themselves are real things.

    The more I think of it the more it makes sense; the other option would be to flatten the tree into a collection of dictionaries. That would work and would have been nice but I'd lose a certain amount of type safety. Everything in the dictionary approach would be of type object.

    Your absolutely right though the deep level in the object tree is what's conflicting with the law of demeter and causing the train crash code. 

    So I've been thinking how can the tree remain, because it feels accurate, with the deep levels but be accessed like things were flat. The visitors design pattern!


    What this has done is seperated out the processing that's done on the tree from the structure of the tree. It works very well and provides a lot of options in adding new features without worrying to much about the impact of structural changes to the tree. Well to a degree. The visitor pattern treats each type of object in the tree as seperate from other types of objects. It's not perfect but think I'll go with it.



    "The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination." - Fred Brooks
    Monday, June 13, 2011 12:53 PM