Evening. I'm having trouble finding an appropriate design pattern for some situations of deep composition. Let me present an example.
Let's say we have a class of type Corporation that has many classes of type Subsidiary that have many classes of type Department that in type contain many classes of type Unit that in turn contain many classes of type Employee.
Now, suppose the use case is to count the number of employees for each corporation. I could loop through each corpration, loop again for each subsidiary, and so on and so forth, in something that would result in a nested loop, 4 levels deep. Plus, I would be breaking the Law of Demeter by referencing my class chain several levels below, something that is so tightly couped it would break the very moment I modified my chain.
Another thing I could do is add tons (ok maybe not tons, but a few) of shortcut references. For example, a corporation could itself ALSO contain a list of Employees resulting in never having to walk through the chain to count them. This way, classes are less tightly coupled (but are they?) and the issue now becomes how to keep the Employee list synced for both the Corporation and the Unit. I could use the Observer pattern to keep them updated I suppose but I really feel something's horribly wrong with this idea or, at the very least, I'm not really using the best solution out there.
As I'm pretty sure this is an extremely common domain, could anyone be kind enough as to point me to an appropriate design pattern?
Thanks.
I don't exactly get the second question but I am answering the first question.
So using that principle in your design
Better Client code with Law of Demeter:
Without Law of Demeter
UPDATE:
Using the above stated solution you can go in as many depths as you want by creating the
countEmployees()
method insideSubsidiaries
and inUnit
as required. There is no point in breaking the encapsulation or using Observer pattern here.Apply the Tell Don't ask principle as you have pointed in the comment yourself and delegate the responsibility of calculating the actual employees on the class that contains employees.