Combination mode
definition
Definition of Composite Pattern: sometimes called part whole pattern, it is a pattern that combines objects into a tree hierarchy, which is used to represent the relationship between "whole part", so that users can have consistent access to single objects and composite objects. It belongs to structural type Design mode.
characteristic
In the combination mode, the objects in the whole tree structure belong to the same type. The advantage is that users do not need to distinguish whether it is a branch node or a leaf node. They can operate directly, which brings great convenience to users.
The main advantages of the combination mode are:
-
The combination mode enables the client code to deal with a single object and a combined object consistently, without caring whether it is a single object or a combined object, which simplifies the client code;
-
It is easier to add new objects into the assembly, and the client will not change the source code because of the addition of new objects, meeting the "opening and closing principle";
Its main disadvantages are: -
The design is complex, and the client needs to spend more time to clarify the hierarchical relationship between classes;
-
It is not easy to limit the components in the container;
-
It is not easy to use the method of inheritance to add new functions of components;
structure
The composite mode contains the following main roles.
- Abstract Component role: its main role is to declare public interfaces for leaf components and branch components and implement their default behavior. In the transparent composition mode, the abstract Component also declares the interface to access and manage subclasses; In the safe combination mode, the interface for accessing and managing subclasses is not declared, and the management work is completed by the branch Component. (general abstract classes or interfaces, defining some general methods, such as adding and deleting)
- Leaf role: it is a leaf node object in the composition. It has no child nodes and is used to inherit or implement abstract components.
- Composite role / intermediate component: it is a branch node object in the composition. It has child nodes, which are used to inherit and implement abstract components. Its main function is to store and manage sub components, which usually includes methods such as add(), remove(), etc.
The combination mode is divided into transparent combination mode and safe combination mode.
realization
Transparent
public abstract class Component { private String name; void add(Component component){ throw new UnsupportedOperationException(); } public Component(String name){ this.name = name; } void remove(Component component){ throw new UnsupportedOperationException(); } abstract void print(); public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class UnitComposite extends Component{ public UnitComposite(String name){ super(name); } List<Component> list = new ArrayList<Component>(); @Override public String getName() { return super.getName(); } @Override public void setName(String name) { super.setName(name); } @Override void add(Component component){ list.add(component); } @Override void remove(Component component){ list.remove(component); } @Override void print() { System.out.println("Unit name:"+getName()+"--------------"); list.forEach(Component::print); } }
public class DeptLeaf extends Component{ public DeptLeaf(String name){ super(name); } @Override public String getName() { return super.getName(); } @Override public void setName(String name) { super.setName(name); } @Override void print() { System.out.println("Department Name:"+getName()); } }
public class Client { public static void main(String[] args) { Component root = new UnitComposite("headquarters"); Component a1 = new UnitComposite("Branch 1"); Component a2 = new UnitComposite("Branch 12"); Component a3 = new UnitComposite("Branch 3"); Component leaf1 = new DeptLeaf("Design Department"); Component leaf2 = new DeptLeaf("Development Department"); Component leaf3 = new DeptLeaf("Sales Department"); Component leaf4 = new DeptLeaf("Finance Department"); root.add(a1); root.add(a3); a1.add(leaf1); a1.add(leaf2); a2.add(leaf3); a2.add(leaf4); a1.add(a2); root.print(); //a1.print(); // a2.print(); } }
Safety type
Similar to transparent, the two classes have a little change.
- Componet deletes the add remove method
- Change the Client Component type to unitcomponent
public abstract class Component { private String name; public Component(String name){ this.name = name; } abstract void print(); public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Client { public static void main(String[] args) { UnitComposite root = new UnitComposite("headquarters"); UnitComposite a1 = new UnitComposite("Branch 1"); UnitComposite a2 = new UnitComposite("Branch 12"); UnitComposite a3 = new UnitComposite("Branch 3"); Component leaf1 = new DeptLeaf("Design Department"); Component leaf2 = new DeptLeaf("Development Department"); Component leaf3 = new DeptLeaf("Sales Department"); Component leaf4 = new DeptLeaf("Finance Department"); root.add(a1); root.add(a3); a1.add(leaf1); a1.add(leaf2); a2.add(leaf3); a2.add(leaf4); a1.add(a2); root.print(); //a1.print(); // a2.print(); } }