设计模式学习十二:组合模式

一.概念

     组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

 

二.UML

  1. Component(对象接口),定义了对象可以做的事情。
  2. Leaf(叶子结点对象)。
  3. Composite(其它结点对象)。

三.实例分析

     网上购物的时候,我们会发现,快递时一层一层下来的,我在北京朝阳区六里屯街道买了一个东西,物品会依次经过六里屯街道-朝阳区-深圳-深圳南山这样的顺序邮寄到我手里。我们可以看出,每个地区都会有一个大的投递点,然后再往下细分。从中,我抽象了这么几个类。说明:顺丰快递总公司实际在深圳,但为了更清楚的说明组合模式,我将"顺丰公司"放在了一个更高的层次。

 

 

     SFCompany

package com.zzy.composite;

/**
 * 顺丰公司抽象类
 * 定义了公司可以做哪些事情
 * @author eason
 *
 */
public abstract class SFCompany {
	
	//公司名
	protected String name;
	//公司级别
	protected int grade;
	
	public SFCompany(String name, int grade) {
		this.name = name;
		this.grade = grade;
	}
	
	//添加一个下属公司
	public abstract void add(SFCompany sf);
	//删除一个下属公司
	public abstract void remove(SFCompany sf);
	//打印自己
	public void display() {
		for(int i=1; i<=grade; i++) {
			System.out.print("-----");
		}
		System.out.println(name);
	}
	
}
 

     SFTailCompany

package com.zzy.composite;


/**
 * 最下层的公司
 * @author eason
 *
 */
public class SFTailCompany extends SFCompany{
	
	public SFTailCompany(String name, int grade) {
		super(name, grade);
	}

	@Override
	public void add(SFCompany sf) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void remove(SFCompany sf) {
		throw new UnsupportedOperationException();
	}
	
//  已经提到父类中
//	@Override
//	public void display() {
//		for(int i=1; i<=grade; i++) {
//			System.out.print("-----");
//		}
//		System.out.println(name);
//	}
}
 

     SFHeadCompany

package com.zzy.composite;

import java.util.ArrayList;
import java.util.List;

/**
 * 有下属公司的顺丰公司
 * @author eason
 *
 */
public class SFHeadCompany extends SFCompany{
	//保存下属公司
	private List<SFCompany> sfCompanys = new ArrayList<SFCompany>();
	
	public SFHeadCompany(String name, int grade) {
		super(name, grade);
	}

	@Override
	public void add(SFCompany sf) {
		sfCompanys.add(sf);
	}

	@Override
	public void remove(SFCompany sf) {
		sfCompanys.remove(sf);
	}

	//先打印自己,在打印自己的下属
	@Override
	public void display() {
//  已经提到父类中,用super.display();代替
//		for(int i=1; i<=grade; i++) {
//			System.out.print("-----");
//		}
//		System.out.println(name);
		super.display();
		for(SFCompany sf : sfCompanys) {
			sf.display();
		}
	}

}
 

     TestCompostite

package com.zzy.composite;

/**
 * 测试类
 * @author eason
 *
 */
public class TestCompostite {

	public static void main(String[] args) {
		SFCompany head = new SFHeadCompany("总公司", 1);
		SFCompany shenzhen = new SFHeadCompany("深圳分公司", 2);
		SFCompany wuhan = new SFHeadCompany("武汉分公司", 2);
		SFCompany beijing = new SFHeadCompany("北京分公司", 2);
		SFCompany wuchang = new SFHeadCompany("武昌分公司", 3);
		SFCompany baoan = new SFHeadCompany("宝安分公司", 3);
		SFCompany luohu = new SFHeadCompany("罗湖分公司", 3);
		SFCompany nanshan = new SFHeadCompany("南山分公司", 3);
		
		head.add(shenzhen);
		head.add(wuhan);
		head.add(beijing);
		
		wuhan.add(wuchang);
		
		shenzhen.add(baoan);
		shenzhen.add(luohu);
		shenzhen.add(nanshan);
		//移除武汉
		//head.remove(wuhan);
		
		head.display();
		
	}

}

     其结果如下:移除武汉是左图

    

 

四.使用场景及使用感受

  1. 需求中体现的是整体和部分的层次关系,以及用户希望忽略整体与部分的不同,统一的使用整体对象和部分对象时,就应该考虑组合模式。
  2. 组合模式让你可以优化处理递归或分级数据结构。如文件系统结构。

 

public static void showDetails(File f) {
		//如果是目录
		if(f.isDirectory()){
			//拿到跟目录下所有文件,迭代后递归
			File[] files = f.listFiles();
			for(File file : files) {
				showDetails(file);
			}
		//如果是文件,打印
		}else {
			System.out.println(f.getAbsolutePath());
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值