[big talk design mode] mode 6: combination mode and its application in JDK and Mybatis source code

[import]

The job functions of the head office and branches are similar, but the subsidiaries are included in the head office, as shown in the following figure:

The objects are combined into a tree structure to represent the "part whole" hierarchy. This pattern structure is called composite pattern.

1, Combination mode

Composite mode combines objects into a tree structure to represent the hierarchy of "part whole". The combination mode enables users to use single objects and combined objects consistently.

Classification:

The transparent composition mode (consistent composition mode) Component declares all the methods used to manage objects, including add (), remove (). Leaf nodes and branch nodes have no difference from the outside world and have completely consistent behavior interfaces. However, it should also be clear that it is meaningless for leaf to have add() and remove().

[code implementation]

Component class

public abstract class Component {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void add(Component component);
    public abstract void remove(Component component);
    public abstract void display(int depth);
}

Leaf class

public class Leaf extends Component {
    public Leaf(String name) {
        setName(name);
    }

    @Override
    public void add(Component component) {
        System.out.println("Leaves cannot add nodes");
    }

    @Override
    public void remove(Component component) {
        System.out.println("Leaves cannot delete nodes");
    }

    @Override
    public void display(int depth) {
        StringBuffer branch=new StringBuffer("");
        for(int i=0;i<depth;i++)
            branch.append("-");
        System.out.println("Leaf node:"+branch+getName());
    }
}

Composite class

public class Composite extends Component{
    private List<Component> children=new ArrayList<Component>();
    public Composite(String name){
        setName(name);
    }

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        StringBuffer branch=new StringBuffer("");
        for(int i=0;i<depth;i++)
            branch.append("-");
        System.out.println("Branch node:"+branch+getName());
        for(Component component:children){
            component.display(depth+1);
        }
    }
}

The safe combination mode {only specifies the most basic consistent behavior at all levels of the system, and puts the method of combination (tree node) (such as addChild of branch node management subclass) into itself.   

[code implementation]

Component class

public abstract class Component {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void display(int depth);
}

Leaf class

public class Leaf extends Component {
    public Leaf(String name) {
        setName(name);
    }

    @Override
    public void display(int depth) {
        StringBuffer branch=new StringBuffer("");
        for(int i=0;i<depth;i++)
            branch.append("-");
        System.out.println("Leaf node:"+branch+getName());
    }
}

Composite class

public class Composite extends Component {
    private List<Component> children = new ArrayList<Component>();

    public Composite(String name) {
        setName(name);
    }

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        StringBuffer branch = new StringBuffer("");
        for (int i = 0; i < depth; i++)
            branch.append("-");
        System.out.println("Branch node:" + branch + getName());
        for (Component component : children) {
            component.display(depth + 1);
        }
    }
}

Test class

public class Demo {
    public static void main(String[] args) {
        Composite root=new Composite("root");
        root.add(new Leaf("leaf A"));
        root.add(new Leaf("leaf B"));

        Composite composite1=new Composite("Composite1");
        root.add(composite1);
        composite1.add(new Leaf("leaf 1A"));
        composite1.add(new Leaf("leaf 1B"));
        root.add(new Leaf("leaf C"));

        root.display(1);
    }
}

Transparent combination mode vs. safe combination mode:

The characteristic of transparent mode is that all public methods of the composite object are defined in the abstract component. The advantage of this is that the client does not need to distinguish whether the current object belongs to a branch node or a leaf node, because they have a completely consistent interface, but the disadvantage is that the leaf node gets some methods that do not belong to it, For example, the addChild method above violates the principle of interface isolation. Unlike the transparent method, the leaf node in the full combination mode does not have the addChild function, so it cannot be called. In the above example, it can be called, but it is not supported after the call. This is the biggest difference between the two methods.

Combined applicable scenarios:

  • When the requirements reflect the structure of part and whole levels;
  • It is hoped that users can ignore the difference between composite objects and single objects and use all objects in the composite structure uniformly.

advantage:

  • The combination mode defines a class hierarchy containing basic objects (such as human resources department and Finance Department) and combination objects (such as branches, offices, etc.). The basic object can be combined into a more complex composite object, and the composite object can be combined. In this way, the composite object can be used wherever the basic object is used in the customer code;
  • The composite pattern allows customers to use composite structures and single objects consistently.

2, Application examples

Company class

public abstract class Company {

    protected String name;

    public Company(String name){
        this.name = name;
    }

    public abstract void add(Company company);//increase
    public abstract void remove(Company company);//remove
    public abstract void display(int depth);//display
    public abstract void lineofDuty();//Perform duties
}

Concrete company specific company category

public class ConcreteCompany extends Company {

    private List<Company> childrenCompany = new ArrayList<Company>();

    public ConcreteCompany(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {
        childrenCompany.add(company);
    }

    @Override
    public void display(int depth) {
        System.out.println("The first " + depth + " The organization name of the layer is: " + name);
        for (Company c : childrenCompany) {
            c.display(depth + 1);
        }
    }

    @Override
    public void lineofDuty() {
        for (Company c : childrenCompany) {
            c.lineofDuty();
        }
    }

    @Override
    public void remove(Company company) {
        childrenCompany.remove(company);
    }

}
/**
 * Finance Department
 */
public class FinanceDepartment extends Company {

    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        System.out.println("The first " + depth + " The organization name of the layer is: " + name);
    }

    @Override
    public void lineofDuty() {
        System.out.println(name + "   Be responsible for the company's financial revenue and expenditure management");
    }

    @Override
    public void remove(Company company) {

    }

}
/**
 * Human Resources Department
 */
public class HRDepartment extends Company {

    public HRDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void display(int depth) {
        System.out.println("The first " + depth + " The organization name of the layer is: " + name);
    }

    @Override
    public void lineofDuty() {
        System.out.println(name + "    Responsible for staff recruitment management training");
    }

    @Override
    public void remove(Company company) {

    }

}

Client class

public class Client {
        public static void main(String[] args) {

            //A head office
            ConcreteCompany root = new ConcreteCompany("Beijing head office");
            root.add(new HRDepartment("Head office human resources department"));
            root.add(new FinanceDepartment("Head office finance department"));

            //Three subsidiaries
            ConcreteCompany com1 = new ConcreteCompany("Guangzhou Branch");
            com1.add(new HRDepartment("Human Resources Department of Guangzhou Branch"));
            com1.add(new FinanceDepartment("Finance Department of Guangzhou Branch"));
            root.add(com1);

            ConcreteCompany com2 = new ConcreteCompany("Hangzhou branch ");
            com2.add(new HRDepartment("Human Resources Department of Hangzhou Branch"));
            com2.add(new FinanceDepartment("Finance Department of Hangzhou Branch"));
            root.add(com2);

            ConcreteCompany com3 = new ConcreteCompany("Shenzhen Branch");
            com3.add(new HRDepartment("Human Resources Department of Shenzhen Branch"));
            com3.add(new FinanceDepartment("Finance Department of Shenzhen Branch"));
            root.add(com3);

            System.out.println("-------Company structure chart--------");
            root.display(1);
            System.out.println("----------Responsibilities of each department----------");
            root.lineofDuty();

        }

    }

[result]

3, Embodiment of combination mode in JDK and mybatis source code

1. In JDK:

  • Container class. As can be seen from the method add(), what it adds is its parent class, which conforms to the design of composition pattern
  • There is a putAll method in HashMap, and the parameter is a Map, which is also the embodiment of a combination mode.  
  • The addAll method in ArrayList is the same

 2,Mybatis:

There are multi-level labels under the interface, which conforms to the design of combination mode.

If the article is useful to you, support it for three times!!!

Keywords: Java Design Pattern

Added by Third_Degree on Sat, 29 Jan 2022 22:48:41 +0200