knowledge/technology/dev/programming/patterns/structural/Composite Pattern.md
2024-01-17 09:00:45 +01:00

93 lines
No EOL
4 KiB
Markdown

---
obj: concept
---
# Composite Pattern
## **Description:**
The Composite Pattern is a structural design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions of objects uniformly. In other words, you can use the same interface to work with both single objects and compositions of objects. This pattern is particularly useful when dealing with hierarchical structures and you want to apply operations recursively.
**How it's Used:**
1. **Component Interface**: Define an abstract class or interface, often called `Component`, that represents the common interface for both leaf and composite objects. This interface includes methods that are common to all objects in the hierarchy.
2. **Leaf Class**: Create a leaf class that implements the `Component` interface. Leaf objects are the individual objects that do not have children in the hierarchy.
3. **Composite Class**: Create a composite class that also implements the `Component` interface. Composite objects can contain child components, including both leaf and other composite objects.
4. **Add and Remove Methods**: In the composite class, provide methods to add and remove child components. These methods allow you to build and modify the hierarchical structure dynamically.
5. **Client Code**: In your client code, work with objects through the `Component` interface. You can treat individual objects and compositions of objects uniformly, as they share a common interface.
## **Example:**
Imagine you are building a graphical user interface (GUI) library that needs to handle a hierarchy of UI elements, including individual controls (buttons, text fields) and composite elements (e.g., windows containing other controls). Here's how the Composite Pattern can be applied:
- **Component Interface**: Define an abstract `UIComponent` interface that represents the common interface for all UI element
```java
public interface UIComponent {
void render();
}
```
- **Leaf Class**: Create leaf classes like `Button` and `TextField` that implement the `UIComponent` interface.
```java
public class Button implements UIComponent {
private String label;
public Button(String label) {
this.label = label;
}
@Override
public void render() {
System.out.println("Rendered Button: " + label);
}
}
public class TextField implements UIComponent {
@Override
public void render() {
System.out.println("Rendered TextField");
}
}
```
- **Composite Class**: Create a composite class, such as `Window`, that implements the `UIComponent` interface and can contain child components.
```java
import java.util.ArrayList;
import java.util.List;
public class Window implements UIComponent {
private List<UIComponent> children = new ArrayList<>();
public void add(UIComponent component) {
children.add(component);
}
public void remove(UIComponent component) {
children.remove(component);
}
@Override
public void render() {
System.out.println("Rendered Window");
for (UIComponent child : children) {
child.render();
}
}
}
```
- **Client Code**: In your GUI library or application, create instances of leaf objects and composite objects and use them through the `UIComponent` interface.
```java
public class Client {
public static void main(String[] args) {
UIComponent button1 = new Button("OK");
UIComponent button2 = new Button("Cancel");
UIComponent textField = new TextField();
Window window = new Window();
window.add(button1);
window.add(button2);
window.add(textField);
window.render();
}
}
```
By using the Composite Pattern, you can build complex UI hierarchies by composing individual UI elements (leaf objects) and containers (composite objects). Clients can work with these elements uniformly, regardless of whether they are individual controls or nested containers. This promotes code reusability and flexibility when dealing with hierarchical structures.