Home > Patterns and Practices > Composite Pattern

Composite Pattern

Composite Pattern

Problem:

You are modeling a shipment sent from a Warehouse to a retail Store. The shipments usually are contained in pallets (think of pallet as a container in which products are shipped). A pallet can contain other pallets or individual products. Assume you need to get the total number of products or the total value of products. You want to represent part (product) – whole (pallet) hierarchies of objects. You want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly.

 

Solution:

The composite pattern comes to the rescue. We’ll model something like this:

 

public class ShipmentItem

{

            public virtual int GetNumberOfItems()

            {

                        return 1;

            }

 

            public abstract decimal GetCost();

           

            public virtual void AddShipmentItem(ShipmentItem item)

            {

                        throw new NotSupportedException();

            }

            public virtual void RemoveShipmentItem(int psoition)

            {

                        throw new NotSupportedException();

            }

            public virtual ShipmentItem GetItem(int position)

            {

                        throw new NotSupportedException();

            }         

}

 

public class Pallet : ShipmentItem

{

            private ArrayList shipmentItems;

 

            public Pallet()

            {

                        shipmentItems = new ArryaList();

            }

 

            public override int GetNumberOfItems()

            {

                        int numberOfItems = 0;

                        foreach(ShipmentItem item in shipmentItems)

                        {

                                    numberOfItems += item.GetNumberOfItems();

                        }

                        return numberOfItems;

            }

 

            public override decimal GetCost()

            {

                        decimal  totalCost = 0D;

                        foreach(ShipmentItem item in shipmentItems)

                        {

                                    totalCost += item.GetCost();

                        }

                        return totalCost;

            }

           

            public override void AddShipmentItem(ShipmentItem item)

            {

                        shipmentItems.Add(item);

            }

            public override void RemoveShipmentItem(int psoition)

            {

                        shipmentItems.Remove(item);

            }

            public override ShipmentItem GetItem(int position)

            {

                        return (ShipmentItem)shipmentItems[position];

            }

           

}

 

public class Product : ShipmentItem

{

            private string productCode;

 

            public Product(string UPC)

            {

                        this.productCode = UPC;

            }

           

            public override decimal GetCost()

            {

                        // Retrieve and return the product cost from a datastore based on the product code.

            }

 

            public readonly string UPC

            {

                        get

                        {

                                    return productCode;

                        }

            }         

}

 

public class OrderShipment

{

            private ArryaList items;

 

            public void LoadShipmentDetails(string xml)

            {

                        // Fill the shipment details

            }

 

            public decimal GetShipmentValue()

            {

                        decimal  totalCost = 0D;

                        foreach(ShipmentItem item in items)

                        {

                                    totalCost += item.GetCost();

                        }

                        return totalCost;

            }

           

            public int GetNumberOfItemsInShipment()

            {                     

                        int numberOfItems = 0;

                        foreach(ShipmentItem item in items)

                        {

                                    numberOfItems += item.GetNumberOfItems();

                        }

                        return numberOfItems;

            }

}

 

The GoF class structure diagram

 

Note: In .NET Framework the Composite can be seen ASP.NET Control tree (the Render method or the visible property etc).

  1. No comments yet.
  1. November 19, 2010 at 11:00 pm

Leave a comment