设计模式的了解-组合模式
设计模式的理解--组合模式
组合模式:
允许你将对象组合成树形结构来表现“整体/部分”层次结构,组合能让客户以一致的方式来处理个别对象以及组合对象。
示例:
定义树形节点:
/** * 树节点,具有添加移除子节点,遍历所有节点的能力 * @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; } }); } }