设计模式的理解--组合模式

本文介绍了一种常用的设计模式——组合模式,并通过一个具体的菜单结构示例展示了如何使用该模式来组织对象,使得客户端能够一致地处理单个对象或对象组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

组合模式:

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

 

 



 示例:

定义树形节点:

/**
 * 树节点,具有添加移除子节点,遍历所有节点的能力
 * @author yanlei
 *
 */
public interface TreeNode {
	
	public void addTreeNode(TreeNode treeNode) ;
	public void removeTreeNode(TreeNode treeNode); 
	public boolean isLeaf();
	/**
	*内部遍历:forEach方法会调用子节点的forEach方法,每一个forEach方法内部都调用TreeNodeIterable.iterate,并向
 * 			   TreeNodeIterable.pushParent保存当前父节点,通过TreeNodeIterable.iterate的
 * 			      返回值确定是否继续遍历,可以知道当前节点的父节点链。
 * 
	*/
	public boolean forEach(TreeNodeIterable treeComponentOperator);
	
}

 具体实现:

/**
 * 树节点的实现
 * @author yanlei
 *
 */
public class TreeNodeImpl implements TreeNode{
	Collection<TreeNode> childs = null;
	private Collection<TreeNode> getChilds(){
		if(childs == null){
			childs = new LinkedList();
		}
		return childs;
	}
	private boolean haveNoChild(){
		return childs ==null || childs.isEmpty();
	}
	@Override
	public boolean isLeaf() {
		// TODO Auto-generated method stub
		return haveNoChild();
	}
	public void setCollection(Collection<TreeNode> collection) {
		this.childs = collection;
	}

	@Override
	public boolean forEach(TreeNodeIterable treeNodeIterable) {
		// TODO Auto-generated method stub
		
		if(treeNodeIterable.iterate(this) ){
			boolean flag = true;
			if(!this.isLeaf()){
				treeNodeIterable.pushParent(this);
				Iterator<TreeNode> iterator = this.childs.iterator();
				while(iterator.hasNext()){
					flag = iterator.next().forEach(treeNodeIterable);
					if(!flag){
						 break;
					}
				}
				treeNodeIterable.popParent();
			}
			return flag;
		}else{
			return false;
		}
	}

	@Override
	public void addTreeNode(TreeNode treeComponet)
			throws UnsupportedOperationException {
		// TODO Auto-generated method stubT
		this.getChilds().add(treeComponet);
	}

	@Override
	public void removeTreeNode(TreeNode treeComponet)
			throws UnsupportedOperationException {
		// TODO Auto-generated method stub
		this.getChilds().remove(treeComponet);
	}
}
 
/**
 * 树节点遍历时,对每个节点的处理类
 * @author yanlei
 *
 */
public interface TreeNodeIterable<T extends TreeNode> {
	/**
	 * 保存当前父节点
	 * @param treeComponent
	 */
	public void pushParent(T treeNode);
	/**
	 * 移除当前父节点
	 * @return
	 */
	public void popParent();
	/**
	 * 对当前节点操作
	 * @param treeComponent
	 * @return
	 */
	public boolean iterate(T treeNode);
}
 

测试类:
import java.util.ArrayList;
import java.util.List;

import org.springframework.util.StringUtils;

/**
 * 菜单
 * @author yanlei
 */
public class Menu extends TreeNodeImpl{
	
	
	public Menu(String name, int id) {
		super();
		this.name = name;
		this.id = id;
	}

	String name;
	int id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	public static void main(String[] args){
		Menu mainMenu = new Menu("主菜单",1);
		Menu sysMenu = new Menu("系统管理",2);
		sysMenu.addTreeNode(new Menu("用户管理",3));
		sysMenu.addTreeNode(new Menu("权限管理",4));
		sysMenu.addTreeNode(new Menu("审批流程管理",5));
		mainMenu.addTreeNode(sysMenu);
		Menu reportMenu = new Menu("报表展示",6);
		Menu subMenu1 = new Menu("用户统计报表",7);
		subMenu1.addTreeNode(new Menu("用户点击率统计",8));
		reportMenu.addTreeNode(subMenu1);
		reportMenu.addTreeNode(new Menu("业务办理情况月表",8));
		mainMenu.addTreeNode(reportMenu);
		//打印出菜单项(不含菜单目录)的全路径
		mainMenu.forEach(new TreeNodeIterable<Menu>(){
			List list = new ArrayList();
			@Override
			public void pushParent(Menu menu) {
				// TODO Auto-generated method stub
				list.add(menu.getName());
			}

			@Override
			public void popParent() {
				// TODO Auto-generated method stub
				 list.remove(list.size()-1);
			}

			@Override
			public boolean iterate(Menu menu) {
				// TODO Auto-generated method stub
				if(menu.isLeaf()){
					System.out.println(StringUtils.arrayToDelimitedString(list.toArray(), "-")+"-"+menu.getName());
					/**
					输出:
					主菜单-系统管理-用户管理
					主菜单-系统管理-权限管理
					主菜单-系统管理-审批流程管理
					主菜单-报表展示-用户统计报表-用户点击率统计
					主菜单-报表展示-业务办理情况月表
					**/
				}
				return true;
			}
			
		});
	}
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值