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

漂亮的网站单页织梦网站描述

漂亮的网站单页,织梦网站描述,苏州注册公司网上核名,网站系统 外贸【设计模式08】组合模式 一、从业务痛点谈起 还记得我们第一次接手企业组织架构管理系统时的困境吗?一个看似简单的需求:“统计某个部门及其所有下级部门的总人数”,却让团队陷入了代码泥潭。 最初的实现是这样的:先查询一级部门&…

【设计模式08】组合模式

一、从业务痛点谈起

还记得我们第一次接手企业组织架构管理系统时的困境吗?一个看似简单的需求:“统计某个部门及其所有下级部门的总人数”,却让团队陷入了代码泥潭。

最初的实现是这样的:先查询一级部门,再循环查询二级部门,接着是三级、四级…代码中充斥着嵌套的if-else和for循环。更糟糕的是,当组织架构层级发生变化时,代码就得重写。某大型集团的组织架构甚至达到了8层,维护这样的代码简直是噩梦。

这时候,我们需要一种设计模式,能够统一处理单个对象和组合对象,让客户端无需关心处理的是叶子节点还是组合节点——这就是组合模式的价值所在。

二、组合模式的核心思想

2.1 定义与本质

组合模式(Composite Pattern):将对象组合成树形结构以表示"部分-整体"的层次结构,使客户端对单个对象和组合对象的使用具有一致性。

打个生活化的比方:组合模式就像俄罗斯套娃,每个套娃既可以是独立的个体,也可以包含其他套娃。无论是操作单个套娃还是一整套,方式都是一样的。

2.2 核心结构解析

contains
«abstract»
Component
+String name
+add(Component c)
+remove(Component c)
+display(int depth)
+calculateCount()
Leaf
+add(Component c)
+remove(Component c)
+display(int depth)
+calculateCount()
Composite
-List<Component> children
+add(Component c)
+remove(Component c)
+display(int depth)
+calculateCount()

组合模式的三个核心角色:

  • Component(抽象组件):定义叶子和容器的共同接口
  • Leaf(叶子组件):树形结构的叶子节点,没有子节点
  • Composite(容器组件):可以包含子节点的容器对象

2.3 适用场景分析

场景特征具体描述典型案例
树形结构数据本身具有层次关系组织架构、文件系统、菜单管理
统一处理希望统一处理个体和组合图形编辑器、UI组件树
递归操作需要递归遍历整个结构权限管理、规则引擎
动态扩展结构层级可能动态变化商品分类、地区管理

三、实现思路与关键代码

3.1 核心逻辑实现

让我们通过企业组织架构的例子,展示组合模式的几种实现方式:

方式一:透明式组合模式(推荐)

// 抽象组件:定义所有组件的公共接口
public abstract class OrganizationComponent {protected String name;protected String description;public OrganizationComponent(String name, String description) {this.name = name;this.description = description;}// 默认实现,叶子节点会抛出异常public void add(OrganizationComponent component) {throw new UnsupportedOperationException("不支持添加操作");}public void remove(OrganizationComponent component) {throw new UnsupportedOperationException("不支持删除操作");}// 抽象方法,强制子类实现public abstract void display(int depth);public abstract int calculateEmployeeCount();
}// 叶子节点:员工
public class Employee extends OrganizationComponent {private String position;public Employee(String name, String position) {super(name, position);this.position = position;}@Overridepublic void display(int depth) {// 打印缩进,体现层级关系System.out.println("-".repeat(depth) + " 员工:" + name + ",职位:" + position);}@Overridepublic int calculateEmployeeCount() {return 1; // 员工算1个人}
}// 容器节点:部门
public class Department extends OrganizationComponent {// 存储子组件private List<OrganizationComponent> components = new ArrayList<>();public Department(String name, String description) {super(name, description);}@Overridepublic void add(OrganizationComponent component) {components.add(component);}@Overridepublic void remove(OrganizationComponent component) {components.remove(component);}@Overridepublic void display(int depth) {System.out.println("-".repeat(depth) + " 部门:" + name);// 递归显示所有子组件for (OrganizationComponent component : components) {component.display(depth + 2);}}@Overridepublic int calculateEmployeeCount() {int count = 0;// 递归计算所有子组件的人数for (OrganizationComponent component : components) {count += component.calculateEmployeeCount();}return count;}
}

方式二:安全式组合模式

// 抽象组件:只定义公共方法
public abstract class OrganizationUnit {protected String name;public OrganizationUnit(String name) {this.name = name;}// 只定义所有组件都有的方法public abstract void display(int depth);public abstract int getStaffCount();
}// 容器接口:定义容器特有的方法
public interface IContainer {void add(OrganizationUnit unit);void remove(OrganizationUnit unit);List<OrganizationUnit> getChildren();
}// 部门实现
public class DepartmentSafe extends OrganizationUnit implements IContainer {private List<OrganizationUnit> children = new ArrayList<>();@Overridepublic void add(OrganizationUnit unit) {children.add(unit);}@Overridepublic void remove(OrganizationUnit unit) {children.remove(unit);}@Overridepublic List<OrganizationUnit> getChildren() {return children;}@Overridepublic void display(int depth) {System.out.println("-".repeat(depth) + " 部门:" + name);for (OrganizationUnit child : children) {child.display(depth + 2);}}@Overridepublic int getStaffCount() {return children.stream().mapToInt(OrganizationUnit::getStaffCount).sum();}
}// 员工实现
public class EmployeeSafe extends OrganizationUnit {@Overridepublic void display(int depth) {System.out.println("-".repeat(depth) + " 员工:" + name);}@Overridepublic int getStaffCount() {return 1;}
}

方式三:带缓存优化的组合模式

public class CachedDepartment extends OrganizationComponent {private List<OrganizationComponent> components = new ArrayList<>();private Integer cachedEmployeeCount; // 缓存员工数量private boolean isDirty = true; // 标记缓存是否失效@Overridepublic void add(OrganizationComponent component) {components.add(component);isDirty = true; // 添加后缓存失效}@Overridepublic void remove(OrganizationComponent component) {components.remove(component);isDirty = true; // 删除后缓存失效}@Overridepublic int calculateEmployeeCount() {if (isDirty || cachedEmployeeCount == null) {// 重新计算并缓存cachedEmployeeCount = components.stream().mapToInt(OrganizationComponent::calculateEmployeeCount).sum();isDirty = false;}return cachedEmployeeCount;}
}

3.2 不同实现方式对比

实现方式优点缺点适用场景
透明式客户端调用简单统一叶子节点包含无意义方法结构相对稳定,强调使用便利性
安全式接口定义清晰,类型安全客户端需要区分类型注重类型安全,结构复杂多变
带缓存性能优化,避免重复计算实现复杂,需要维护缓存一致性大规模数据,频繁查询场景

四、企业级应用案例

4.1 案例一:美团组织架构权限管理系统

背景与问题:
美团的组织架构极其复杂,包含总部、城市分公司、业务线、部门等多个层级。权限管理需求:

  • 上级部门自动拥有下级部门的所有权限
  • 支持按部门批量授权
  • 能够快速查询某员工的所有权限(包括继承的)

模式应用方案:

public class PermissionComponent {// 权限树节点public abstract class PermissionNode {protected String nodeId;protected Set<String> directPermissions = new HashSet<>();// 获取所有权限(包括继承的)public abstract Set<String> getAllPermissions();// 检查是否有某权限public boolean hasPermission(String permission) {return getAllPermissions().contains(permission);}}// 部门节点public class DepartmentNode extends PermissionNode {private List<PermissionNode> children = new ArrayList<>();private Department department;@Overridepublic Set<String> getAllPermissions() {Set<String> allPermissions = new HashSet<>(directPermissions);// 递归收集所有子部门的权限for (PermissionNode child : children) {allPermissions.addAll(child.getAllPermissions());}return allPermissions;}// 批量授权public void grantPermissionToAll(String permission) {this.directPermissions.add(permission);// 自动传播到所有子节点for (PermissionNode child : children) {if (child instanceof DepartmentNode) {((DepartmentNode) child).grantPermissionToAll(permission);}}}}// 员工节点public class EmployeeNode extends PermissionNode {private Employee employee;private DepartmentNode department; // 所属部门@Overridepublic Set<String> getAllPermissions() {Set<String> allPermissions = new HashSet<>(directPermissions);// 继承部门权限if (department != null) {allPermissions.addAll(department.getAllPermissions());}return allPermissions;}}
}

实施效果:

  • 权限继承关系清晰,维护成本降低60%
  • 批量授权效率提升10倍
  • 支持灵活的组织架构调整,代码零修改

4.2 案例二:京东商品分类体系

背景与问题:
京东的商品分类体系包含数万个类目,层级深度不一(3-7层)。需求包括:

  • 统计某分类下的所有商品数量
  • 批量调整分类下所有商品的属性
  • 生成分类面包屑导航

模式应用方案:

public abstract class CategoryComponent {protected Long categoryId;protected String categoryName;protected Integer level;// 生成面包屑public abstract String generateBreadcrumb();// 统计商品数量public abstract int countProducts();// 批量操作public abstract void batchUpdate(Map<String, Object> attributes);
}public class Category extends CategoryComponent {private List<CategoryComponent> subCategories = new ArrayList<>();private CategoryComponent parent;@Overridepublic String generateBreadcrumb() {if (parent == null) {return categoryName;}return parent.generateBreadcrumb() + " > " + categoryName;}@Overridepublic int countProducts() {// 使用并行流提升性能return subCategories.parallelStream().mapToInt(CategoryComponent::countProducts).sum();}@Overridepublic void batchUpdate(Map<String, Object> attributes) {// 异步批量更新CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {updateSelf(attributes);// 递归更新子分类List<CompletableFuture<Void>> futures = subCategories.stream().map(sub -> CompletableFuture.runAsync(() -> sub.batchUpdate(attributes))).collect(Collectors.toList());CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();});}
}

五、模式深度剖析

5.1 优势与局限

优势:

  • 简化客户端代码:客户端无需关心处理的是单个对象还是组合对象
  • 扩展性强:易于增加新的节点类型
  • 符合开闭原则:对扩展开放,对修改关闭
  • 递归处理自然:天然支持递归操作

局限:

  • 设计复杂度:可能使设计变得过于一般化
  • 类型安全问题:透明式组合中,叶子节点包含无意义的方法
  • 性能考虑:深层递归可能导致栈溢出
  • 难以限制组件类型:难以限制容器中的组件类型

5.2 线程安全考量

public class ThreadSafeDepartment extends OrganizationComponent {// 使用线程安全的集合private final CopyOnWriteArrayList<OrganizationComponent> components = new CopyOnWriteArrayList<>();// 使用读写锁优化性能private final ReadWriteLock lock = new ReentrantReadWriteLock();@Overridepublic void add(OrganizationComponent component) {lock.writeLock().lock();try {components.add(component);} finally {lock.writeLock().unlock();}}@Overridepublic int calculateEmployeeCount() {lock.readLock().lock();try {return components.stream().mapToInt(OrganizationComponent::calculateEmployeeCount).sum();} finally {lock.readLock().unlock();}}
}

5.3 性能影响分析

操作类型时间复杂度优化策略
遍历O(n)使用并行流、分页加载
查找特定节点O(n)建立索引Map、使用缓存
添加/删除O(1)使用高效数据结构
统计计算O(n)缓存计算结果、增量更新

六、框架中的应用

6.1 Spring中的组合模式

Spring中多处使用了组合模式:

// Spring的CompositeMessageSource
public class CompositeMessageSource implements MessageSource {private final List<MessageSource> messageSources = new ArrayList<>();public void addMessageSource(MessageSource messageSource) {this.messageSources.add(messageSource);}@Overridepublic String getMessage(String code, Object[] args, Locale locale) {for (MessageSource messageSource : messageSources) {try {return messageSource.getMessage(code, args, locale);} catch (NoSuchMessageException ex) {// 继续尝试下一个MessageSource}}throw new NoSuchMessageException(code, locale);}
}// Spring Security的投票机制
public class AffirmativeBased extends AbstractAccessDecisionManager {public void decide(Authentication authentication, Object object,Collection<ConfigAttribute> configAttributes) {// 遍历所有投票器(组合模式)for (AccessDecisionVoter voter : getDecisionVoters()) {int result = voter.vote(authentication, object, configAttributes);if (result == AccessDecisionVoter.ACCESS_GRANTED) {return; // 只要有一个同意就通过}}}
}

6.2 MyBatis中的应用

// MyBatis的SqlNode体系
public interface SqlNode {boolean apply(DynamicContext context);
}public class MixedSqlNode implements SqlNode {private final List<SqlNode> contents;@Overridepublic boolean apply(DynamicContext context) {// 组合多个SqlNodecontents.forEach(node -> node.apply(context));return true;}
}

七、与相似模式的辨析

7.1 组合模式 vs 装饰器模式

对比维度组合模式装饰器模式
设计目的表示"部分-整体"层次动态添加职责
结构关系树形结构链式结构
对象数量可包含多个子对象一般包装一个对象
使用重点统一处理个体和组合透明地扩展功能

7.2 组合模式 vs 迭代器模式

组合模式经常与迭代器模式配合使用:

public class DepartmentWithIterator extends Department implements Iterable<OrganizationComponent> {@Overridepublic Iterator<OrganizationComponent> iterator() {return new DepartmentIterator();}private class DepartmentIterator implements Iterator<OrganizationComponent> {private Stack<Iterator<OrganizationComponent>> stack = new Stack<>();public DepartmentIterator() {stack.push(components.iterator());}@Overridepublic boolean hasNext() {if (stack.empty()) return false;Iterator<OrganizationComponent> iterator = stack.peek();if (!iterator.hasNext()) {stack.pop();return hasNext();}return true;}@Overridepublic OrganizationComponent next() {if (hasNext()) {Iterator<OrganizationComponent> iterator = stack.peek();OrganizationComponent component = iterator.next();if (component instanceof Department) {stack.push(((Department) component).components.iterator());}return component;}return null;}}
}

八、实践启示

通过对组合模式的深入剖析和实战应用,我们得到以下核心启示:

  • 递归思维的力量:组合模式将递归思维优雅地融入面向对象设计中,让我们能够用统一的方式处理复杂的树形结构。这启发我们在面对层次性数据时,要善于发现和利用递归特性。

  • 接口统一的价值:通过统一叶子节点和容器节点的接口,组合模式极大地简化了客户端代码。这提醒我们,良好的抽象能够隐藏复杂性,提供简洁的使用体验。

  • 性能与设计的权衡:在实际应用中,我们需要在设计的优雅性和性能之间找到平衡点。缓存机制、并行处理、懒加载等优化手段都是必要的补充。

  • 安全性不应被忽视:选择透明式还是安全式组合,取决于我们对类型安全的重视程度。在关键业务系统中,类型安全往往比使用便利性更重要。

  • 模式组合的威力:组合模式与访问者模式、迭代器模式、责任链模式等配合使用,能够构建出功能强大且灵活的系统架构。

记住,组合模式不仅仅是一种设计模式,更是一种思维方式——当我们面对"整体与部分"的关系时,要思考如何让它们和谐共存,统一处理

http://www.dtcms.com/a/543665.html

相关文章:

  • 如何查看网站做没做竞价莆田做网站的公司
  • 郑州区块链数字钱包网站开发公司档案馆网站机房建设
  • 沈阳网站设计定制wordpress 钩子列表
  • 网站备案安全吗石家庄网络推广
  • 网站的转化率电影免费在线观看
  • php网站做多久关键词筛选
  • 可以做微信推送的网站临淄区住房和城乡建设局网站
  • 网站建设销售工作怎么样wordpress模班之家
  • 一个网站应该怎么做有经验的中山网站建设
  • 泰兴市住房和建设局网站自动写作文网站
  • 做go kegg的在线网站it人力外包服务公司
  • 帝国cms网站搬家怎么判断网站开发语言
  • 网站建设的相关新闻南昌seo快速排名
  • 怎么把网站建设推广出去中国建筑网官网企业文化
  • godaddy做网站深圳微信公众平台
  • 如何做好网站关键词布局免费搭建个人网页
  • 学习制作网页的网站网站做图分辨率是多少
  • 如何做网站怎么赚钱免费网站空间和域名
  • 自己能自学网站建设吗网络服务提供者发现未成年秘密信息应采取
  • 陕西做网站公司哪家好建网站需求
  • jsp网站搭建电商设计师岗位职责
  • 网站模板设计教程360排名检测
  • 银川网站制作报价网页制作教程步骤视频讲解
  • 做公司网站注意事项沈阳创新网站建设报价
  • 专业网站设计都选亿企邦用电脑做网站服务器
  • 网站建设的讲话要求wordpress工具箱主题
  • 订餐网站的数据库建设甘肃省住房建设厅网站证书查询
  • 快站优惠券去哪里找如何苗木网站建设
  • 那些网站是php开发的wordpress 审核
  • 网站设计深圳联系电话?在线设计房屋布局软件