codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Subjects
🧩

OOP Concepts

23 chapters

1Procedural vs Object-Oriented2Classes, Objects, & Instantiation3Constructors & Destructors4Static Members & Methods5Encapsulation & Access Modifiers6Data Abstraction7Inheritance Types (Single, Multiple)8Compile-Time Polymorphism (Overloading)9Polymorphism & Interfaces10Run-Time Polymorphism (Overriding)11Virtual Functions & V-Tables12Interfaces & Abstract Classes13Generic Programming (Templates & Generics)14Exception Handling in OOP15SOLID Design Principles16Composition over Inheritance17Coupling & Cohesion18UML Diagrams Basics19Creational Patterns (Singleton, Factory)20Structural Patterns (Adapter, Decorator)21Behavioral Patterns (Observer, Strategy)22MVC Architecture Pattern23Object Serialization & Cloning
SubjectsOOP Concepts

Structural Patterns (Adapter, Decorator)

Updated 2026-04-27
2 min read

Structural Patterns (Adapter, Decorator)

Structural patterns are concerned with how classes and objects are composed to form larger structures. They use inheritance and composition to create new functionality from existing components.

1. The Adapter Pattern

Intent: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

Real-World Analogy

When you travel from India to Europe, your Indian plug doesn't fit into a European wall socket. You use a Power Adapter that sits between your plug and the socket, converting one interface to another without modifying either the plug or the socket.

The Problem

You are building a stock market analytics app. Your app uses a beautiful charting library that only accepts data in XML format. But your new data vendor's API only returns data in JSON format. You cannot modify the vendor's API or the charting library.

The Solution

// The interface your charting library expects
interface XMLDataSource {
    String getXMLData();
}

// The vendor's class you CANNOT modify
class JsonDataVendor {
    public String getJsonData() {
        return "{ \"price\": 150.25 }";
    }
}

// The ADAPTER: Bridges the gap
class JsonToXmlAdapter implements XMLDataSource {
    private JsonDataVendor vendor;

    JsonToXmlAdapter(JsonDataVendor vendor) {
        this.vendor = vendor;
    }

    public String getXMLData() {
        String json = vendor.getJsonData();
        // Convert JSON to XML
        return "<price>150.25</price>";
    }
}

The charting library works with XMLDataSource. The adapter implements XMLDataSource but internally delegates to JsonDataVendor, performing the conversion transparently.

2. The Decorator Pattern

Intent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Real-World Analogy

A plain coffee costs $2. You want to add Milk (+$0.50), then Whipped Cream (+$0.75), then Caramel Drizzle (+$1.00). Each addition "decorates" the base coffee, adding cost and description.

The Problem

If you used inheritance, you would need classes like CoffeeWithMilk, CoffeeWithMilkAndWhippedCream, CoffeeWithCaramelAndWhippedCream... The number of subclasses explodes combinatorially.

The Solution

interface Coffee {
    String getDescription();
    double getCost();
}

class BasicCoffee implements Coffee {
    public String getDescription() { return "Basic Coffee"; }
    public double getCost() { return 2.00; }
}

// Abstract Decorator
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;
    CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; }
}

// Concrete Decorators
class MilkDecorator extends CoffeeDecorator {
    MilkDecorator(Coffee coffee) { super(coffee); }
    public String getDescription() { return decoratedCoffee.getDescription() + " + Milk"; }
    public double getCost() { return decoratedCoffee.getCost() + 0.50; }
}

class WhipDecorator extends CoffeeDecorator {
    WhipDecorator(Coffee coffee) { super(coffee); }
    public String getDescription() { return decoratedCoffee.getDescription() + " + Whip"; }
    public double getCost() { return decoratedCoffee.getCost() + 0.75; }
}

// Usage: Decorators wrap objects like layers
Coffee order = new BasicCoffee();             // $2.00
order = new MilkDecorator(order);             // $2.50
order = new WhipDecorator(order);             // $3.25
System.out.println(order.getDescription());   // "Basic Coffee + Milk + Whip"
System.out.println(order.getCost());          // 3.25

Each decorator wraps the previous object, adding its own behavior. You can stack decorators in any combination without creating a single new subclass.



PreviousCreational Patterns (Singleton, Factory)NextBehavioral Patterns (Observer, Strategy)

Recommended Gear

Creational Patterns (Singleton, Factory)Behavioral Patterns (Observer, Strategy)