组合模式(Composite Pattern)又称作整体-部分(Part-Whole)模式,其宗旨是通过将单个对象(叶子节点)和组织对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的使用具有一致性,属于结构型设计模式。
(1)模式的结构
主要角色如下:
(2)组合模式有两种
透明组合模式: 组织接口中声明用来管理子对象的所有行为方法,好处就是树枝节点和叶子节点对外界没有区别,它们具备完全一致的行为接口,缺点时,叶子节点本身不具备组织接口的行为方法,所以实现它们是没有意义的。安全组合模式: 组织接口中不声明用来管理子对象的所有行为方法,所以叶子节点也就不需要去实现它们。而是在组织节点中声明用来管理子对象的所有行为方法。这样做由于不够透明,树枝节点和叶子节点将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。优点:
缺点:
代码如下:
public class CompositePattern1 {public static void main(String[] args) {Component1 root = new Composite1("root");Component1 branch1 = new Composite1("branch1");Component1 branch2 = new Composite1("branch2");Component1 leaf1 = new Leaf1("leaf1");Component1 leaf2 = new Leaf1("leaf2");Component1 leaf3 = new Leaf1("leaf3");Component1 leaf4 = new Leaf1("leaf4");root.addChild(branch1);root.addChild(leaf3);branch1.addChild(leaf1);branch1.addChild(branch2);branch2.addChild(leaf2);branch2.addChild(leaf4);String display = root.display();System.out.println(display);System.out.println("===============");System.out.println("branch2.getChild(1).display() -> " + branch2.getChild(1).display());branch2.removeChild(leaf4);String display2 = root.display();System.out.println(display2);}
}// 抽象组成角色
abstract class Component1 {protected String name;public Component1(String name) {this.name = name;}public abstract String display();public boolean addChild(Component1 component1) {throw new RuntimeException(" addChild 不支持");}public boolean removeChild(Component1 component1) {throw new RuntimeException(" removeChild 不支持");}public Component1 getChild(int index) {throw new RuntimeException(" getChild 不支持");}}// 组织对象角色
class Composite1 extends Component1 {private List component1List;public Composite1(String name) {super(name);this.component1List = new ArrayList();}@Overridepublic String display() {StringBuilder sb = new StringBuilder(this.name);for (int i = 0; i < component1List.size(); i++) {Component1 component1 = component1List.get(i);sb.append("\n");sb.append(component1.display());}return sb.toString();}@Overridepublic boolean addChild(Component1 component1) {return component1List.add(component1);}@Overridepublic boolean removeChild(Component1 component1) {return component1List.remove(component1);}@Overridepublic Component1 getChild(int index) {return component1List.get(index);}
}// 单个对象角色
class Leaf1 extends Component1 {public Leaf1(String name) {super(name);}@Overridepublic String display() {return this.name;}
}

代码如下:
public class CompositePattern2 {public static void main(String[] args) {Composite2 root = new Composite2("root");Composite2 branch1 = new Composite2("branch1");Composite2 branch2 = new Composite2("branch2");Component2 leaf1 = new Leaf2("leaf1");Component2 leaf2 = new Leaf2("leaf2");Component2 leaf3 = new Leaf2("leaf3");Component2 leaf4 = new Leaf2("leaf4");root.addChild(branch1);root.addChild(leaf3);branch1.addChild(leaf1);branch1.addChild(branch2);branch2.addChild(leaf2);branch2.addChild(leaf4);String display = root.display();System.out.println(display);System.out.println("===============");System.out.println("branch2.getChild(1).display() -> " + branch2.getChild(1).display());branch2.removeChild(leaf4);String display2 = root.display();System.out.println(display2);}
}// 抽象组成角色
abstract class Component2 {protected String name;public Component2(String name) {this.name = name;}public abstract String display();}// 组织对象角色
class Composite2 extends Component2 {private List component2List;public Composite2(String name) {super(name);this.component2List = new ArrayList();}@Overridepublic String display() {StringBuilder sb = new StringBuilder(this.name);for (int i = 0; i < component2List.size(); i++) {sb.append("\n");Component2 component2 = component2List.get(i);sb.append(component2.display());}return sb.toString();}public boolean addChild(Component2 component2) {return component2List.add(component2);}public boolean removeChild(Component2 component2) {return component2List.remove(component2);}public Component2 getChild(int index) {return component2List.get(index);}
}// 单个对象角色
class Leaf2 extends Component2 {public Leaf2(String name) {super(name);}@Overridepublic String display() {return this.name;}
}
以文件系统为例,目录包含文件夹和文件。下面使用安全组合模式实现。
(1)目录:抽象组成角色
public abstract class Directory {protected String name;public Directory(String name) {this.name = name;}public abstract void show();
}
(2)文件夹:组织对象角色
public class Folder extends Directory {private List dirList;private Integer depth;public Folder(String name, Integer depth) {super(name);this.depth = depth;dirList = new ArrayList<>();}public void list() {for (Directory dir : this.dirList) {System.out.println(dir.name);}}@Overridepublic void show() {System.out.println(this.name);for (Directory dir : this.dirList) {if (this.depth != null) {for (Integer integer = 0; integer < this.depth; integer++) {System.out.print(" ");}for (Integer integer = 0; integer < this.depth; integer++) {if (integer == 0) {System.out.print("+");}System.out.print("-");}}dir.show();}}public boolean addChild(Directory directory) {return dirList.add(directory);}public boolean removeChild(Directory directory) {return dirList.remove(directory);}public Directory getChild(int index) {return dirList.get(index);}
}
(3)文件:单个对象角色
public class File extends Directory{public File(String name) {super(name);}@Overridepublic void show() {System.out.println(this.name);}
}
(4)测试
public static void main(String[] args) {Folder root = new Folder("root", 1);File dy = new File("抖音.exe");File qq = new File("QQ.exe");root.addChild(dy);root.addChild(qq);Folder office = new Folder("办公软件", 2);File word = new File("Word.exe");File ppt = new File("PPT.exe");File excel = new File("Excel.exe");office.addChild(word);office.addChild(ppt);office.addChild(excel);Folder devTools = new Folder("开发工具", 3);File idea = new File("idea.exe");File navicat = new File("navicat.exe");devTools.addChild(idea);devTools.addChild(navicat);office.addChild(devTools);root.addChild(office);System.out.println("========show方法======");root.show();System.out.println("========list方法======");root.list();}

– 求知若饥,虚心若愚。