DEV Community

Aditya
Aditya

Posted on

Design Patterns in Java- A simplified Guide #2

Welcome to this 3-part guide. In this post, I'll provide a basic introduction to design patterns, along with examples.

This specific post will cover what design patterns are, why we should know about them, the types of design patterns, and structural patterns.

Quick links:

  1. Creational Patterns
  2. Structural Patterns
  3. Behavioral Patterns

What are Design Patterns?

Design patterns are proven solutions to common problems in software development. They help developers solve complex tasks in a structured way and allow them to reuse successful solutions, making their code easier to understand and maintain. Think of design patterns as blueprints for solving typical problems that occur when building software.

Why Should We Know About Them?

Knowing about design patterns helps developers solve common problems in a structured and efficient way, making code more reusable, maintainable, and scalable.

Think of a restaurant kitchen. The chef follows a recipe (design pattern) to prepare a dish. Instead of reinventing the process each time, the chef uses proven steps to consistently deliver the same quality dish. Similarly, design patterns help developers efficiently solve problems without reinventing solutions each time.

Types of Design Patterns:

In Java, design patterns are categorized into three main groups:

1. Creational Patterns: These patterns help with creating objects in a flexible and reusable way.
2. Structural Patterns: These patterns focus on how objects are arranged and connected to form larger systems.
3. Behavioral Patterns: These patterns deal with how objects interact and communicate with each other.

Structural Patterns

Structural patterns focus on how to organize and connect objects to form larger, more complex systems.

Adapter:

If you are using an old database API in a new application, you can use an adapter pattern to make the old API work with the new system.

interface NewDatabase {
    void fetchData();
}

class OldDatabase {
    public void getData() {
        System.out.println("Fetching data from old database");
    }
}

class OldDatabaseAdapter implements NewDatabase {
    private OldDatabase oldDatabase;

    public OldDatabaseAdapter(OldDatabase oldDatabase) {
        this.oldDatabase = oldDatabase;
    }

    public void fetchData() {
        oldDatabase.getData();
    }
}
Enter fullscreen mode Exit fullscreen mode

Bridge:

You have a drawing application that can draw different shapes. The bridge pattern lets you separate the shape (abstraction) from the drawing implementation (implementation).

interface DrawingAPI {
    void drawCircle(double x, double y, double radius);
}

class Circle {
    private double x, y, radius;
    private DrawingAPI drawingAPI;

    public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.drawingAPI = drawingAPI;
    }

    public void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }
}

Enter fullscreen mode Exit fullscreen mode

Composite:

In a file system, a folder can contain both files and other folders. The composite pattern allows you to treat both files and folders in the same way.

interface FileSystemComponent {
    void showDetails();
}

class File implements FileSystemComponent {
    private String name;

    public File(String name) {
        this.name = name;
    }

    public void showDetails() {
        System.out.println("File: " + name);
    }
}

class Folder implements FileSystemComponent {
    private List<FileSystemComponent> components = new ArrayList<>();

    public void add(FileSystemComponent component) {
        components.add(component);
    }

    public void showDetails() {
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Decorator:

You want to add new functionality to a Car class without modifying the original Car. The decorator pattern lets you add features such as sunroof or leather seats dynamically.

interface Car {
    void assemble();
}

class BasicCar implements Car {
    public void assemble() {
        System.out.println("Basic car assembled.");
    }
}

class CarDecorator implements Car {
    protected Car car;

    public CarDecorator(Car car) {
        this.car = car;
    }

    public void assemble() {
        this.car.assemble();
    }
}

class SunroofDecorator extends CarDecorator {
    public SunroofDecorator(Car car) {
        super(car);
    }

    public void assemble() {
        super.assemble();
        System.out.println("Adding sunroof.");
    }
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)