Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Design and Architecture
  4. Composition/Aggregation law of demeter

Composition/Aggregation law of demeter

Scheduled Pinned Locked Moved Design and Architecture
questionarchitecturediscussion
15 Posts 6 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    DiiJAY
    wrote on last edited by
    #1

    Hi, I have question regarding architecture when dealing with composition/aggregation hierarchy. The three classes below "House", "Room" and "Door" describes a simple nested architecture used for this question. This architecture means that when I use a House object and want to refer to a door nested in a Room I will brake the "Law of demeter" rule that states that I should only use direct connection like House.ToString() not indirect connection like House.Room.Door.ToString(), is this okay or bad practise, is there any better way of organising the architecture? Would it be better to do helper functions for the door in the Room Class, and not expose a Door object public, like: DoorOpen(); DoorClose(); If this arhitecture is prefered, what should be done with the events inside the Door class, should they also be defined once again in the Room class and be "chained" back thru it's parent classes some way ? Any thoughts, tips and ideas would be helpful. public class House { public House() { Room = new Room(); } public Room Room { get; private set; } } public class Room { public Room() { Door = new Door(); } public Door Door { get; private set; } } public class Door { public event EventHandler<EventArgs> OnOpen; public event EventHandler<EventArgs> OnClose; private bool _isOpen; public Door() { } public void Open() { _isOpen = true; OnOpen(this, new EventArgs()); } public void Close() { _isOpen = false; OnClose(this, new EventArgs()); } }

    G L P D 4 Replies Last reply
    0
    • D DiiJAY

      Hi, I have question regarding architecture when dealing with composition/aggregation hierarchy. The three classes below "House", "Room" and "Door" describes a simple nested architecture used for this question. This architecture means that when I use a House object and want to refer to a door nested in a Room I will brake the "Law of demeter" rule that states that I should only use direct connection like House.ToString() not indirect connection like House.Room.Door.ToString(), is this okay or bad practise, is there any better way of organising the architecture? Would it be better to do helper functions for the door in the Room Class, and not expose a Door object public, like: DoorOpen(); DoorClose(); If this arhitecture is prefered, what should be done with the events inside the Door class, should they also be defined once again in the Room class and be "chained" back thru it's parent classes some way ? Any thoughts, tips and ideas would be helpful. public class House { public House() { Room = new Room(); } public Room Room { get; private set; } } public class Room { public Room() { Door = new Door(); } public Door Door { get; private set; } } public class Door { public event EventHandler<EventArgs> OnOpen; public event EventHandler<EventArgs> OnClose; private bool _isOpen; public Door() { } public void Open() { _isOpen = true; OnOpen(this, new EventArgs()); } public void Close() { _isOpen = false; OnClose(this, new EventArgs()); } }

      G Offline
      G Offline
      Graham Breach
      wrote on last edited by
      #2

      I don't know if this will help you or not, but internal doors will be shared - two rooms will both have the same door that opens and closes between them.

      1 Reply Last reply
      0
      • D DiiJAY

        Hi, I have question regarding architecture when dealing with composition/aggregation hierarchy. The three classes below "House", "Room" and "Door" describes a simple nested architecture used for this question. This architecture means that when I use a House object and want to refer to a door nested in a Room I will brake the "Law of demeter" rule that states that I should only use direct connection like House.ToString() not indirect connection like House.Room.Door.ToString(), is this okay or bad practise, is there any better way of organising the architecture? Would it be better to do helper functions for the door in the Room Class, and not expose a Door object public, like: DoorOpen(); DoorClose(); If this arhitecture is prefered, what should be done with the events inside the Door class, should they also be defined once again in the Room class and be "chained" back thru it's parent classes some way ? Any thoughts, tips and ideas would be helpful. public class House { public House() { Room = new Room(); } public Room Room { get; private set; } } public class Room { public Room() { Door = new Door(); } public Door Door { get; private set; } } public class Door { public event EventHandler<EventArgs> OnOpen; public event EventHandler<EventArgs> OnClose; private bool _isOpen; public Door() { } public void Open() { _isOpen = true; OnOpen(this, new EventArgs()); } public void Close() { _isOpen = false; OnClose(this, new EventArgs()); } }

        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #3

        yep. Give Room a public CloseAllWindows() method and let it keep the windows to itself. (I substituted windows for doors, to keep Graham happy). :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


        I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


        D 1 Reply Last reply
        0
        • L Luc Pattyn

          yep. Give Room a public CloseAllWindows() method and let it keep the windows to itself. (I substituted windows for doors, to keep Graham happy). :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


          I only read code that is properly formatted, adding PRE tags is the easiest way to obtain that.


          D Offline
          D Offline
          DiiJAY
          wrote on last edited by
          #4

          It's correct a Rooms will share a door in my example, but it was just ment as an example :) So let's continue and consider a window class instead. What happends if I have alot of member data in my Window class should I still use the class 'Window' as a private member inside 'Room' and make "wrapper" Methods and events inside Room like: Room.CleanWindow(int index), Room.OnWindowCleaned(), Room.OpenWindow(int index). etc etc. Sort of chaining methods and events. This seems to duplicate Methods and Eventsin a way, thoughts about this ?

          G J 2 Replies Last reply
          0
          • D DiiJAY

            It's correct a Rooms will share a door in my example, but it was just ment as an example :) So let's continue and consider a window class instead. What happends if I have alot of member data in my Window class should I still use the class 'Window' as a private member inside 'Room' and make "wrapper" Methods and events inside Room like: Room.CleanWindow(int index), Room.OnWindowCleaned(), Room.OpenWindow(int index). etc etc. Sort of chaining methods and events. This seems to duplicate Methods and Eventsin a way, thoughts about this ?

            G Offline
            G Offline
            Graham Breach
            wrote on last edited by
            #5

            One advantage of using "wrapper" methods is that you can use them to do things that the Window class doesn't know about:

            class Room {

            public:
            void OpenWindow(int index)
            {
            try {
            // move plant pots out of the way
            plants[index].Remove();
            windows[index].Open();
            plants[index].Replace();

            } catch(DroppedPlantPotException& dppe) {
            // oops...
            CleanTheFloor();
            }
            }

            private:
            std::vector<Window> windows;
            std::vector<PlantPot> plants;
            };

            1 Reply Last reply
            0
            • D DiiJAY

              It's correct a Rooms will share a door in my example, but it was just ment as an example :) So let's continue and consider a window class instead. What happends if I have alot of member data in my Window class should I still use the class 'Window' as a private member inside 'Room' and make "wrapper" Methods and events inside Room like: Room.CleanWindow(int index), Room.OnWindowCleaned(), Room.OpenWindow(int index). etc etc. Sort of chaining methods and events. This seems to duplicate Methods and Eventsin a way, thoughts about this ?

              J Offline
              J Offline
              Jonathan Davies
              wrote on last edited by
              #6

              To model the real world it seems to me as if you should have a WindowCleaner class which has a public method CleanWindows(House) and which should fire events. Maybe WindowCleaner inherits from WindowOpener or a class Person who is a WindowOpener? The room is pretty inanimate, it's the people who do things - unless this is a very high tech house.

              1 Reply Last reply
              0
              • D DiiJAY

                Hi, I have question regarding architecture when dealing with composition/aggregation hierarchy. The three classes below "House", "Room" and "Door" describes a simple nested architecture used for this question. This architecture means that when I use a House object and want to refer to a door nested in a Room I will brake the "Law of demeter" rule that states that I should only use direct connection like House.ToString() not indirect connection like House.Room.Door.ToString(), is this okay or bad practise, is there any better way of organising the architecture? Would it be better to do helper functions for the door in the Room Class, and not expose a Door object public, like: DoorOpen(); DoorClose(); If this arhitecture is prefered, what should be done with the events inside the Door class, should they also be defined once again in the Room class and be "chained" back thru it's parent classes some way ? Any thoughts, tips and ideas would be helpful. public class House { public House() { Room = new Room(); } public Room Room { get; private set; } } public class Room { public Room() { Door = new Door(); } public Door Door { get; private set; } } public class Door { public event EventHandler<EventArgs> OnOpen; public event EventHandler<EventArgs> OnClose; private bool _isOpen; public Door() { } public void Open() { _isOpen = true; OnOpen(this, new EventArgs()); } public void Close() { _isOpen = false; OnClose(this, new EventArgs()); } }

                P Offline
                P Offline
                Pete OHanlon
                wrote on last edited by
                #7

                There are various patterns that you could apply here, but the one that immediately springs to mind here is that you could use a Mediator here. Depending on the implementation of the Mediator, what you might want to do is:

                public class Door
                {
                public Door()
                {
                }

                public void Open()
                {
                _isOpen = true;
                Mediator.Instance.NotifyColleagues(DoorState.Open);
                }

                public void Close()
                {
                _isOpen = false;
                Mediator.Instance.NotifyColleagues(DoorState.Closed);
                }
                }

                public class House
                {
                private int _ambientTemperature = 22;

                public House()
                {
                Mediator.Instance.Register((object o) => { _ambientTemperature -= 2; }, DoorState.Open);
                Mediator.Instance.Register((object o) => { _ambientTemperature += 2; }, DoorState.Closed);
                }
                }

                In this example, House is decoupled from Door; it registers an interest in the DoorState messages and reacts accordingly without any events having to tunnel up. It's the responsibility of the Mediator to route the message to the appropriate targets, so everything becomes nice and decoupled - more importantly, this is easily testable. If you want a sample Mediator, this is based around the one I use here[^].

                "WPF has many lovers. It's a veritable porn star!" - Josh Smith

                As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.

                My blog | My articles | MoXAML PowerToys | Onyx

                1 Reply Last reply
                0
                • D DiiJAY

                  Hi, I have question regarding architecture when dealing with composition/aggregation hierarchy. The three classes below "House", "Room" and "Door" describes a simple nested architecture used for this question. This architecture means that when I use a House object and want to refer to a door nested in a Room I will brake the "Law of demeter" rule that states that I should only use direct connection like House.ToString() not indirect connection like House.Room.Door.ToString(), is this okay or bad practise, is there any better way of organising the architecture? Would it be better to do helper functions for the door in the Room Class, and not expose a Door object public, like: DoorOpen(); DoorClose(); If this arhitecture is prefered, what should be done with the events inside the Door class, should they also be defined once again in the Room class and be "chained" back thru it's parent classes some way ? Any thoughts, tips and ideas would be helpful. public class House { public House() { Room = new Room(); } public Room Room { get; private set; } } public class Room { public Room() { Door = new Door(); } public Door Door { get; private set; } } public class Door { public event EventHandler<EventArgs> OnOpen; public event EventHandler<EventArgs> OnClose; private bool _isOpen; public Door() { } public void Open() { _isOpen = true; OnOpen(this, new EventArgs()); } public void Close() { _isOpen = false; OnClose(this, new EventArgs()); } }

                  D Offline
                  D Offline
                  DiiJAY
                  wrote on last edited by
                  #8

                  Thanx for the responses. The classes "House", "Room", "Door" was just an example, I'm not looking for designs to solve the specific design of a House which have a CleanWindow method. :) I will try to rephrase my question. The question is about nested class architecute with composition/aggregation, it could be anything that tries to model the real world, but in this specific question it's not important what it is, just that composition/aggregation is uesd, see below for examples of nested class structures, maybe these aren't the best examples but there must be valid relationsships like this in reel world: Computer/Cpu/Processor Database/Table/Column The question is should I use, which sort breaks the law of demeter: Computer.Motherboard.Cpu.Temperature(); Computer.Motherboard.Cpu.IsOverheated(); Or should I make "Motherboard" and "Cpu" private and wrap/chain method calls and events thru the nested structure: Computer.CpuTemperature() Computer.CpuIsOverheated() I hope the question is clearer this time.

                  J 1 Reply Last reply
                  0
                  • D DiiJAY

                    Thanx for the responses. The classes "House", "Room", "Door" was just an example, I'm not looking for designs to solve the specific design of a House which have a CleanWindow method. :) I will try to rephrase my question. The question is about nested class architecute with composition/aggregation, it could be anything that tries to model the real world, but in this specific question it's not important what it is, just that composition/aggregation is uesd, see below for examples of nested class structures, maybe these aren't the best examples but there must be valid relationsships like this in reel world: Computer/Cpu/Processor Database/Table/Column The question is should I use, which sort breaks the law of demeter: Computer.Motherboard.Cpu.Temperature(); Computer.Motherboard.Cpu.IsOverheated(); Or should I make "Motherboard" and "Cpu" private and wrap/chain method calls and events thru the nested structure: Computer.CpuTemperature() Computer.CpuIsOverheated() I hope the question is clearer this time.

                    J Offline
                    J Offline
                    Jonathan Davies
                    wrote on last edited by
                    #9

                    Based on this[^] your first example pair fails due to "too many dots".

                    D 1 Reply Last reply
                    0
                    • J Jonathan Davies

                      Based on this[^] your first example pair fails due to "too many dots".

                      D Offline
                      D Offline
                      DiiJAY
                      wrote on last edited by
                      #10

                      Ok, So it will be a benefit to make nested classes private and create extra code for wrapper methods and events in the main class for this sort of architecture instead of make a direct connection to the Cpu object?, will this even be true if I referenced Motherboard and Cpu as interfaces ?

                      J 1 Reply Last reply
                      0
                      • D DiiJAY

                        Ok, So it will be a benefit to make nested classes private and create extra code for wrapper methods and events in the main class for this sort of architecture instead of make a direct connection to the Cpu object?, will this even be true if I referenced Motherboard and Cpu as interfaces ?

                        J Offline
                        J Offline
                        Jonathan Davies
                        wrote on last edited by
                        #11

                        DiiJAY wrote:

                        Ok, So it will be a benefit to make nested classes private and create extra code for wrapper methods and events in the main class for this sort of architecture instead of make a direct connection to the Cpu object?

                        Yes. Using Computer.Motherboard.Cpu.IsOverheated() means the calling code has to know about not only Computer class but also the the Motherboard and Cpu classes as well. Using just Computer.CpuIsOverheated() means the caller doesn't know about, or care, how the temperature is obtained internally. As an example of the benefit, if you upgraded your PC with a motherboard that had 4 parallel CPUs the call to Computer.CpuIsOverheated() will still work from the caller's perspective. Internally the new motherboard code might average out the temperature of the 4 CPUs but this internal change is hidden from the caller. With this upgrade the Computer.Motherboard.Cpu.IsOverheated(); call runs into problems: Which of the 4 CPUs does this call refer to?

                        DiiJAY wrote:

                        will this even be true if I referenced Motherboard and Cpu as interfaces ?

                        Interfaces I use to refer to a set of related methods, if you wanted the temperature of, say, a Car, Room and a PC an ITemperature interface with a ITemperature.GetTemp() method would be handy but you would still want to hide your Motherboard and Cpu classes for the reasons already mentioned.

                        D D 2 Replies Last reply
                        0
                        • J Jonathan Davies

                          DiiJAY wrote:

                          Ok, So it will be a benefit to make nested classes private and create extra code for wrapper methods and events in the main class for this sort of architecture instead of make a direct connection to the Cpu object?

                          Yes. Using Computer.Motherboard.Cpu.IsOverheated() means the calling code has to know about not only Computer class but also the the Motherboard and Cpu classes as well. Using just Computer.CpuIsOverheated() means the caller doesn't know about, or care, how the temperature is obtained internally. As an example of the benefit, if you upgraded your PC with a motherboard that had 4 parallel CPUs the call to Computer.CpuIsOverheated() will still work from the caller's perspective. Internally the new motherboard code might average out the temperature of the 4 CPUs but this internal change is hidden from the caller. With this upgrade the Computer.Motherboard.Cpu.IsOverheated(); call runs into problems: Which of the 4 CPUs does this call refer to?

                          DiiJAY wrote:

                          will this even be true if I referenced Motherboard and Cpu as interfaces ?

                          Interfaces I use to refer to a set of related methods, if you wanted the temperature of, say, a Car, Room and a PC an ITemperature interface with a ITemperature.GetTemp() method would be handy but you would still want to hide your Motherboard and Cpu classes for the reasons already mentioned.

                          D Offline
                          D Offline
                          DiiJAY
                          wrote on last edited by
                          #12

                          Thank you Jonathan, that made the picture clear!

                          J 1 Reply Last reply
                          0
                          • D DiiJAY

                            Thank you Jonathan, that made the picture clear!

                            J Offline
                            J Offline
                            Jonathan Davies
                            wrote on last edited by
                            #13

                            Glad to be of help.

                            1 Reply Last reply
                            0
                            • J Jonathan Davies

                              DiiJAY wrote:

                              Ok, So it will be a benefit to make nested classes private and create extra code for wrapper methods and events in the main class for this sort of architecture instead of make a direct connection to the Cpu object?

                              Yes. Using Computer.Motherboard.Cpu.IsOverheated() means the calling code has to know about not only Computer class but also the the Motherboard and Cpu classes as well. Using just Computer.CpuIsOverheated() means the caller doesn't know about, or care, how the temperature is obtained internally. As an example of the benefit, if you upgraded your PC with a motherboard that had 4 parallel CPUs the call to Computer.CpuIsOverheated() will still work from the caller's perspective. Internally the new motherboard code might average out the temperature of the 4 CPUs but this internal change is hidden from the caller. With this upgrade the Computer.Motherboard.Cpu.IsOverheated(); call runs into problems: Which of the 4 CPUs does this call refer to?

                              DiiJAY wrote:

                              will this even be true if I referenced Motherboard and Cpu as interfaces ?

                              Interfaces I use to refer to a set of related methods, if you wanted the temperature of, say, a Car, Room and a PC an ITemperature interface with a ITemperature.GetTemp() method would be handy but you would still want to hide your Motherboard and Cpu classes for the reasons already mentioned.

                              D Offline
                              D Offline
                              David Skelly
                              wrote on last edited by
                              #14

                              All very true and all good advice. However, the danger is that your Computer interface is going to become very bloated. Consider that a computer contains not just a motherboard and one or more CPUs, but also hard drives, a USB bus (plus any USB devices which may or may not be connected), a floppy drive (if your computer is as old as mine), a graphics card, a network card, a sound card, RAM, etc. etc. etc. (I'm sure you can think of a few more components.) Exposing every possible operation for every possible component through the Computer class interface leads to a very unwieldy design. The danger is that your Computer class becomes a sort of "god" object which tries to do everything and be all things to all men. There are no hard and fast rules for object design. There is a certain amount of give and take to end up with the best solution, balancing one consideration against another.

                              J 1 Reply Last reply
                              0
                              • D David Skelly

                                All very true and all good advice. However, the danger is that your Computer interface is going to become very bloated. Consider that a computer contains not just a motherboard and one or more CPUs, but also hard drives, a USB bus (plus any USB devices which may or may not be connected), a floppy drive (if your computer is as old as mine), a graphics card, a network card, a sound card, RAM, etc. etc. etc. (I'm sure you can think of a few more components.) Exposing every possible operation for every possible component through the Computer class interface leads to a very unwieldy design. The danger is that your Computer class becomes a sort of "god" object which tries to do everything and be all things to all men. There are no hard and fast rules for object design. There is a certain amount of give and take to end up with the best solution, balancing one consideration against another.

                                J Offline
                                J Offline
                                Jonathan Davies
                                wrote on last edited by
                                #15

                                I agree. In general I'm all for an architecture designed someone who recognises there can be rules there in the first place. Investigating what the Law of demeter is (I knew the principle but not the actual rule) and why it's used, and why in other cases it's perhaps not used, can only be a good thing.

                                modified on Tuesday, March 9, 2010 5:41 AM

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups