.Net Interview Questions:- Can you explain composite pattern?
Shivprasad Koirala
GOF definition :- A tree structure of simple and composite objects
Many times objects are organized in tree structure and developers have to understand the difference between leaf and branch objects. This makes the code more complex and can lead to errors. For example below is a simple object tree structure where the customer is the main object which has many address objects and every address object references lot of phone objects.
Figure: - General Process
Now let’s say you want to insert the complete object tree. The sample code will be something as shown below. The code loops through all the customers, all addresses inside the customer object and all phones inside the address objects. While this loop happens the respective update methods are called as shown in the below code snippet.
foreach (Customer objCust in objCustomers){objCust.UpDateCustomer(); foreach (Address oAdd in objCust.Addresses) { oAdd.UpdateAddress(); } foreach (Phone ophone in oAdd.Phones) { ophone.UpDatePhone(); }}
The problem with the above code is that the update vocabulary changes for each object. For customer its ‘UpdateCustomer’ , for address its ‘UpdateAddress’ and for phone it is ‘UpdatePhone’. In other words the main object and the contained leaf nodes are treated differently. This can lead to confusion and make your application error prone.The code can be cleaner and neat if we are able to treat the main and leaf object uniformly. You can see in the below code we have created an interface (IBusinessObject) which forces all the classes i.e. customer, address and phone to use a common interface. Due to the common interface all the object now have the method name as “Update”.
foreach (IBusinessObject ICust in objCustomers){ICust.Update(); foreach (IBusinessObject Iaddress in ((Customer)(ICust)).ChildObjects) { Iaddress.Update();foreach (IBusinessObject iphone in ((Address)(Iaddress)).ChildObjects) { iphone.Update();} }}
In order to implement composite pattern first create an interface as shown in the below code snippet.
public interface IBusinessObject{ void Update(); bool isValid(); void Add(object o); }
Force this interface across all the root objects and leaf / node objects as shown below.
public class Customer : IBusinessObject { private List<Address> _Addresses; public IEnumerable<Address> ChildObjects { get { return (IEnumerable<Address>)_Addresses; } } public void Add(object objAdd) { _Addresses.Add((Address) objAdd); } public void Update() { } public bool isValid() { return true; }}
Force the implementation on the address object also.
public class Address : IBusinessObject { private List<Phone> _Phones; public IEnumerable<Phone> ChildObjects { get { return (IEnumerable<Phone>)_Phones.ToList<object>(); } } public void Add(object objPhone) { _Phones.Add((Phone)objPhone); } public void Update() { } public bool isValid() { return true; } }
Force the implementation on the last node object i.e. phone.
public class Phone : IBusinessObject { public void Update() {} public bool isValid() {return true;} public void Add(object o) { // no implementaton } } }
View my 21 important .NET Interview questions and answers