Combination mode
Composite Pattern, also called part-whole pattern, is used to treat a group of similar objects as a single object. The composition mode combines objects according to a tree structure, which is used to represent part and whole hierarchies. This type of design pattern is a structural pattern, which creates a tree structure of groups of objects.
This pattern creates a class that contains its own group of objects. This class provides a way to modify groups of identical objects.
We demonstrate the usage of combination mode through the following examples. The example illustrates the hierarchy of employees in an organization.
Introduction
Intent: Combines objects into a tree structure to represent the "part-whole" hierarchy. The composition pattern allows users to use single objects and composite objects consistently.
Main solution: It blurs the concepts of simple elements and complex elements in our tree structure problem. The client program can process complex elements in the same way as simple elements, thus making Client programs are decoupled from the internal structure of complex elements.
When to use: 1. You want to represent the part-whole hierarchy (tree structure) of the object. 2. You want users to ignore the difference between combined objects and single objects, and users will use all objects in the combined structure uniformly.
How to solve: The branches and leaves implement a unified interface, and the interface is combined inside the branch.
Key code: The interface is combined internally in the branch, and contains an internal attribute List, which contains Component.
Application examples: 1. Arithmetic expressions include operands, operators and another operand, where another operator can also be an operation tree, an operator and another operation number. 2. In JAVA AWT and SWING, Button and Checkbox are leaves, and Container is a branch.
Advantages: 1. High-level module calls are simple. 2. Nodes can be added freely.
Disadvantages: When using the combination mode, the declarations of the leaves and branches are implementation classes, not interfaces, which violates the dependency inversion principle.
Usage scenarios: Partial and overall scenarios, such as tree menu, file and folder management.
Note: is a concrete class when defined.
Implementation
We have a class Employee, which is treated as a composite model class. CompositePatternDemo, our demo class uses the Employee class to add department hierarchy and print all employees.
Step 1
Create the Employee class with a list of Employee objects.
Employee.java
import java.util.ArrayList; import java.util.List; public class Employee { private String name; private String dept; private int salary; private List<Employee> subordinates; //构造函数 public Employee(String name,String dept, int sal) { this.name = name; this.dept = dept; this.salary = sal; subordinates = new ArrayList<Employee>(); } public void add(Employee e) { subordinates.add(e); } public void remove(Employee e) { subordinates.remove(e); } public List<Employee> getSubordinates(){ return subordinates; } public String toString(){ return ("Employee :[ Name : "+ name +", dept : "+ dept + ", salary :" + salary+" ]"); } }
Step 2
Use the Employee class to create and print the employee hierarchy.
CompositePatternDemo.java
public class CompositePatternDemo { public static void main(String[] args) { Employee CEO = new Employee("John","CEO", 30000); Employee headSales = new Employee("Robert","Head Sales", 20000); Employee headMarketing = new Employee("Michel","Head Marketing", 20000); Employee clerk1 = new Employee("Laura","Marketing", 10000); Employee clerk2 = new Employee("Bob","Marketing", 10000); Employee salesExecutive1 = new Employee("Richard","Sales", 10000); Employee salesExecutive2 = new Employee("Rob","Sales", 10000); CEO.add(headSales); CEO.add(headMarketing); headSales.add(salesExecutive1); headSales.add(salesExecutive2); headMarketing.add(clerk1); headMarketing.add(clerk2); //打印该组织的所有员工 System.out.println(CEO); for (Employee headEmployee : CEO.getSubordinates()) { System.out.println(headEmployee); for (Employee employee : headEmployee.getSubordinates()) { System.out.println(employee); } } } }
Step 3
Verify the output.
Employee :[ Name : John, dept : CEO, salary :30000 ] Employee :[ Name : Robert, dept : Head Sales, salary :20000 ] Employee :[ Name : Richard, dept : Sales, salary :10000 ] Employee :[ Name : Rob, dept : Sales, salary :10000 ] Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ] Employee :[ Name : Laura, dept : Marketing, salary :10000 ] Employee :[ Name : Bob, dept : Marketing, salary :10000 ]