1、模式简介
组合模式可以将对象以树形结构来表现“整体/部分”层次结构,让客户以一致的方式处理个别形象以及对象组合。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。使用组合模式,我们能把相同的操作应用在组合的个别对象上,换句话说,我们可以忽略对象组合的个别对象之间的差别。
2、案例
本例是模拟电脑中文件系统的层级结构。我们定义了一个文件的实体类MyFile,其中除了名称(name)、是否是文件夹(isDir)、文件大小(size)、所处层级(level)外,还有一个子文件列表的引用。代码如下:
文件实体类MyFile.java中的代码:
import java.util.ArrayList; import java.util.List; public class MyFile { private String name; // 文件名称 private boolean isDir; // 是否是文件夹,是返回true,否则返回false private double size; // 文件大小 private int level; // 文件所在的层级,根文件是0级 private List<MyFile> subFiles; // 文件的子文件(只有文件夹才有子文件) public MyFile() { subFiles = new ArrayList<>(); } public MyFile(String name, boolean isDir, double size, int level) { this(); this.name = name; this.isDir = isDir; this.size = size; this.level = level; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isDir() { return isDir; } public void setDir(boolean isDir) { this.isDir = isDir; } public double getSize() { return size; } public void setSize(double size) { this.size = size; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public List<MyFile> getSubFiles() { return subFiles; } public void setSubFiles(List<MyFile> subFiles) { this.subFiles = subFiles; } public void addSubFile(MyFile file) { this.subFiles.add(file); } @Override public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 1; i <= level; i++) { sb.append("----"); } sb.append("(" + (isDir() ? "dir" : "file") + ")"); sb.append(getName()); sb.append("(" + getSize() + "K)"); return sb.toString(); } }
测试类Test.java中的代码:
import java.util.List; public class Test { public static void main(String[] args) { // 初始化文件结构树 MyFile rootDir = initFileTree(); // 按层级打印文件结构树 printFileInfo(rootDir); } // 初始化文件结构树 private static MyFile initFileTree() { MyFile rootDir = new MyFile("rootDir", true, 100, 0); MyFile subDir1_1 = new MyFile("subDir1_1", true, 50, 1); MyFile subFile2_1_1 = new MyFile("subFile2_1_1", false, 10, 2); MyFile subFile2_1_2 = new MyFile("subFile2_1_2", false, 15, 2); MyFile subDir2_1_1 = new MyFile("subDir2_1_1", true, 25, 2); MyFile subDir2_1_2 = new MyFile("subDir2_1_2", true, 0, 2); MyFile subFile3_1_1_1 = new MyFile("subFile3_1_1_1", false, 19, 3); MyFile subFile3_1_1_2 = new MyFile("subFile3_1_1_2", false, 6, 3); subDir2_1_1.addSubFile(subFile3_1_1_1); subDir2_1_1.addSubFile(subFile3_1_1_2); subDir1_1.addSubFile(subFile2_1_1); subDir1_1.addSubFile(subFile2_1_2); subDir1_1.addSubFile(subDir2_1_1); subDir1_1.addSubFile(subDir2_1_2); rootDir.addSubFile(subDir1_1); MyFile subDir1_2 = new MyFile("subDir1_2", true, 30, 1); MyFile subFile2_2_1 = new MyFile("subFile2_2_1", false, 22, 2); MyFile subFile2_2_2 = new MyFile("subFile2_2_2", false, 8, 2); subDir1_2.addSubFile(subFile2_2_1); subDir1_2.addSubFile(subFile2_2_2); rootDir.addSubFile(subDir1_2); MyFile subDir1_3 = new MyFile("subDir1_3", true, 20, 1); MyFile subDir2_3_1 = new MyFile("subDir2_3_1", true, 20, 2); MyFile subDir3_3_1_1 = new MyFile("subDir2_3_1_1", true, 20, 3); MyFile subDir4_3_1_1_1 = new MyFile("subDir2_3_1_1_1", true, 20, 4); MyFile subFile5_3_1_1_1_1 = new MyFile("subFile2_3_1_1_1_1", false, 20, 5); subDir4_3_1_1_1.addSubFile(subFile5_3_1_1_1_1); subDir3_3_1_1.addSubFile(subDir4_3_1_1_1); subDir2_3_1.addSubFile(subDir3_3_1_1); subDir1_3.addSubFile(subDir2_3_1); rootDir.addSubFile(subDir1_3); return rootDir; } // 递归打印文件树信息 private static void printFileInfo(MyFile file) { System.out.println(file.toString()); List<MyFile> subFiles = file.getSubFiles(); if (subFiles != null && subFiles.size() > 0) { for (MyFile subFile : subFiles) { printFileInfo(subFile); } } else { } } }
运行结果如下图所示:
最后贴出组合模式在GitHub中的代码:【GitHub - Composite】。