设计模式-组合模式
概念
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。
优点
1、高层模块调用简单。
2、节点自由增加。
缺点
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
角色
1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
使用场景
1、您想表示对象的部分-整体层次结构(树形结构)。
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
案例场景
生成一个菜单树
UML类图
代码解析UML类图
/** * 设计模式-组合模式-组合接口 * * Created by laizhiyuan on 2017/6/12. */ public abstract class MenuComponent { /** * 菜单名字 */ private String menuName; /** * 菜单级别 */ private int level; public MenuComponent(String menuName, int level) { this.menuName = menuName; this.level = level; } /** * 添加菜单 * * @param menu */ public abstract void addMenu(MenuComponent menu); /** * 移除菜单 * * @param menu */ public abstract void removeMenu(MenuComponent menu); /** * 生成菜单树 */ public abstract void generate(); public String getMenuName() { return menuName; } public void setMenuName(String menuName) { this.menuName = menuName; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } }
/** * 设计模式-组合模式-枝节点 * * 枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。 * 这里指菜单 * * Created by laizhiyuan on 2017/6/12. */ public class MenuComposite extends MenuComponent{ /** * 树枝内部组合该接口 */ private List<MenuComponent> childMenu = new ArrayList<MenuComponent>(); public MenuComposite(String menuName, int level) { super(menuName, level); } @Override public void addMenu(MenuComponent menu) { childMenu.add(menu); } @Override public void removeMenu(MenuComponent menu) { childMenu.remove(menu); } @Override public void generate() { String temp ; if (this.getLevel() == 1){ System.out.println("!"); System.out.println("-" + this.getMenuName()); } for (MenuComponent menu : childMenu){ System.out.println("!"); temp = ""; while (menu.getLevel() > 0){ menu.setLevel(menu.getLevel() - 1); temp += "-"; } System.out.println(temp + menu.getMenuName()); menu.generate(); } } }
/** * 设计模式-组合模式-叶子节点 * * 表示叶子结点对象,叶子结点没有子结点。 * * Created by laizhiyuan on 2017/6/13. */ public class MenuLeaf extends MenuComponent{ public MenuLeaf(String menuName, int level) { super(menuName, level); } @Override public void addMenu(MenuComponent menu) { /** * 叶子节点没有添加功能 */ } @Override public void removeMenu(MenuComponent menu) { /** * 叶子节点没有删除功能 */ } @Override public void generate() { } }
测试
/** * Created by laizhiyuan on 2017/6/12. */ public class Main { public static void main(String[] args) { MenuComposite root = new MenuComposite("系统管理", 1); MenuComponent child = new MenuComposite("用户管理", 2); MenuComponent child2 = new MenuComposite("部门管理", 2); root.addMenu(child); root.addMenu(child2); MenuLeaf child3 = new MenuLeaf("添加用户", 3); MenuLeaf child4 = new MenuLeaf("删除用户", 3); child.addMenu(child3); child.addMenu(child4); root.generate(); } }