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 Tutorials
🎭

Design Patterns

32 / 100 topics
11Introduction to Structural Patterns12Adapter Pattern13Bridge Pattern14Composite Pattern15Decorator Pattern16Facade Pattern17Flyweight Pattern18Proxy Pattern32Practical Exercises for Structural Patterns
Tutorials/Design Patterns/Practical Exercises for Structural Patterns
🎭Design Patterns

Practical Exercises for Structural Patterns

Updated 2026-05-15
10 min read

Practical Exercises for Structural Patterns

Introduction

Welcome to the third section of our design patterns curriculum, where we dive into Structural Patterns. These patterns are concerned with how classes and objects can be composed to form larger structures. They help in creating flexible and reusable code by defining new classes that represent relationships between existing ones.

In this tutorial, you'll learn about some of the most commonly used structural design patterns through hands-on exercises. We'll cover:

  1. Adapter Pattern
  2. Bridge Pattern
  3. Composite Pattern

Each pattern will be explained with a real-world analogy and followed by a practical coding exercise to help you understand its application.

Concept

Adapter Pattern

Real-World Analogy: Think of an adapter as a device that allows two incompatible devices to work together. For example, a USB-C to Lightning cable lets your iPhone charge using a USB-C port.

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

Bridge Pattern

Real-World Analogy: Imagine you have different types of remote controls (e.g., TV, Radio) and different brands of devices. A bridge allows these remotes to control their respective devices without changing the remote's code.

Definition: The Bridge pattern separates an abstraction from its implementation so that the two can vary independently.

Composite Pattern

Real-World Analogy: Consider a tree structure where each node can be either a leaf or another subtree. A composite pattern allows you to treat individual objects and compositions of objects uniformly.

Definition: The Composite pattern composes objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions of objects uniformly.

Examples

Exercise 1: Adapter Pattern

Problem: You have a legacy system that uses an old API, but you need to integrate it with a new system that expects a different API.

Solution: Use the Adapter pattern to create a new interface that wraps the old API.

JavaScript
1// Old API
2class OldAPI {
3request() {
4 return "Old data";
5}
6}
7
8// New API expected by the system
9class NewAPI {
10fetchData() {
11 // This method should fetch data from the OldAPI
12}
13}
14
15// Adapter class
16class Adapter extends NewAPI {
17constructor(oldApi) {
18 this.oldApi = oldApi;
19}
20
21fetchData() {
22 return this.oldApi.request();
23}
24}
25
26// Usage
27const oldApiInstance = new OldAPI();
28const adapterInstance = new Adapter(oldApiInstance);
29console.log(adapterInstance.fetchData()); // Output: "Old data"

Exercise 2: Bridge Pattern

Problem: You have a drawing application that supports different shapes and colors. You want to add more colors without changing the shape classes.

Solution: Use the Bridge pattern to separate the abstraction (shapes) from the implementation (colors).

JavaScript
1// Color interface
2class Color {
3applyColor() {}
4}
5
6// Concrete Colors
7class Red extends Color {
8applyColor() { return "Red"; }
9}
10
11class Blue extends Color {
12applyColor() { return "Blue"; }
13}
14
15// Shape abstraction
16class Shape {
17constructor(color) {
18 this.color = color;
19}
20
21draw() {}
22}
23
24// Concrete Shapes
25class Circle extends Shape {
26draw() {
27 console.log(`Drawing a circle with ${this.color.applyColor()} color`);
28}
29}
30
31class Square extends Shape {
32draw() {
33 console.log(`Drawing a square with ${this.color.applyColor()} color`);
34}
35}
36
37// Usage
38const red = new Red();
39const blue = new Blue();
40
41const circle = new Circle(red);
42circle.draw(); // Output: "Drawing a circle with Red color"
43
44const square = new Square(blue);
45square.draw(); // Output: "Drawing a square with Blue color"

Exercise 3: Composite Pattern

Problem: You need to represent a file system where both files and directories can be treated uniformly.

Solution: Use the Composite pattern to create a tree structure of files and directories.

JavaScript
1// Component interface
2class Component {
3add(component) {}
4remove(component) {}
5display() {}
6}
7
8// Leaf class (File)
9class File extends Component {
10constructor(name) {
11 this.name = name;
12}
13
14display() {
15 console.log(`File: ${this.name}`);
16}
17}
18
19// Composite class (Directory)
20class Directory extends Component {
21constructor(name) {
22 this.name = name;
23 this.children = [];
24}
25
26add(component) {
27 this.children.push(component);
28}
29
30remove(component) {
31 const index = this.children.indexOf(component);
32 if (index !== -1) {
33 this.children.splice(index, 1);
34 }
35}
36
37display() {
38 console.log(`Directory: ${this.name}`);
39 this.children.forEach(child => child.display());
40}
41}
42
43// Usage
44const root = new Directory("Root");
45const documents = new Directory("Documents");
46const photos = new Directory("Photos");
47
48const report = new File("report.txt");
49const vacationPhoto = new File("vacation.jpg");
50
51documents.add(report);
52photos.add(vacationPhoto);
53
54root.add(documents);
55root.add(photos);
56
57root.display();
58// Output:
59// Directory: Root
60// Directory: Documents
61// File: report.txt
62// Directory: Photos
63// File: vacation.jpg

What's Next?

Congratulations on completing the exercises for Structural Patterns! In the next section, we'll explore Behavioral Patterns. These patterns are focused on improving communication between objects and defining how they interact.

Stay tuned for more hands-on exercises to enhance your understanding of design patterns and their practical applications in software development.

Happy coding!


PreviousPractical Exercises for Creational PatternsNext Practical Exercises for Behavioral Patterns

Recommended Gear

Practical Exercises for Creational PatternsPractical Exercises for Behavioral Patterns