【设计模式 - 8】之组合模式(Composite)

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】


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值