java设计模式之组合模式
设计模式种的组合模式不是类与类之间那个组合。
而是只业务逻辑种的那种树形数据结构,比如文件目录、公司的组织架构等。
这种模式在实际的项目开发中并不那么常用。但是,一旦数据满足树形结构,应用这种模式就能发挥很大的作用,能让代码变得非常简洁。
我们以文件目录为例,通过实现一个文件目录树来理解组合模式。
首先实现一个抽象目录类
public abstract class FileSystemNode { protected String path; public FileSystemNode(String path) { this.path = path; } public String getPath() { return path; } /** * 统计文件个数 * @return */ public abstract int countNumOfFiles(); /** * 统计文件大小 * @return */ public abstract long countSizeOfFiles(); /** * 遍历目录 */ public abstract void travel(); }
它有两个子类,分别是文件类和目录类,文件类代表目录中的一个文件
public class File extends FileSystemNode { public File(String path) { super(path); } @Override public int countNumOfFiles() { return 1; } @Override public long countSizeOfFiles() { java.io.File file = new java.io.File(path); if(!file.exists()){ return 0; } return file.length(); } @Override public void travel() { System.out.println(path); } }
目录类下可以是一个或多个文件,也可能有几个目录。
public class Directory extends FileSystemNode { private ListsubNodes = new ArrayList<>(); public Directory(String path) { super(path); } @Override public int countNumOfFiles() { int numFiles = 0; for (FileSystemNode subNode : subNodes) { numFiles += subNode.countNumOfFiles(); } return numFiles; } @Override public long countSizeOfFiles() { int fileSizes = 0; for (FileSystemNode subNode : subNodes) { fileSizes += subNode.countSizeOfFiles(); } return fileSizes; } @Override public void travel() { for (FileSystemNode subNode : subNodes) { if(subNode instanceof File){ System.out.println(subNode.getPath()); }else if(subNode instanceof Directory){ subNode.travel(); } } } public void addSubNode(FileSystemNode fileOrDir) { subNodes.add(fileOrDir); } public void removeSubNode(FileSystemNode fileOrDir) { int size=subNodes.size(); int curNode=Integer.MAX_VALUE; for(int i=0;i ){ if(subNodes.get(i).getPath().equals(fileOrDir.getPath())){ curNode=i; break; } } if(curNode<size){ subNodes.remove(curNode); } } }
入口类
public class Application { public static void main(String[] args) { String baseDir="/Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/"; Directory algorithm = new Directory(baseDir+"algorithm"); Directory basic = new Directory(baseDir+"algorithm/basic"); Directory other = new Directory(baseDir+"algorithm/other"); File lru = new File(baseDir + "algorithm/basic/LRU.java"); File heap = new File(baseDir + "algorithm/basic/MHeap.java"); File hashmap = new File(baseDir + "algorithm/basic/MHashMap.java"); basic.addSubNode(lru); basic.addSubNode(heap); basic.addSubNode(hashmap); File gcd = new File(baseDir + "algorithm/other/GCD.java"); File matrix = new File(baseDir + "algorithm/other/MatrixBasic.java"); File decompose = new File(baseDir + "algorithm/other/MatrixDecompose.java"); other.addSubNode(gcd); other.addSubNode(matrix); other.addSubNode(decompose); algorithm.addSubNode(basic); algorithm.addSubNode(other); System.out.println(algorithm.countNumOfFiles()); System.out.println(algorithm.countSizeOfFiles()); algorithm.travel(); } }
输出:
6 12269 /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/basic/LRU.java /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/basic/MHeap.java /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/basic/MHashMap.java /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/other/GCD.java /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/other/MatrixBasic.java /Users/gaochengcheng/Documents/gitlab/java-mine/data-structure/src/main/java/com/example/java/algorithm/other/MatrixDecompose.java