OO模式-Composite

组合模式也叫做“部分-整体”模式,这样其实定义也就很明显了,正好和数据结构的知识相对应,把对象组合成树形结构以表示“部分-整体”的层次结构。

先看类图:


     首先分析一下这个类图,Leaf和Composite是同辈的,都是继承父类Component,又因为Component中存在Leaf子类,所以他和Component还存在着聚合关系


     举一个很常见的例子,我们天天对着电脑,和各种文件,文件夹打交道,这不就是一个很好地组合模式吗?

来看看类图:


    来看看具体的实现代码:

    AbstractFile为组合中的对象声明接口,实现所有类共有接口的默认行为。

  1. package composite; 
  2.  
  3. import java.util.*;    //添加引用 
  4.  
  5. public abstract class AbstractFile { 
  6.     protected String name; // 定义name字段 
  7.  
  8.     public void printName() { 
  9.         System.out.println(name); 
  10.     } 
  11.  
  12.     // 通常都用add和remove方法来提供增加或移除树叶或树枝的功能 
  13.     public abstract boolean addChild(AbstractFile file); // 增加 
  14.  
  15.     public abstract boolean removeChild(AbstractFile file); // 移除 
  16.     // 一个集合,存放摘要文件的子文件的对象 
  17.  
  18.     public abstract List<AbstractFile> getChildren(); 
package composite;

import java.util.*;    //添加引用

public abstract class AbstractFile {
	protected String name; // 定义name字段

	public void printName() {
		System.out.println(name);
	}

	// 通常都用add和remove方法来提供增加或移除树叶或树枝的功能
	public abstract boolean addChild(AbstractFile file); // 增加

	public abstract boolean removeChild(AbstractFile file); // 移除
	// 一个集合,存放摘要文件的子文件的对象

	public abstract List<AbstractFile> getChildren();
}
    File为子类文件,继承父类,也是树中所谓的叶子节点,叶子节点是没有子节点的,所以父类所谓的方法并不能实现,返回true和null

  1. package composite; 
  2.  
  3. import java.util.*; 
  4.  
  5. public class File extends AbstractFile { 
  6.     public File(String name) { 
  7.         this.name = name; 
  8.     } 
  9. //文件并没有添加的能力,它只是一个单独的个体 
  10.     public boolean addChild(AbstractFile file) { 
  11.         return false
  12.     } 
  13. //对于文件本身,已经是叶子节点了,所以也无删除子文件的功能 
  14.     public boolean removeChild(AbstractFile file) { 
  15.         return false
  16.     } 
  17.  
  18.     // 由于File已经是叶子节点了,所以就不存在集合这一说,所以这个方法返回的是空值 
  19.     public List<AbstractFile> getChildren() { 
  20.         return null
  21.     } 
package composite;

import java.util.*;

public class File extends AbstractFile {
	public File(String name) {
		this.name = name;
	}
//文件并没有添加的能力,它只是一个单独的个体
	public boolean addChild(AbstractFile file) {
		return false;
	}
//对于文件本身,已经是叶子节点了,所以也无删除子文件的功能
	public boolean removeChild(AbstractFile file) {
		return false;
	}

	// 由于File已经是叶子节点了,所以就不存在集合这一说,所以这个方法返回的是空值
	public List<AbstractFile> getChildren() {
		return null;
	}
}
    Folder为子类文件夹,同样也继承于父类,但是此类只是一个普通的节点,里边依旧包含叶子节点。

  1. package composite; 
  2.  
  3. import java.util.*; 
  4.  
  5. public class Folder extends AbstractFile { 
  6.      
  7.     private List<AbstractFile> childList ; 
  8.  
  9.     public Folder(String name) { 
  10.         this.name = name; 
  11.         //用来建立一个集合保存子文件 
  12.         this.childList = new ArrayList<AbstractFile>(); 
  13.     } 
  14.     //添加子文件 
  15.     public boolean addChild(AbstractFile file) { 
  16.         return childList.add(file); 
  17.     } 
  18.     //删除子文件 
  19.     public boolean removeChild(AbstractFile file) { 
  20.         return childList.remove(file); 
  21.     } 
  22.  
  23.     // 子类的返回类型应该和父类的定义保持一致 
  24.     public List<AbstractFile> getChildren() { 
  25.         return childList; 
  26.     } 
  27.  
package composite;

import java.util.*;

public class Folder extends AbstractFile {
	
	private List<AbstractFile> childList ;

	public Folder(String name) {
		this.name = name;
		//用来建立一个集合保存子文件
		this.childList = new ArrayList<AbstractFile>();
	}
	//添加子文件
	public boolean addChild(AbstractFile file) {
		return childList.add(file);
	}
	//删除子文件
	public boolean removeChild(AbstractFile file) {
		return childList.remove(file);
	}

	// 子类的返回类型应该和父类的定义保持一致
	public List<AbstractFile> getChildren() {
		return childList;
	}

}
最后来看看客户端是如何调用和打印的

  1. package composite; 
  2.  
  3. import java.util.List; 
  4.  
  5. public class Client { 
  6.     public static void main(String[] args) { 
  7.         // TODO 自动生成的方法存根 
  8.         // 构造一个树形的文件、目录结构 
  9.         AbstractFile rootFolder = new Folder("c:\\"); 
  10.         AbstractFile compositeFolder = new Folder("composite"); 
  11.         AbstractFile windowsFolder = new Folder("windows"); 
  12.         AbstractFile file = new File("TestComposite.java"); 
  13.  
  14.         rootFolder.addChild(compositeFolder); 
  15.         rootFolder.addChild(windowsFolder); 
  16.         compositeFolder.addChild(file); 
  17.         // 打印目录文件树 
  18.         printTree(rootFolder); 
  19.     } 
  20.  
  21.     private static void printTree(AbstractFile ifile) { 
  22.         ifile.printName(); 
  23.         List<AbstractFile> children = ifile.getChildren(); 
  24.         if (children == null
  25.             return
  26.         for (AbstractFile file : children) { 
  27.             printTree(file); // 打印方法的调用 
  28.         } 
  29.     } 
package composite;

import java.util.List;

public class Client {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		// 构造一个树形的文件、目录结构
		AbstractFile rootFolder = new Folder("c:\\");
		AbstractFile compositeFolder = new Folder("composite");
		AbstractFile windowsFolder = new Folder("windows");
		AbstractFile file = new File("TestComposite.java");

		rootFolder.addChild(compositeFolder);
		rootFolder.addChild(windowsFolder);
		compositeFolder.addChild(file);
		// 打印目录文件树
		printTree(rootFolder);
	}

	private static void printTree(AbstractFile ifile) {
		ifile.printName();
		List<AbstractFile> children = ifile.getChildren();
		if (children == null)
			return;
		for (AbstractFile file : children) {
			printTree(file); // 打印方法的调用
		}
	}
}

透明方式与安全方式

     在File子类中,他所谓的各种方法都是不实行的,但是却依旧存在,这种方式就叫做“透明方式”;这样做的好处就是叶子节点和枝节点对于外界没有区别,它们具备完全一致的行为接口;但是问题也会很明显的,那就是在File中那些所谓的方法的存在是毫无意义的;

     如果不想让其做无用功,也就是把File子类中的无意义的方法都去掉,这种方式叫做“安全方式”;但是由于是不透明的,所以他们就不能具有一致的接口了,这样反而增加了其复杂性,客户端的调用需要再增加其相应的判断。


什么时候使用组合模式?

     1)需求中体现的是“部分-整体”的层次的结构时,使用此模式;

     2)用户希望忽略组合对象与单个对象的不同,统一地使用组合结构中的所有的对象的时候,使用此模式;


最后总结:

     每个模式其实都是需要慢慢理解的,真正的懂得了它的精髓所在,那当再看到类似的字眼的时候就会有亲近的感觉,对于组合模式总结为以下几点:

  •      组合模式提供一个结构,可同时包容个别对象和组合对象;
  •      允许客户对个别对象以及组合对象一视同仁;
  •      组合结构内的任意对象都称为组件,组件可以是组合,也可以是叶子节点;
  •      在实现组合模式时,有许多设计上的折衷。这时候就要就情况选择透明方式还是安全方式了!

     Composite是构造型的设计模式之一,通过递归手段来构造诸如文件系统之类的属性的对象结构。知识之间是相互连通的,就看你是不是选择最短路径了!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值