组合模式
描述
组合模式用于描述部分与整体的关系,将个体对象与组合对象的行为统一,便于维护整个数据集。
基本使用
所有节点方法一致
- 定义通用操作抽象组件
java
public abstract class AbstractComponent {
private final String name;
protected AbstractComponent(String name) {
this.name = name;
}
public void description() {
System.out.println("name: " + this.name);
}
public abstract void addItem(AbstractComponent child);
public abstract void deleteItem(AbstractComponent child);
public abstract List<AbstractComponent> getChildren();
}
- 定义树枝节点
java
public class ComplexComponent extends AbstractComponent {
private final List<AbstractComponent> children = new ArrayList<>();
protected ComplexComponent(String name) {
super(name);
}
public void addItem(AbstractComponent child) {
children.add(child);
}
public void deleteItem(AbstractComponent child) {
children.remove(child);
}
public List<AbstractComponent> getChildren() {
return children;
}
}
- 定义叶子节点
java
public class LeafComponent extends AbstractComponent {
protected LeafComponent(String name) {
super(name);
}
@Override
public void addItem(AbstractComponent child) {
}
@Override
public void deleteItem(AbstractComponent child) {
}
@Override
public List<AbstractComponent> getChildren() {
return null;
}
}
使用
由于所有节点操作一致,在使用中无需强转
java
public class Sample {
public static void main(String[] args) {
AbstractComponent root = new ComplexComponent("L1");
AbstractComponent l2 = new ComplexComponent("L2");
root.addItem(l2);
AbstractComponent l2_1 = new ComplexComponent("L2_1");
AbstractComponent l2_2 = new ComplexComponent("L2_2");
l2.addItem(l2_1);
l2.addItem(l2_2);
AbstractComponent l2_1_1 = new ComplexComponent("L2_1_1");
l2_1.addItem(l2_1_1);
AbstractComponent l2_1_2 = new ComplexComponent("L2_1_2");
l2_1.addItem(l2_1_2);
printComponent(root);
}
private static void printComponent(AbstractComponent root) {
root.description();
root.getChildren().forEach(component -> {
if (component instanceof ComplexComponent) {
printComponent(component);
} else {
component.description();
}
});
}
}
叶子无实现子节点
- 定义通用操作的抽象组件
java
public abstract class AbstractComponent {
private final String name;
protected AbstractComponent(String name) {
this.name = name;
}
public void description() {
System.out.println("name: " + this.name);
}
}
- 定义树枝节点
java
public class ComplexComponent extends AbstractComponent {
private final List<AbstractComponent> children = new ArrayList<>();
protected ComplexComponent(String name) {
super(name);
}
public void addItem(AbstractComponent child) {
children.add(child);
}
public void deleteItem(AbstractComponent child) {
children.remove(child);
}
public List<AbstractComponent> getChildren() {
return children;
}
}
- 定义叶子节点
java
public class LeafComponent extends AbstractComponent {
protected LeafComponent(String name) {
super(name);
}
}
使用
java
public class Sample {
public static void main(String[] args) {
ComplexComponent root = new ComplexComponent("L1");
ComplexComponent l2 = new ComplexComponent("L2");
root.addItem(l2);
ComplexComponent l2_1 = new ComplexComponent("L2_1");
ComplexComponent l2_2 = new ComplexComponent("L2_2");
l2.addItem(l2_1);
l2.addItem(l2_2);
ComplexComponent l2_1_1 = new ComplexComponent("L2_1_1");
l2_1.addItem(l2_1_1);
ComplexComponent l2_1_2 = new ComplexComponent("L2_1_2");
l2_1.addItem(l2_1_2);
printComponent(root);
}
private static void printComponent(ComplexComponent root) {
root.description();
root.getChildren().forEach(component -> {
if (component instanceof ComplexComponent) {
printComponent((ComplexComponent) component);
} else {
component.description();
}
});
}
}
添加向上查询
在有的场景中,需要支持向上查询。
可以在通用抽象中定义一个上级节点,然后在父节点添加子节点同时为子节点关联父节点
- 定义通用抽象组件
java
public abstract class AbstractComponent {
private final String name;
/**
* 新增了一个父级成员
*/
private AbstractComponent parent;
protected AbstractComponent(String name) {
this.name = name;
}
public void description() {
System.out.println("name: " + this.name + " parent: " + (Objects.isNull(getParent()) ? "null" : getParent().getName()));
}
public abstract void addItem(AbstractComponent child);
public abstract void deleteItem(AbstractComponent child);
public abstract List<AbstractComponent> getChildren();
public void setParent(AbstractComponent parent) {
this.parent = parent;
}
public AbstractComponent getParent() {
return parent;
}
public String getName() {
return name;
}
}
- 定义树枝节点
java
public class ComplexComponent extends AbstractComponent {
private final List<AbstractComponent> children = new ArrayList<>();
protected ComplexComponent(String name) {
super(name);
}
/**
* 在添加子节点时 同时设置子节点的父级节点
* @param child
*/
public void addItem(AbstractComponent child) {
children.add(child);
child.setParent(this);
}
/**
* 在移除子节点时 同时清空子节点的父级节点
* @param child
*/
public void deleteItem(AbstractComponent child) {
children.remove(child);
child.setParent(null);
}
public List<AbstractComponent> getChildren() {
return children;
}
}
- 定义叶子节点(没变化)
java
public class LeafComponent extends AbstractComponent {
protected LeafComponent(String name) {
super(name);
}
@Override
public void addItem(AbstractComponent child) {
}
@Override
public void deleteItem(AbstractComponent child) {
}
@Override
public List<AbstractComponent> getChildren() {
return null;
}
}
使用(没变化)
java
public class Sample {
public static void main(String[] args) {
AbstractComponent root = new ComplexComponent("L1");
AbstractComponent l2 = new ComplexComponent("L2");
root.addItem(l2);
AbstractComponent l2_1 = new ComplexComponent("L2_1");
AbstractComponent l2_2 = new ComplexComponent("L2_2");
l2.addItem(l2_1);
l2.addItem(l2_2);
AbstractComponent l2_1_1 = new ComplexComponent("L2_1_1");
l2_1.addItem(l2_1_1);
AbstractComponent l2_1_2 = new ComplexComponent("L2_1_2");
l2_1.addItem(l2_1_2);
printComponent(root);
}
private static void printComponent(AbstractComponent root) {
root.description();
root.getChildren().forEach(component -> {
if (component instanceof ComplexComponent) {
printComponent(component);
} else {
component.description();
}
});
}
}