当前位置: 首页 > wzjs >正文

长沙优化网站技术厂家360浏览器建设银行网站

长沙优化网站技术厂家,360浏览器建设银行网站,装修平台网站排名,中国楼市最新消息2022组合模式实战:用树形结构管理企业组织与文件系统 一、模式核心:让 “部分 - 整体” 操作统一化 在企业 OA 系统中,组织架构呈现典型的树形结构:公司由多个部门组成,部门下有子部门和员工。传统方式需要为 “单个员工…

组合模式实战:用树形结构管理企业组织与文件系统

一、模式核心:让 “部分 - 整体” 操作统一化

在企业 OA 系统中,组织架构呈现典型的树形结构:公司由多个部门组成,部门下有子部门和员工。传统方式需要为 “单个员工” 和 “部门团队” 设计不同的操作接口,导致代码冗余。组合模式(Composite Pattern) 通过将对象组织成树形结构,使客户端对单个对象(叶子节点)和组合对象(容器节点)的操作具有一致性,核心解决:

  • 层次化管理:统一处理 “部分” 与 “整体” 的关系(如员工与部门)
  • 透明化操作:客户端无需区分叶子节点和容器节点,直接调用统一接口

核心思想与 UML 类图

组合模式通过定义统一的组件接口,让叶子节点和容器节点实现相同的方法,形成递归组合结构:

img

二、两种实现模式:透明组合 vs 安全组合

1. 透明组合模式(通用接口)

  • 设计原则:在基接口中声明所有组合操作(如add/remove),叶子节点直接抛出不支持异常
  • 优点:客户端无需区分节点类型,操作统一
  • 缺点:叶子节点可能包含无用方法(违反单一职责)

代码实现(组织架构案例)

// 统一组件接口(透明模式)
public interface OrgComponent {void add(OrgComponent component);void remove(OrgComponent component);void print(); // 打印组织架构
}// 叶子节点(员工)
public class Employee implements OrgComponent {private String name;public Employee(String name) {this.name = name;}// 叶子节点不支持添加/删除,直接抛出异常public void add(OrgComponent c) {throw new UnsupportedOperationException("员工不能添加子节点");}public void remove(OrgComponent c) {throw new UnsupportedOperationException("员工不能删除子节点");}public void print() {System.out.println("├─员工:" + name);}
}// 组合节点(部门)
public class Department implements OrgComponent {private String name;private List<OrgComponent> children = new ArrayList<>();public Department(String name) {this.name = name;}public void add(OrgComponent c) {children.add(c);}public void remove(OrgComponent c) {children.remove(c);}public void print() {System.out.println("│─部门:" + name);children.forEach(OrgComponent::print); // 递归打印子节点}
}

2. 安全组合模式(分离接口)

  • 设计原则:将组合操作(如add/remove)放到容器节点接口中,叶子节点不暴露这些方法
  • 优点:避免叶子节点包含无效方法
  • 缺点:客户端需区分节点类型(通过类型判断或接口转换)

适用场景对比

维度透明组合模式安全组合模式
接口统一性强(所有节点实现同一接口)弱(需区分叶子 / 容器接口)
职责清晰性弱(叶子节点包含无用方法)强(方法仅出现在合理节点中)
客户端复杂度低(无需类型判断)高(需处理类型转换)

三、实战:构建可扩展的权限管理系统

1. 需求分析

  • 系统包含角色(叶子节点,如 “普通用户”“管理员”)和角色组(容器节点,如 “销售团队”“开发团队”)
  • 需要统一管理节点的权限分配,支持递归遍历子节点

2. 核心实现(透明组合模式)

// 权限组件接口
public interface PermissionComponent {void add(PermissionComponent component);void remove(PermissionComponent component);void grantPermission(String permission); // 授予权限List<String> getPermissions(); // 获取所有权限
}// 叶子节点:具体角色
public class Role implements PermissionComponent {private String roleName;private List<String> permissions = new ArrayList<>();public Role(String roleName) {this.roleName = roleName;}// 角色不能添加子节点public void add(PermissionComponent c) {throw new UnsupportedOperationException();}public void remove(PermissionComponent c) {throw new UnsupportedOperationException();}public void grantPermission(String permission) {permissions.add(permission);}public List<String> getPermissions() {return permissions;}
}// 组合节点:角色组
public class RoleGroup implements PermissionComponent {private String groupName;private List<PermissionComponent> members = new ArrayList<>();public RoleGroup(String groupName) {this.groupName = groupName;}public void add(PermissionComponent c) {members.add(c);}public void remove(PermissionComponent c) {members.remove(c);}public void grantPermission(String permission) {members.forEach(c -> c.grantPermission(permission)); // 递归授权}public List<String> getPermissions() {return members.stream().flatMap(c -> c.getPermissions().stream()).distinct() // 去重处理.collect(Collectors.toList());}
}

3. 客户端调用示例

public class ClientDemo {public static void main(String[] args) {// 创建叶子节点:普通用户、管理员Role user = new Role("普通用户");Role admin = new Role("管理员");// 创建组合节点:开发组、测试组RoleGroup devGroup = new RoleGroup("开发团队");devGroup.add(user); devGroup.add(admin); // 添加成员// 给组合节点授权,递归影响所有子节点devGroup.grantPermission("CODE_READ");devGroup.grantPermission("CODE_COMMIT");// 输出管理员权限(包含直接授权和继承权限)System.out.println("管理员权限:" + admin.getPermissions()); // 输出:[CODE_READ, CODE_COMMIT]}
}

四、框架与源码中的组合模式应用

1. Java Swing 组件树

  • JComponent作为基接口,JPanel(容器)和JButton(叶子)实现统一接口
  • 递归遍历组件树:
public static void traverseComponent(Component c, int depth) {System.out.println(" ".repeat(depth) + c.getClass().getSimpleName());if (c instanceof Container) {((Container) c).getComponents().forEach(child -> traverseComponent(child, depth + 1));}
}

2. Apache Dubbo 服务治理

  • 服务分组(Group)作为组合节点,包含多个服务提供者(Provider,叶子节点)
  • 路由规则支持对组合节点统一配置,如负载均衡策略、熔断规则

3. 文件系统实现

File类在 Java 中是典型组合模式:

  • 目录(组合节点)可包含子文件 / 目录
  • 普通文件(叶子节点)无下属节点
  • 统一通过listFiles()方法遍历,无需区分节点类型

五、避坑指南:正确使用组合模式的 3 个要点

1. 合理选择模式类型

  • 透明模式:适合简单场景,优先保证客户端操作统一(如组织架构展示)
  • 安全模式:适合复杂场景,避免叶子节点暴露无效方法(如权限管理系统)

2. 处理递归终止条件

  • 叶子节点必须明确拒绝组合操作(如抛出UnsupportedOperationException
  • 避免空节点导致的递归死循环(初始化时检查子节点列表非空)

3. 控制组合层次深度

  • 过深的树形结构可能导致栈溢出(改用迭代遍历替代递归)
// 迭代方式遍历组件树(避免栈溢出)
public static void iterateComponent(Component root) {Deque<Component> stack = new ArrayDeque<>();stack.push(root);while (!stack.isEmpty()) {Component c = stack.pop();System.out.println(c.getClass().getSimpleName());if (c instanceof Container) {Arrays.stream(((Container) c).getComponents()).forEach(stack::push); // 反向入栈保证顺序}}
}

4. 反模式:滥用组合模式

  • 当树形结构层级极少(如只有两层)时,组合模式可能增加代码复杂度
  • 避免为无 “部分 - 整体” 关系的对象强行构建树形结构(优先使用聚合关系)

六、总结:何时该用组合模式?

适用场景核心特征典型案例
对象具有层次化结构存在 “整体 - 部分” 关系,如组织架构、文件系统企业权限管理、GUI 组件树
需要统一操作单个 / 组合对象客户端希望用相同接口处理叶子和容器节点批量操作、递归遍历功能
支持动态组合与层次变化节点可以动态添加、删除子节点动态菜单构建、流程引擎设计

组合模式通过 “统一接口 + 递归组合” 的设计,将树形结构的复杂性封装在组件内部,使客户端能够以一致的方式处理简单元素和复杂组合。下一篇我们将深入探讨代理模式,解析从静态代理到动态代理的 AOP 实现原理,敬请期待!

扩展思考:组合模式 vs 装饰模式

两者都涉及对象的层次结构,但核心目标不同:

模式目的结构特点典型应用
组合模式处理 “部分 - 整体” 关系树形结构,叶子 / 容器节点目录结构、组织架构
装饰模式动态添加对象功能链式结构,装饰器与被装饰对象实现相同接口日志增强、权限校验

理解这些模式的差异,有助于在设计时做出更合适的选择。


文章转载自:

http://6pYIBQL7.mznqz.cn
http://dRdOPy2w.mznqz.cn
http://g6qHr3Ag.mznqz.cn
http://dngZUncI.mznqz.cn
http://6XPghTwj.mznqz.cn
http://YCerz0M2.mznqz.cn
http://bfgXewBJ.mznqz.cn
http://mO5lt4MG.mznqz.cn
http://FZuw3mGl.mznqz.cn
http://p8czvQjg.mznqz.cn
http://biRggFd9.mznqz.cn
http://Z0U9Ppxy.mznqz.cn
http://JsbJhZpk.mznqz.cn
http://B0r2rM2v.mznqz.cn
http://alOU2Pz9.mznqz.cn
http://tebjQAS7.mznqz.cn
http://2gBE7JGw.mznqz.cn
http://TBjHiA3a.mznqz.cn
http://v83bUErj.mznqz.cn
http://18urw162.mznqz.cn
http://b3MtMVFP.mznqz.cn
http://CuV2BiB3.mznqz.cn
http://tUGZIfhg.mznqz.cn
http://eyn5iDN2.mznqz.cn
http://FNJGNryh.mznqz.cn
http://jeOdY86q.mznqz.cn
http://gEr43UEw.mznqz.cn
http://hslDIe4G.mznqz.cn
http://1b9Hh0FO.mznqz.cn
http://g5SFu4YC.mznqz.cn
http://www.dtcms.com/wzjs/688153.html

相关文章:

  • 工程建设室内涂料招投标网站做网站 简单外包
  • php网站开发外包营销策划与运营方案
  • 网站源码哪个好网站上的qq咨询怎么做
  • 制作个简单公司网站要多少钱社区建立网站
  • 用什么程序做视频网站如何为自己公司做网站
  • 电子网站建设策划模板asp网站安全吗
  • 中国制造网外贸网站深圳东门属于哪个区
  • 石嘴山网站定制开发建设销售平台排行榜前十名
  • 怎么看网站是不是用凡客做的精品网站建设费用磐石网络
  • 有没有做网站一次付费十堰网站建设价格
  • 网站建设内页六安人论坛百姓杂谈
  • 网站开发记什么费用网站制作哪里做得好
  • 杭州网站设计网页做旅游广告在哪个网站做效果好
  • 西安北郊做网站响应式网站建设案例
  • 绿色的医疗资讯手机网站wap模板html源码下载网站建设中期怎么入账
  • 海宁市住房和城乡规划建设局网站黔江网站制作
  • 什么查网站是否降权西安seo排名优化推广价格
  • 佛山市做网站的公司旅游电子商务网站建设费用
  • 做网站开发用笔记本要什么配置wordpress下载官网
  • 手机微网站怎么制作的网站编辑 seo
  • 用ps做糖果店网站模板唯品会专门做特卖的网站
  • 番禺做网站开发网络编程技术题库
  • 竞价单页 网站深圳市建设管理中心
  • 做电商网站价格WordPress导航类主题主题
  • 网站中的文字滑动怎么做的网站本地环境搭建软件
  • 平凉市建设厅官方网站三星官方网站
  • 郑州专业网站建设价格上海网站制作案例
  • 公司网站建设请示新手怎么做网站内容维护
  • 一个网站空间可以做多少个网站html网页制作兼职平台
  • 网站支付页面源代码长沙网络推广袁飞seo