Composite mode (java)

Let's start with an official statement

Composite > pattern, also known as partial overall pattern, is used to treat a group of similar objects as a single object. The combination mode combines objects according to the tree structure, which is used to represent the partial and overall levels. This type of design pattern is a structural pattern, which creates a tree structure of object groups. This pattern creates a class that contains its own group of objects. This class provides a way to modify the same object group.

How, do you feel empty after reading it? Anyway, I can't understand it, but there are two sentences that are important and worth remembering. "It belongs to structural mode" and "combined mode combines objects according to tree structure to represent part and overall level". The latter sentence is equivalent to indicating the applicable scenario of combined mode, which is applicable to tree structure. How can it be regarded as tree structure, such as:
(want to look directly at the code and turn down)

A combination method can be used for similar structures. If we follow our consistent thinking, we should think of: first, a breakfast class, and then steamed stuffed bun and corn inherit the breakfast class, and then. In this way, it is inherited level by level as shown in the figure. The structure is not like this when using composite mode. Here is the UML diagram I drew with my feet. It is not standard, but it can be seen.

As can be seen from the figure, the following three levels inherit a Component class, which feels like a brotherhood. Components have their public default behaviors, such as adding and deleting. For the "breakfast" in the first line of the first figure, it has steamed stuffed buns and corn, which can be added (add an egg type (tea egg and quail egg...). For the "steamed stuffed buns" in the second line of the first figure, it has green vegetables and steamed stuffed cabbage, and it can also be added (add a milk bag). However, there is no addition operation for the third line, because it is no longer extensible and can be regarded as a leaf node.
The following code demonstrates it again:
Create a contributor abstract class

public abstract class Component {
    private String name;//name
    private String desc;//describe

	//add to
    protected void add(Component component){}
	//delete
    protected void remove(Component component){}
	//Print
    protected void print(){}

    public Component(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

Create the EatTime class and inherit the Component

//Meal time (breakfast, lunch, lunch)
public class EatTime extends Component{

	//This list can be understood as indicating its next level. If this class represents (breakfast), then the list represents the type of food for breakfast (steamed stuffed bun, corn,...),
	//So the list contains things about breakfast. If it's lunch, it's the same understanding
    private List<Component>  eatCategoryList = new ArrayList<>();

    public EatTime(String name, String desc) {
        super(name, desc);
    }

	//Here are three common actions to override
    @Override
    protected void add(Component component) {
        eatCategoryList.add(component);
    }

    @Override
    protected void remove(Component component) {
        eatCategoryList.remove(component);
    }

    @Override
    protected void print() {
        System.out.println("===================="+getName()+"=======================");
        eatCategoryList.forEach(item-> item.print());
    }
}

Create EatCategory and inherit Component

//Classification of food (steamed stuffed bun, corn ·)
public class EatCategory extends Component{

    //This is understandable
    //This list can be understood as indicating its next level. If this class represents (steamed stuffed bun), then the list represents the type of food for breakfast (milk yellow bun, plum cabbage bun...),
    private ArrayList<Component> eatFoodArrayList = new ArrayList<>();

    public EatCategory(String name, String desc) {
        super(name, desc);
    }
    
	//Here are three common actions to override
    @Override
    protected void add(Component component) {
        eatFoodArrayList.add(component);
    }

    @Override
    protected void remove(Component component) {
        eatFoodArrayList.remove(component);
    }

    @Override
    protected void print() {
        System.out.println("========"+getName()+"=======");
        eatFoodArrayList.forEach(item-> item.print());
    }
}

Create the EatFood class and inherit the Component

//Specific types of food (milk yellow bag, plum vegetable bag ··)
public class EatFood extends Component{

    public EatFood(String name, String desc) {
        super(name, desc);
    }

	//There is no adding or deleting behavior here. For example, there is no subdivision under the milk yellow bag, that is, it is a leaf node
    @Override
    protected void print() {
        System.out.println(getName());
    }
}

Let's test it

public class Client {
    public static void main(String[] args) {
        Component eatTime = new EatTime("breakfast","Breakfast time 6-8 spot");

        Component eatCategory = new EatCategory("steamed stuffed bun","Steamed stuffed bun thief is delicious");

        Component food1 = new EatFood("Tea tree mushroom bun", "1 Dollars");
        Component food2 = new EatFood("Steamed pork bun with plum vegetables", "1.5 Dollars");
        Component food3 = new EatFood("Stewed pork bun", "2 Dollars");

        eatTime.add(eatCategory);
        eatCategory.add(food1);
        eatCategory.add(food2);
        eatCategory.add(food3);


        Component eatCategory1 = new EatCategory("Corn","Corn thief is delicious");
        Component food4 = new EatFood("Northeast corn", "5 Dollars");
        Component food5 = new EatFood("Southwest corn", "1.5 Dollars");
        Component food6 = new EatFood("Northwest corn", "8 Dollars");

        eatTime.add(eatCategory1);
        eatCategory1.add(food4);
        eatCategory1.add(food5);
        eatCategory1.add(food6);


        eatTime.print();


        /**
         * The output results are as follows:
         * 
         * ====================Breakfast=======================
         * ========Steamed stuffed bun=======
         * Tea tree mushroom bun
         * Steamed pork bun with plum vegetables
         * Stewed pork bun
         * ========Corn=======
         * Northeast corn
         * Southwest corn
         * Northwest corn
         * 
         */
    }
}

The combination mode is also known as the part whole mode. In real life, there are many "part whole" relationships, such as the relationship between cars and tires and engines, the relationship between hospitals and departments and doctors, and the relationship between schools and colleges, students and teachers.

Tags: Java Back-end

Posted on Thu, 18 Nov 2021 07:14:23 -0500 by saqibb