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

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

组合模式:

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

 

 


设计模式的了解-组合模式
 示例:

定义树形节点:

/**
 * 树节点,具有添加移除子节点,遍历所有节点的能力
 * @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;
			}
			
		});
	}
}