Java Structural Design Patterns: Adapter, Decorator, Facade, Composite

sametklou

Java Structural Design Patterns: Adapter, Decorator, Facade, Composite

In Java, structural design patterns play a crucial role in organizing code and improving code reusability. Here, we will discuss four important structural design patterns: Adapter, Decorator, Facade, and Composite.

Adapter Pattern

The Adapter pattern allows objects with incompatible interfaces to work together. This pattern involves a single class known as the Adapter that is responsible for joining functionalities of independent or incompatible interfaces.

public interface Target {
    void request();
}

public class Adaptee {
    public void specificRequest() {
        System.out.println("Specific Request");
    }
}

public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

Decorator Pattern

The Decorator pattern allows a user to add new functionality to an object dynamically without affecting its structure. This pattern involves classes and interfaces to allow adding new functionalities to an object.

public interface Component {
    void operation();
}

public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("Concrete Component Operation");
    }
}

public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

Facade Pattern

The Facade pattern provides a unified interface to a set of interfaces in a system. It defines a higher-level interface that makes the system easier to use.

public class Subsystem1 {
    public void operation1() {
        System.out.println("Subsystem1 Operation1");
    }
}

public class Subsystem2 {
    public void operation2() {
        System.out.println("Subsystem2 Operation2");
    }
}

public class Facade {
    private Subsystem1 subsystem1;
    private Subsystem2 subsystem2;

    public Facade() {
        this.subsystem1 = new Subsystem1();
        this.subsystem2 = new Subsystem2();
    }

    public void operation() {
        subsystem1.operation1();
        subsystem2.operation2();
    }
}

Composite Pattern

The Composite pattern is used when a group of objects should behave as a single object. This pattern composes objects into tree structures to represent part-whole hierarchies.

public interface Component {
    void operation();
}

public class Leaf implements Component {
    @Override
    public void operation() {
        System.out.println("Leaf Operation");
    }
}

public class Composite implements Component {
    private List<Component> components = new ArrayList<>();

    public void addComponent(Component component) {
        components.add(component);
    }

    @Override
    public void operation() {
        for (Component component : components) {
            component.operation();
        }
    }
}

By understanding and implementing these structural design patterns in Java, you can enhance your code organization and improve the flexibility and reusability of your codebase.