order
Orders are very common in our daily life. Sometimes an order contains other orders, as follows:
The order contains two sub orders and a bottle of milk, and the two sub orders have their own contents. In this way, an order tree is formed. The specific goods are leaf nodes and orders are non leaf nodes. As follows:
So what should we do with this tree structure? The answer is to use combination mode
Combination mode
Composite mode is a structural design mode. You can use it to combine objects into a tree structure, and you can use them like independent objects. Therefore, composite mode is also called "partial overall mode".
code
Next, let's use the code to feel the combination mode.
Define top-level interfaces
First, we define the top-level interface. I call it "calculatable", which means something that can be valued. In the later code, anything can be valued.
/** * @author skyline */ public interface CalculateAble { /** * Calculate price */ double calculate(); /** * Current trade name * @return */ String name(); /** * Add another computable node * @param calculateAble */ default void add(CalculateAble calculateAble) {} /** * Get product list * @return */ default List<CalculateAble> getCalculateAbleList() { return null; } }
Some specific goods
Next, we define some specific commodities, which are tree leaf nodes.
Apple
public class Apple implements CalculateAble { @Override public double calculate() { return 20; } @Override public String name() { return "apple"; } }
notebook
public class AlienWareNoteBook implements CalculateAble { @Override public double calculate() { return 25000; } @Override public String name() { return "alienWareNoteBook"; } }
milk
public class Milk implements CalculateAble { @Override public double calculate() { return 25; } @Override public String name() { return "Milk"; } }
Tea
public class Tea implements CalculateAble { @Override public double calculate() { return 99; } @Override public String name() { return "tea"; } }
order
There will be multiple products in an order, so the order object is a tree non leaf node
public class Order implements CalculateAble { private final List<CalculateAble> calculateAbles; private final String name; public Order(String name) { this.calculateAbles = new ArrayList<>(); this.name = name; } @Override public double calculate() { //The total price of the order and the sum of the prices of all items included in the order double sum = 0; for (CalculateAble calculateAble : calculateAbles) { sum += calculateAble.calculate(); } return sum; } @Override public String name() { return name; } @Override public void add(CalculateAble calculateAble) { calculateAbles.add(calculateAble); } @Override public List<CalculateAble> getCalculateAbleList() { return calculateAbles; } }
main
Finally, let's look at the main method
public class CompositeMain { public static void main(String[] args) { //Create an order called order CalculateAble order = new Order("order"); //Create an order called smallOrder CalculateAble smallOrder = new Order("smallOrder"); //Add an item to smallOrder: Apple smallOrder.add(new Apple()); //Add an item to smallOrder: tea smallOrder.add(new Tea()); //Create an order called bigOrder CalculateAble bigOrder = new Order("bigOrder"); //Add an item to bigOrder: notebook bigOrder.add(new AlienWareNoteBook()); //Add smallOrder to order order.add(smallOrder); //Add bigOrder to order order.add(bigOrder); //Add milk to order order.add(new Milk()); //Recursive printing tree loop(order, 0); //Calculate total price double calculate = order.calculate(); System.out.println("The total price is:" + calculate); } private static void loop(CalculateAble calculateAble, int level) { if (level == 0) { } else if (level == 1) { System.out.print("├─"); } else { for (int i = 0; i < level - 1; i++) { System.out.print("│ "); } System.out.print("├─"); } System.out.println(calculateAble.name()); List<CalculateAble> calculateAbleList = calculateAble.getCalculateAbleList(); if (calculateAbleList != null) { for (CalculateAble able : calculateAbleList) { loop(able, level + 1); } } } }
Finally, let's look at the implementation results:
From the results, we can see that the tree printed by the program is the same as the tree we drew at the beginning. There is no problem with the calculation of the total price.
summary
- If you want to deal with tree data, you can consider composite patterns
- If you want to handle simple objects (Apple, Tea, Alienware notebook, Milk) and complex objects (Order) in the same way, you can also use the composite mode