Design pattern - structural pattern combination pattern

Posted by GESmithPhoto on Sun, 23 Jan 2022 17:38:14 +0100

See the display needs of a school department

Write a program to display the department structure of a school: the demand is that the Department composition of the school should be displayed on one page. A school has multiple colleges and a college has multiple departments. As shown in the figure:

Traditional solution school department display (class diagram)

Analysis on the problems existing in the display of schools and departments with traditional solutions

  1. The college is regarded as a subclass of the school, and the Department is a subclass of the college. In fact, it is hierarchical based on the size of the organization
  2. In fact, our requirement is to display the composition of colleges and departments of the school in one page. A school has multiple colleges and a college has multiple departments. This scheme can not well realize the management operations, such as adding, deleting, traversing, etc. of colleges and departments
  3. Solution: schools, colleges and departments are regarded as organizational structures. There is no inheritance relationship between them, but a tree structure, which can better realize management operations. = > Combination mode

Basic introduction to combination mode

  1. Composite Pattern, also known as partial overall pattern, creates a tree structure of object groups and combines objects into a tree structure to represent the hierarchical relationship of "whole part".
  2. The combination mode combines objects according to the tree structure, which is used to represent the partial and overall levels.
  3. This type of design pattern belongs to structural pattern.
  4. The combination mode makes the user's access to single objects and combined objects consistent, that is, combination allows customers to deal with individual objects and combined objects in a consistent way

Schematic class diagram of combined mode

Description of schematic structure diagram - i.e. (roles and responsibilities of combination mode)

  1. Component: This is the object declaration interface in the composition. If appropriate, it implements the default behavior of the interface common to all classes for access and management

Component subassemblies, which # can be abstract classes or interfaces

  1. Leaf: represents a leaf node in a combination. A leaf node has no child nodes
  2. Composite: a non leaf node, which is used to store subcomponents and implement related operations of subcomponents in the Component} interface, such as add and delete.

Application example of combination mode to solve the display of school departments

Application example requirements

  1. Write a program to display the department structure of a school: the demand is that the Department composition of the school should be displayed on one page. A school has multiple colleges and a college has multiple departments.
  2. Train of thought analysis and illustration (class diagram)
  3. code implementation
    package com.atguigu.composite;
    
    /**
     * @Author panghl
     * @Date 2021/6/26 11:43
     * @Description TODO
     **/
    public abstract class OrganizationComponent {
    
        private String name;
        private String des;
    
        protected void add(OrganizationComponent component){
            //Default implementation
            throw new UnsupportedOperationException("Operation not supported");
        }
        protected void remove(OrganizationComponent component){
            //Default implementation
            throw new UnsupportedOperationException("Operation not supported");
        }
    
        //constructor 
        public OrganizationComponent(String name, String des) {
            super();
            this.name = name;
            this.des = des;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
    
        //The method print is made abstract, and subclasses need to be implemented
        protected abstract void print();
    
    }
    
    package com.atguigu.composite;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Author panghl
     * @Date 2021/6/26 11:46
     * @Description University It is Composite, which can manage the College
     **/
    public class University extends OrganizationComponent {
    
        List<OrganizationComponent> organizationComponents = new ArrayList<>();
    
        public University(String name, String des) {
            super(name, des);
        }
    
        @Override
        protected void add(OrganizationComponent component) {
            organizationComponents.add(component);
        }
    
        @Override
        protected void remove(OrganizationComponent component) {
            organizationComponents.remove(component);
        }
    
        @Override
        public String getName() {
            return super.getName();
        }
    
        @Override
        public String getDes() {
            return super.getDes();
        }
    
        //The print method is to output the colleges included in the University
        @Override
        protected void print() {
            System.out.println("==========="+super.getName()+"========");
            //Traverse organizationComponents
            for (OrganizationComponent organizationComponent : organizationComponents) {
                organizationComponent.print();
            }
        }
    
    }
    

    package com.atguigu.composite;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Author panghl
     * @Date 2021/6/26 11:52
     * @Description TODO
     **/
    public class College extends OrganizationComponent {
    
        //Department stored in List
        List<OrganizationComponent> organizationComponents = new ArrayList<>();
    
        public College(String name, String des) {
            super(name, des);
        }
    
        @Override
        protected void add(OrganizationComponent component) {
            //In the actual business in the future, College add and University add may not be exactly the same
            organizationComponents.add(component);
        }
    
        @Override
        protected void remove(OrganizationComponent component) {
            organizationComponents.remove(component);
        }
    
        @Override
        public String getName() {
            return super.getName();
        }
    
        @Override
        public String getDes() {
            return super.getDes();
        }
    
        //The print method is to output the colleges included in the University
        @Override
        protected void print() {
            System.out.println("==========="+super.getName()+"========");
            //Traverse organizationComponents
            for (OrganizationComponent organizationComponent : organizationComponents) {
                organizationComponent.print();
            }
        }
    }
    
    package com.atguigu.composite;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Author panghl
     * @Date 2021/6/26 11:54
     * @Description TODO
     **/
    public class Department extends OrganizationComponent {
    
        //The collection is gone
    
        public Department(String name, String des) {
            super(name, des);
        }
    
    
        @Override
        public String getName() {
            return super.getName();
        }
    
        @Override
        public String getDes() {
            return super.getDes();
        }
    
    
        //Add and remove do not need to be written because they are leaf nodes
        @Override
        protected void print() {
            System.out.println(getName());
        }
    
    }
    

    package com.atguigu.composite;
    
    /**
     * @Author panghl
     * @Date 2021/6/26 11:56
     * @Description TODO
     **/
    public class Client {
        public static void main(String[] args) {
            //Create object school from Avenue
            OrganizationComponent university = new University("Tsinghua University","First class universities in China");
    
            //Create College
            OrganizationComponent college1 = new College("school of computing", "Cheng xuape");
            OrganizationComponent college2 = new College("School of Information Engineering", "Lead wire");
    
            //Create departments (majors) under each college
            OrganizationComponent department1 = new Department("software engineering", "software development");
            OrganizationComponent department2 = new Department("Computer science and technology", "Computer science and technology");
            OrganizationComponent department3 = new Department("Network engineering", "Network engineering");
            OrganizationComponent department4 = new Department("communication engineering", "communication engineering");
    
            college1.add(department1);
            college1.add(department2);
            college2.add(department3);
            college2.add(department4);
            university.add(college1);
            university.add(college2);
    
            university.print();
        }
    }
    

Source code analysis of composite pattern in JDK set

  1. The Java collection class HashMap uses the composite pattern
  2. Code analysis + Debug source code

Class diagram:

package com.atguigu.jdk;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author panghl
 * @Date 2021/6/26 12:08
 * @Description TODO
 **/
public class Composite {
    public static void main(String[] args) {

        /**
         * explain
         * 1,Map It is an abstract build (similar to our Component)
         * 2,HashMap Is an intermediate composite that implements / inherits related methods
         *          put,putAll 
         * 3,Node It is a static internal class of HashMap, similar to the Leaf node of Leaf. There are no put and putall here
         *    static class Node<K,V>  implements Map.Entry<K,V>
         */

        Map<String, String> map1 = new HashMap<>();
        map1.put("0","Journey to the East");
        Map<String, String> map2 = new HashMap<>();
        map2.put("1","Journey to the West");
        map2.put("2","The Dream of Red Mansion");
        map1.putAll(map2);
        System.out.println(map1);
    }
}

Notes and details of combination mode

  1. Simplify client operations. The client only needs to face consistent objects without considering the whole part or node leaf.
  2. It has strong scalability. When we want to change the composite object, we only need to adjust the internal hierarchical relationship, and the client does not need to make any changes
  3. Facilitate the creation of complex hierarchies. The client does not care about the composition details in the composition, and it is easy to add nodes or leaves to create a complex tree structure
  4. When you need to traverse the organization, or the object you are dealing with has a tree structure, it is very suitable to use the composite mode
  5. It requires high abstraction. If there are many differences between nodes and leaves, for example, many methods and attributes are different, it is not suitable to use composite mode

Topics: Design Pattern