设计模式——组合模式(Composite Pattern)

组合模式(Composite Pattern)

    概念:组合模式有时候也叫做"部分-整体"的模式,在处理树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂的元素,从而使得客户程序与复杂元素的内部结构解耦。组合模式使得客户对单个对象和组合对象的使用具有一致性。

组合模式分两种:

一、安全形式的组合模式

   如果把管理子组件的操作定义在Composite中,那么客户在使用叶子对象的时候,就不会发生使用添加子组件或是删除子组件的操作了,因为压根就没有这样的功能,这种实现方式是安全的。但是这样一来,客户端在使用的时候,就必须区分到底使用的是Composite对象,还是叶子对象,不同对象的功能是不一样的。也就是说,这种实现方式,对客户而言就不是透明的了。


安全式组合模式

二、透明形式的组合模式

    如果把管理子组件的操作定义在Component中,那么客户端只需要面对Component,而无需关心具体的组件类型,这种实现方式就是透明性的实现。事实上,前面示例的实现方式都是这种实现方式。但是透明性的实现是以安全性为代价的,因为在Component中定义的一些方法,对于叶子对象来说是没有意义的,比如:增加、删除子组件对象。而客户不知道这些区别,对客户是透明的,因此客户可能会对叶子对象调用这种增加或删除子组件的方法,这样的操作是不安全的。

    组合模式的透明性实现,通常的方式是:在Component中声明管理子组件的操作,并在Component中为这些方法提供缺省的实现,如果是有子对象不支持的功能,缺省的实现可以是抛出一个例外,来表示不支持这个功能。



透明式组合模式


两种组合模式的共同构成:

1、Component:组合模式的对象接口声明,用于访问和管理其子组件。

2、Leaf:表示叶子节点对象,叶子节点无子节点,并实现了Component的所有方法

3、Composite:组合部件含有子部件,并实现了操作子部件的所有方法,实现了Component的所有方法


组合模式的应用举例:

        最常见的组合模式应用就是文件系统,文件系统是树形结构。当我们对单个文件进行如复制、剪切和删除等操作时和对某个文件夹做同类操作时感觉是一样的,都像是在操作某个文件。现在我们来简单模拟一下复制操作,采用安全模式的代码如下:

//组合模式的公共接口 用于声明一些通用操作
public interface Component {
	void copy();
}

//组合模式的leaf
public class File implements Component {

	private String filename;
	
	public File(String filename) {
		this.filename = filename;
	}

	@Override
	public void copy() {
		System.out.println("复制文件" + filename);
	}

}

import java.util.ArrayList;
//组合模式的composite
public class Folder implements Component {
	
	private ArrayList<Component> comList;
	private String folderName;
	
	public Folder(String folderName) {
		this.comList = new ArrayList<Component>(0);
		this.folderName = folderName;
	}

	public void add(Component com){
		comList.add(com);
	}
	
	public void remove(Component com){
		comList.remove(com);
	}

	@Override
	public void copy() {
		System.out.println("复制文件夹:" + folderName);
		for(Component c:comList){
			c.copy();
		}
		
	}

}

//客户类 用于测试
public class Client {

	public static void main(String[] args) {
		//创建文件夹
		Folder folder = new Folder("资料文件夹");
		Folder bookFolder = new Folder("书籍文件夹");
		Folder filmFolder = new Folder("影音文件夹");
		//创建文件
		File book1 = new File("设计模式。pdf");
		File book2 = new File("简爱。txt");
		File film1 = new File("第四区。avi");
		File film2 = new File("功夫。avi");
		
		//将filmFolder和bookFolder文件放到folder文件夹下
		folder.add(filmFolder);
		folder.add(bookFolder);
		//将film1和film1文件放到filmFolder文件夹下
		filmFolder.add(film1);
		filmFolder.add(film2);
		//将book1和book2文件放到bookFolder文件夹下
		filmFolder.add(book1);
		filmFolder.add(book2);
		
		//复制文设计模式。pdf
		System.out.println("------------------复制文设计模式。pdf操作------------------");
		book1.copy();
		//复制资料文件夹
		System.out.println("--------------------复制资料文件夹操作--------------------");
		folder.copy();
		
	}

}

运行结果:




优点:

1、定义了包括基本对象和组合组合对象的层次结构,基本对象可以被组合成更复杂的对象,而且这个对象还可以被组合。
2、简化了客户代码。
3、使得更容易增加新类型的组件。
4、使设计变得更变通。


组合模式的应用场景:

1、需要表示对象的“部分-整体”的层次关系。
2、需求是用户对单个对象和组合对象的使用具有一致性


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值