Here a single item and a group of items are unrelated classes. So the code is hard to change and not type-safe. It also cannot hold nested groups, which are common in e-commerce and file systems.
1. Working of the Code
The Product: A single item with a name and a price.
The Bundle: A group that holds a list of Product objects only.
Manual Setup: Items and bundles are created and added to a List<Object> cart, a list that accepts anything.
Type Discovery: At checkout, the code asks each item for its type with instanceof.
Manual Calculation: Then it casts the item to that type (tells Java what it really is) so it can call the display and price methods.
2. Key Issues in this Design
Violation of Polymorphism (instanceof Abuse)
The Issue: The checkout loop uses instanceof to tell items from bundles.
The Impact: This breaks polymorphism. With polymorphism, the client calls a method on a shared interface and does not need to know the exact class.
Lack of Uniformity
The Issue: Product and ProductBundle are separate types. They share no interface or superclass.
The Impact: You cannot write one piece of logic for "anything in the cart". Each type needs its own logic.
Unsafe Abstraction (List<Object>)
The Issue: The cart uses List<Object>. This is a "code smell" (a sign of weak design) in Java.
The Impact: The compiler cannot check what is in the list. You must cast, and a wrong cast fails at runtime with a ClassCastException.
Non-Recursive Structure
The Issue: A ProductBundle can only contain Product objects.
The Impact: You cannot put a bundle inside another bundle (for example, a "Holiday Gift Box" holding a "Skincare Kit"). Real hierarchies need this.
Duplicated Logic
The Issue: Display and price logic is repeated in both classes.
The Impact: If the price rule changes (for example, adding tax), you must update several places. That takes more work and risks bugs.
3. Structural Analysis
Component
Status
Observation
Individual Item
Isolated
Operates independently with no relation to bundles.
Bundle
Rigid
Limited to holding only basic products; cannot nest.
Client
Over-informed
Must know the internal types of everything in the cart.
4. Summary of the "Smell"
If you use instanceof to walk through a list, or you cannot nest groups inside groups, you need the Composite Pattern. It lets us treat "parts" and "wholes" the same way.
1package DesignPatterns.StructuralPatterns.CompositeDesignPattern.Before;23import java.util.*;45/**6 * PROBLEM 1: Lack of a Common Interface.7 * There is no 'CatalogComponent' or 'Component' interface.8 * This prevents treating single items and bundles uniformly.9 */10class Product {1112 private String name;13 private double price;1415 public Product(String name, double price) {16 this.name = name;17 this.price = price;18 }1920 public double getPrice() {21 return price;22 }2324 public void display(String indent) {25 System.out.println(indent + "Product: " + name + " - ₹" + price);26 }27}2829/**30 * PROBLEM 2: Rigid Composition.31 * This class can only store 'Product' objects. It cannot store other bundles.32 */33class ProductBundle {3435 private String bundleName;36 private List<Product> products = new ArrayList<>();3738 public ProductBundle(String bundleName) {39 this.bundleName = bundleName;40 }4142 // This method is locked to the concrete 'Product' class.43 public void addProduct(Product product) {44 products.add(product);45 }4647 public double getPrice() {48 double total = 0;49 for (Product product : products) {50 total += product.getPrice();51 }52 return total;53 }5455 public void display(String indent) {56 System.out.println(indent + "Bundle: " + bundleName);57 for (Product product : products) {58 product.display(indent + " ");59 }60 }61}6263class Main {6465 public static void main(String[] args) {66 Product book = new Product("Book", 500);67 Product charger = new Product("Charger", 800);6869 ProductBundle iphoneCombo = new ProductBundle("iPhone Combo Pack");70 iphoneCombo.addProduct(charger);7172 /**73 * PROBLEM 3: Type-Safety & Code Smells.74 * We have to use List<Object> because there is no common type.75 */76 List<Object> cart = new ArrayList<>();77 cart.add(book);78 cart.add(iphoneCombo);7980 double total = 0;81 System.out.println("Cart Details:\n");8283 /**84 * PROBLEM 4: Violation of Open/Closed Principle.85 * If we add a new type (e.g., 'DigitalSubscription'), we must86 * come back here and add another 'instanceof' block.87 */88 for (Object item : cart) {89 if (item instanceof Product) {90 ((Product) item).display(" ");91 total += ((Product) item).getPrice();92 } else if (item instanceof ProductBundle) {93 ((ProductBundle) item).display(" ");94 total += ((ProductBundle) item).getPrice();95 }96 }9798 System.out.println("\nTotal Price: ₹" + total);99 }100}101