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.