​​十三、组合模式(Composite)_ide


一、什么是组合模式

        将对象组合成树形结构以表示’部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。


二、组合模式角色

    1、Component (树形结构的节点抽象):为组合中的对象声明接口(公共属性,行为等的定义),实现所有类共有接口的默认行为, [可选]提供管理父节点对象的接口方法。

    2、Leaf (树形结构的叶节点):在组合模式中表示叶子节点,叶子节点没有子节点。

    3、Composite(树形结构的枝节点):定义枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如Add和Remove。


三、组合模式类图

        十三、组合模式(Composite)_ide_02


四、组合模式代码

    1、Component

public abstract class Component {

protected String name;

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


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

}

    2、Leaf 

public class Leaf extends Component {

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

@Override
public void add(Component component) {
System.out.println("叶子节点下不能添加节点!!!");
}

@Override
public void remove(Component component) {
System.out.println("叶子节点不能执行删除操作!!!");
}

@Override
public void display(int deep) {
StringBuilder sb = new StringBuilder();
for (int i = 0;i<deep;i++){
sb.append("-");
}
System.out.println(sb.append(this.name).toString());
}
}

    3、Composite

public class Composite extends Component {

private List<Component> nodeList;

public Composite(String name) {
super(name);
nodeList = new ArrayList<>();
}

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

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

@Override
public void display(int deep) {
StringBuilder sb = new StringBuilder();
for (int i = 0;i<deep;i++){
sb.append("-");
}
System.out.println(sb.append(this.name).toString());

nodeList.forEach(n -> n.display(deep + 1));
}
}

    4、客户端

public class MainClass {

public static void main(String[] args) {
Component root = new Composite("C:");
Component programFiles = new Composite("Program Files");
Component aTxt = new Leaf("a.txt");

root.add(programFiles); //添加文件夹
root.add(aTxt);

Component git = new Composite("Git");
Component bJava = new Leaf("b.java");
programFiles.add(git);
git.add(bJava);


root.display(0);
}
}

    5、运行结果

        十三、组合模式(Composite)_Leaf_03


五、透明方式和安全方式

        我们上面实现的方式就是透明方式,在Component中声明了所有用来管理子对象的方法,其中包括add,remove。这样实现Component接口的所有子类都具备了add和remove方法。这样做的好处就是叶子节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但是因为Leaf类本身不具备add、remove方法的功能,所以实现它没有意义。

        安全方式,就是在Component接口中不声明add和remove方法,Leaf就不用实现它,在Composite中声明所有用来管理子类的方法,不过由于不够透明,客户端调用需要做相应的判断,带来了不便。