Composite 组合模式
目录
[TOC]
1. 概述
1.1. 设计模式定义
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
1.2. 自我理解
组合模式的第一要义,就是将树形结构的数据,用一个类,或者少数一两个类,就可以拼装成一棵树的形状
组合模式的第二要义,就是直接对一个父级的数据执行某个操作,这个操作会直接递归调用所有下层的子数据的相关操作
通过这个树形结构自己递归自己的方式,就将对一棵树的操作,完美的执行了
好处,就是对树形数据的操作,不需要调用方组织复杂的屎一样的if for的代码,去执行
外部要操作一颗树,直接对树的父级节点,调用一个操作,这颗树自己就递归着把事儿给干完了
1.3. 组合模式的组成
Component (抽象构件:容器):它可以是接口或者抽象类,为叶子构建和子容器构建对象声明接口,在该角色中可以包含所有子类共有的行为的实现和声明。在抽象构建中定义了访问及管理它的子构件的方法,如增加子构件,删除子构件,获取子构件等。
Leaf(叶子构建):叶子构建可以说就是各种类型的文件!叶子构建没有子构件。它实现了抽象构建中的定义的行为。对于那些访问子容器,删除子容器,增加子容器的就报错。
Compsite(子容器构建):它在组合模式中表示容器节点对象,容器结点是子节点,可以是子容器,也可以是叶子构建,它提供一个集合来存储子节点。
2. UML
3. Example
3.1. 场景
实现一个系统的菜单设计,这里我并没有按照命令模式的具体角色去做案例,因为个人觉得任何模式都是设计思想,思想并不是固定的,而是一定要运用到实际开发中来。
就说这个叶子节点,并无用,我用一个变量去限制是否为叶子节点即可。
组合模式的要求是定义一个树形结构,并且针对该树的操作可以迭代到子节点中去。
3.2. 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
package com.loserzhao.jomin.designpattern.composite; import java.util.HashMap; import java.util.Map; /** * Created * Date: 2021/07/12 16:05 <br/> * Description: 组合模式 * * @author jomin@loserzhao.com * @see */ public class CompositePatternDemo { public static void main(String[] args) { Map<String, Menu> menus = new HashMap<String, Menu>(); initMenus(menus); for(Map.Entry<String, Menu> menu : menus.entrySet()){ menu.getValue().display(""); } System.out.println("--------------------------------------"); System.out.println("删除《菜单管理》"); System.out.println("--------------------------------------"); // 删除《菜单管理》 menus.get("系统管理").getMenus().remove("菜单管理"); for(Map.Entry<String, Menu> menu : menus.entrySet()){ menu.getValue().display(""); } } /** * Author: jomin@loserzhao.com <br/> * Date: 16:36 2021-07-12 <br/> * Description: 初始化菜单 * @param menus */ private static void initMenus(Map<String, Menu> menus) { Menu systemMenu = new Menu("系统管理"); Menu userManagerMenu = new Menu("用户管理"); Menu permissionManagerMenu = new Menu("权限管理"); Menu menuManagerMenu = new Menu("菜单管理"); Menu menuPermissionManagerMenu = new Menu("菜单权限管理"); Menu dataGovernmentMenu = new Menu("数据治理"); Menu dataManagerMenu = new Menu("数据管理"); Menu dataQualityManagerMenu = new Menu("数据质量管控"); menus.put(systemMenu.getName(), systemMenu); menus.put(dataGovernmentMenu.getName(), dataGovernmentMenu); systemMenu.addChildrenMenu(userManagerMenu); systemMenu.addChildrenMenu(permissionManagerMenu); menuManagerMenu.addChildrenMenu(menuPermissionManagerMenu); systemMenu.addChildrenMenu(menuManagerMenu); dataGovernmentMenu.addChildrenMenu(dataManagerMenu); dataGovernmentMenu.addChildrenMenu(dataQualityManagerMenu); // 测试叶子节点不能增加子节点,让《数据质量管控》成为叶子节点 dataQualityManagerMenu.setLeaf(true); Menu dataQualitySourceManagerMenu = new Menu("数据源质量管理"); dataQualityManagerMenu.addChildrenMenu(dataQualitySourceManagerMenu); } public static class Menu { private String name; Map<String, Menu> menus = new HashMap<String, Menu>(); private boolean leaf = false; Menu(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, Menu> getMenus() { return menus; } public void addChildrenMenu(Menu menu) { if (leaf) { System.out.println("ERROR, leaf node don`t support add children menu"); } else { menus.put(menu.getName(), menu); } } public boolean isLeaf() { return leaf; } public void setLeaf(boolean leaf) { this.leaf = leaf; } public void remove() { for(Map.Entry<String, Menu> menu : menus.entrySet()){ if (menu.getValue().menus.size() > 0) { menu.getValue().remove(); } } } public void display(String prefixStr) { System.out.println(prefixStr + this.name); if (menus.size() > 0) { for(Map.Entry<String, Menu> menu : menus.entrySet()){ menu.getValue().display(prefixStr + "--"); } } } } } |
3.3. 运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
ERROR, leaf node don`t support add children menu 系统管理 --用户管理 --权限管理 --菜单管理 ----菜单权限管理 数据治理 --数据管理 --数据质量管控 -------------------------------------- 删除《菜单管理》 -------------------------------------- 系统管理 --用户管理 --权限管理 数据治理 --数据管理 --数据质量管控 |
原创文章,转载请注明: 转载自LoserZhao – 诗和远方[ http://www.loserzhao.com/ ]
本文链接地址: http://www.loserzhao.com/java/designpattern/composite-designpattern.html
文章的脚注信息由WordPress的wp-posturl插件自动生成
0 条评论。