In real life, there are many "part-whole" relationships, such as departments and colleges in universities, departments and subsidiaries in headquarters, books and bags in study supplies, clothes and wardrobes in household appliances, pots and pans in kitchens, etc. This is also true in software development, such as files and folders in the file system, simple controls in form programs, container controls, and so on. The processing of these simple and composite objects is very convenient if they are implemented in a combination mode.
Definition and Features of Combination Mode
Definition of a Composite Pattern pattern: Sometimes referred to as a Part-Whole pattern, it is a pattern of grouping objects into a tree-like hierarchy that represents a "whole-part" relationship, giving users consistent access to individual objects and grouped objects and being structured Design Mode.
The combination mode is generally used to describe the relationship between the whole and the part. It organizes objects into a tree structure. The top node is called the root node. Below the root node, it can contain the branch node and the leaf node. Below the branch node, it can also contain the branch node and the leaf node. The tree structure diagram is as follows.
As can be seen from the figure above, root and branch nodes are essentially the same data type and can be used as containers. Leaf and branch nodes are not semantically of one type. In combination mode, however, the branch and leaf nodes are considered to belong to the same data type (defined by a unified interface) and behave consistently.
In this way, the objects in the whole tree structure belong to the same type in the combination mode. The benefit is that the user does not need to distinguish whether they are branch nodes or leaf nodes, and can operate directly, which brings great convenience to users.
The main advantages of the combination mode are:
- Composite mode simplifies client code by allowing client code to consistently process individual and composite objects, regardless of whether they are dealing with individual or composite objects.
- It is easier to add new objects to the assembly, and clients will not change the source code to satisfy the Open and Close Principle by adding new objects.
Its main drawbacks are:
- The design is complex, and clients need to spend more time clarifying hierarchical relationships between classes.
- It is not easy to restrict components in containers;
- It is not easy to use inherited methods to add new functionality to components;
Structure and implementation of combinatorial mode
The structure of the composite mode is not very complex. The structure and implementation of the composite mode are analyzed below.
1. Structure of patterns
The combination mode contains the following main roles.
- Component role: Its primary purpose is to declare common interfaces for leaf and branch components and to implement their default behavior. In a transparent combination mode, abstract components also declare interfaces to access and manage subclasses; Interfaces to access and manage subclasses are not declared in a secure composite mode, and management is done by the branch component. (General abstract class or interface, defining some common methods, such as adding or deleting)
- Leaf role: A leaf node object in a combination that has no child nodes and is used to inherit or implement Abstract components.
- Composite Role/Intermediate Component: A branch node object in a composite that has child nodes for inheriting and implementing Abstract components. Its main function is to store and manage sub-parts, usually including Add(), Remove(), GetChild().
Combination modes are divided into transparent and safe combination modes.
(1) Transparency
In this way, since the abstract component declares all methods in all subclasses, the client is transparent to the client without having to distinguish between leaf and branch objects. The disadvantage is that leaf components do not have Add(), Remove(), and GetChild() methods but implement them (empty implementation or throw exceptions), which can cause some security problems. The structure diagram is shown in Figure 1.
Figure 1 Diagram of the structure of the transparent combination mode
(2) Safety methods
In this way, the method of managing sub-components is moved to the branch component. The abstract component and the leaf component do not have a method of managing sub-objects, which avoids the security problems of the previous method. However, because the leaves and branches have different interfaces, the client needs to know the existence of the leaf and branch objects when calling, so the transparency is lost. The structure diagram is shown in Figure 2.
Figure 2 Structural diagram of a secure combination mode
2. Implementation of patterns
If you want to access the elements in the collection c0={leaf1,{leaf2,leaf3}}, the corresponding tree graph is shown in Figure 3.
Figure 3 Tree of set c0
Transparent Combination Mode
Below is the implementation code for the transparent combination mode.
public class CompositePattern { public static void main(String[] args) { Component c0 = new Composite(); Component c1 = new Composite(); Component leaf1 = new Leaf("1"); Component leaf2 = new Leaf("2"); Component leaf3 = new Leaf("3"); c0.add(leaf1); c0.add(c1); c1.add(leaf2); c1.add(leaf3); c0.operation(); } } //Abstract component interface Component { public void add(Component c); public void remove(Component c); public Component getChild(int i); public void operation(); } //Leaf Component class Leaf implements Component { private String name; public Leaf(String name) { this.name = name; } public void add(Component c) { } public void remove(Component c) { } public Component getChild(int i) { return null; } public void operation() { System.out.println("Leaf" + name + ": Visited!"); } } //Branch Component class Composite implements Component { private ArrayList<Component> children = new ArrayList<Component>(); public void add(Component c) { children.add(c); } public void remove(Component c) { children.remove(c); } public Component getChild(int i) { return children.get(i); } public void operation() { for (Object obj : children) { ((Component) obj).operation(); } } }
The program runs as follows:
Leaf 1: Visited! Leaf 2: Visited! Leaf 3: Visited!
Security Composite Mode
The implementation code for the secure and transparent combination modes is similar, as long as you make simple changes to them, the code is as follows.
First modify the Component code to preserve only the hierarchical public behavior.
interface Component { public void operation(); }
Then modify the client code to change the branch component type to the Composite type to get a way to manage subclass operations.
public class CompositePattern { public static void main(String[] args) { Composite c0 = new Composite(); Composite c1 = new Composite(); Component leaf1 = new Leaf("1"); Component leaf2 = new Leaf("2"); Component leaf3 = new Leaf("3"); c0.add(leaf1); c0.add(c1); c1.add(leaf2); c1.add(leaf3); c0.operation(); } }
Scenarios for Composite Mode
The structure and characteristics of the combination mode are analyzed in the previous section, and the following scenarios are applied to it.
- When you need to represent the hierarchy of an object's whole and part.
- Where a user is required to hide a composite object from the user, unlike a single object, and use all objects in the composite structure with a uniform interface.
Extension of Combination Mode
If you abstract the leaf and branch nodes in the combination mode described earlier, that is, the leaf and branch nodes have child nodes, then the combination mode expands to a complex combination mode, such as Java AWT/Swing The simple component JTextComponent in has subclasses JTextField, JTextArea, and the container component Container has subclasses Window, Panel. The structure diagram of the complex combination pattern is shown in Figure 5.
Figure 5 Structural diagram of a complex combination pattern
extended reading
If you want to learn more about combinatorial patterns, you can read the following article at a glance.
- Using Transparent Combination Model to Implement Course Catalog Structure
- Using Secure Composite Mode for Infinite File System
- Application of Combination Mode in JDK Source
- Combination Mode in MyBatis Source