1. Introduction
A shopping cart can hold a single book. It can also hold a gift box with other items, even other boxes, inside. You want the price without checking which one you have.
The Composite Pattern is a structural design pattern (about how classes fit together). It arranges objects in a tree where a part is one item or a group of items (a part-whole hierarchy). Code treats one item and a whole group the same way.
2. Problem It Solves
In an e-commerce checkout, products sit inside bundles. Without this pattern, the client code (the code that uses these classes) must check by hand whether each thing is a single item or a group:
- Class Explosion:
ProductandProductBundleare separate types, and they share no interface (a common list of methods). - Polymorphism Breakage: Polymorphism means one call works on many types. Here it breaks, so you must use
instanceof(a check of an object's type) again and again before you act. - Rigid Structure: A
ProductBundlecannot hold anotherProductBundle, so nesting is impossible (for example, a combo pack inside a larger gift box).
3. Class Diagram
The diagram shows the Leaf (Product) and the Composite (ProductBundle). Both implement the CartItem interface.
4. Leaf vs. Composite
Leaf (The Atomic Object)
- Definition: A simple object that holds no other objects inside it.
- Role:
Productis the Leaf. It stands for one item (a book or a phone) and knows its own price.
Composite (The Container)
- Definition: An object that holds many
CartItemobjects. These can be Leaves or other Composites. - Role:
ProductBundleis the Composite. It delegates (passes the work on)getPrice()anddisplay()to each child, then adds up the prices.
5. Advantages and Disadvantages
| Advantages | Disadvantages |
|---|---|
| Uniformity: One item and a group are used in the same way. | Over-Generalization: Treating everything alike can hide real differences between types. |
| Open/Closed Principle: You can add new item types without editing existing code. | Complexity: Too much for a flat list. |
| Recursive Depth: Groups can sit inside groups, as deep as you need (combos inside kits inside boxes). | SRP Violation: In general (not in this example), in a large system one class may handle both business logic and the tree structure (SRP: one job per class). |
6. Real-World Use Cases
- File Systems: Folders (Composites) containing Files (Leaves) and other Sub-folders.
- UI Toolkits: A
Panel(Composite) containingButtons(Leaves) and otherPanels. - E-commerce: Product Bundles and Kits, as in the refactored code.
Key Takeaway: The "Part-Whole" Hierarchy
Use the Composite Pattern when your data forms a Tree Structure. Make the "Whole" (Bundle) implement the same interface as the "Part" (Product). Then you no longer need type checks, and the structure can grow easily.