Composition And Aggregation

This article describes Composition and Aggregation

Composition

In general terms, composition is a process of combining two or more elements to form a whole in such a way that the life of all the elements depend on each other.

In computing terms, Composition is a special form of Association where entities becomes a part-of relationship or association which means the life of one entity becomes dependent on one other. For example, a section becomes a part of an Article – if you delete an article then all the sections contained within that article will be removed along with that article.

Looking at the relationship termed Composition, we can easily figure out that one entity becomes a composite object and others becomes components of a composite object, for example Article is a composite object whereas Section becomes a component of composite object.

Composite object takes ownership of the component, composite is responsible for the creation and destruction of the component parts. Composition helps us in implementing encapsulation as the component parts usually are members of the composite object.

In UML notation, Composition is depicted as a filled diamond and a solid line for example one or many sections can be part of an article.

 

Implementation in C#

There are different ways  to implement Composition relationship in C# but I personally prefer to use Nested Classes

  1. publicclassArticle {  
  2.     privatereadonlyList < Section > _sections = newList < Section > ();  
  3.     public Article() {  
  4.         _sections.Add(newSection() {  
  5.             Heading = "Heading 1", Paragraph = "Text Goes Here......."  
  6.         });  
  7.         Console.WriteLine("Article Created Successfully with one default section.");  
  8.     }  
  9.     publicvoid AddSection() {  
  10.         Section section = newSection() {  
  11.             Heading = "Heading 1", Paragraph = "Text Goes Here......."  
  12.         };  
  13.         _sections.Add(section);  
  14.         Console.WriteLine("Section Added Successfully. {0} Section Added in an Article ", _sections.Count);  
  15.     }  
  16.     classSection {  
  17.         publicstring Heading {  
  18.             get;  
  19.             set;  
  20.         }  
  21.         publicstring Paragraph {  
  22.             get;  
  23.             set;  
  24.         }  
  25.     }  
  26. }  
Aggregation

In general terms, Aggregation is a process of combining two or more distinct components to form an aggregate (whole) object but individual components have their own life-cycle.

In computing terms, Aggregation is a form of Association where different components combine to form a relationship or association between the aggregate (whole) and components in which the components live their own life-cycle; for example, we combine different network adapters, routers and network switches to build a complete network. If we take out any network switch or router, it will not impact any other component or network and we should be able to access network as expected. Similarly if we delete the network completely, it should not impact any individual component and we should be able to access those components without going through the aggregate object.

Aggregate object takes ownership of the component, but aggregate object is not responsible for the creation and destruction of the component parts, meaning the component object may live longer than the aggregate object.

In UML notation, Aggregation is depicted as an empty diamond and a solid line for example one or many Network Switch, Network Adaptor and Router combine to form a Network.

 

As seen in the above UML diagram NetworkSwitch, NetworkAdapter and Router aggregate themselves to form a Network and it is not mandatory for individual NetworkSwitch, NetworkAdapter and Router to be part of any Network, meaning they have their own life-cycle and can be accessed through their individual object.

Implementation in C#

  1. classNetwork {  
  2.     privatereadonlyList < Router > _routers = newList < Router > ();  
  3.     privatereadonlyList < NetworkSwitch > _networkSwitches = newList < NetworkSwitch > ();  
  4.     privatereadonlyList < NetworkAdpater > _networkAdapters = newList < NetworkAdpater > ();  
  5.     publicstring NetworkName {  
  6.         get;  
  7.         set;  
  8.     }  
  9.     publicvoid AddNetworkSwitch(NetworkSwitch networkSwitch) {  
  10.         _networkSwitches.Add(networkSwitch);  
  11.         Console.WriteLine("Switch {0} Added to the Network {1} ", networkSwitch.NetworkSwitchId, NetworkName);  
  12.     }  
  13.     publicvoid RemoveNetworkSwitch(NetworkSwitch networkSwitch) {  
  14.         _networkSwitches.Remove(networkSwitch);  
  15.         Console.WriteLine("Switch {0} removed from the Network {1} ", networkSwitch.NetworkSwitchId, NetworkName);  
  16.     }  
  17.     publicvoid AddNetworkAdapter(NetworkAdpater networkAdpater) {  
  18.         _networkAdapters.Add(networkAdpater);  
  19.         Console.WriteLine("Switch {0} Added to the Network {1} ", networkAdpater.NetworkAdpaterId, NetworkName);  
  20.     }  
  21.     publicvoid RemoveNetworkAdpater(NetworkAdpater networkAdpater) {  
  22.         _networkAdapters.Remove(networkAdpater);  
  23.         Console.WriteLine("Switch {0} removed from the Network {1}", networkAdpater.NetworkAdpaterId, NetworkName);  
  24.     }  
  25.     publicvoid AddRouter(Router router) {  
  26.         _routers.Add(router);  
  27.         Console.WriteLine("Router {0} Added to the Network {1} ", router.RouterId, NetworkName);  
  28.     }  
  29.     publicvoid RemoveRouter(Router router) {  
  30.         _routers.Remove(router);  
  31.         Console.WriteLine("Router {0} removed from the Network {1}", router.RouterId, NetworkName);  
  32.     }  
  33.     publicvoid PrintNetworkInformation() {  
  34.         foreach(var networkAdpater in _networkAdapters) {  
  35.             Console.WriteLine("{0} has a adapter {1}", NetworkName, networkAdpater.NetworkAdpaterId, NetworkName);  
  36.         }  
  37.         foreach(var networkSwitch in _networkSwitches) {  
  38.             Console.WriteLine("{0} has a switch {1}", NetworkName, networkSwitch.NetworkSwitchId, NetworkName);  
  39.         }  
  40.         foreach(var router in _routers) {  
  41.             Console.WriteLine("{0} has a router {1}", NetworkName, router.RouterId, NetworkName);  
  42.         }  
  43.     }  
  44. }  
  45. classNetworkSwitch {  
  46.     publicstring NetworkSwitchId {  
  47.         get;  
  48.         set;  
  49.     }  
  50.     publicstring Description {  
  51.         get;  
  52.         set;  
  53.     }  
  54. }  
  55. classNetworkAdpater {  
  56.     publicstring NetworkAdpaterId {  
  57.         get;  
  58.         set;  
  59.     }  
  60.     publicstring Description {  
  61.         get;  
  62.         set;  
  63.     }  
  64. }  
  65. classRouter {  
  66.     publicstring RouterId {  
  67.         get;  
  68.         set;  
  69.     }  
  70.     publicstring Description {  
  71.         get;  
  72.         set;  
  73.     }  
  74. }  

 

Now we can initialize and access an instance of NetworkSwitch, NetworkAdpater and Router individually and add them to a network object and remove them from network whenever needed. Adding and removing an instance of NetworkSwitch from Network object will not make any impact on the individual NetworkSwitch object

Conclusion

Composition and Aggregation both are subset of Association. Aggregation differs from composition in that it does not enforce ownership and the aggregate (whole) object does not take responsibility for the creation and destruction of components.

Tip

Use composition when one object needs to be developed as an integral part of another object.