组合模式
业务场景:
传统的解决方案:(使用继承的方式)
传统方案解决学校院系展示问题分析
1)将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的
2)实际上我们的要求是 :在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系, 因此这种方案,不能很好实现的管理的操作,比如 对学院、系的添加,删除,遍历等
3)解决方案:把学校、院、系都看做是组织结构,他们之间没有继承的关系,而是 一个树形结构,可以更好的实现管理操作。 => 组合模式
组合模式基本介绍
基本介绍
1) 组合模式(CompositePattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以 表示“整体-部分”的层次关系。
2) 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
3) 这种类型的设计模式属于结构型模式。
4) 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象
组合模式原理图:
对原理结构图的说明-即(组合模式的角色及职责)
- component:这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理component子部件,component可以是抽象类或者接口。
- Leaf:在组合中表示叶子节点,叶子节点没有子节点。
- Composite:非叶子节点,用哦关于存储子部件,在component接口中实现子部件的相关操作,比如增加、删除等。
代码:
component部分
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 | package com.composite; public abstract class OrganizationComponent { private String name; //名字 private String des; //说明 //构造器 public OrganizationComponent(String name, String des) { this .name = name; this .des = des; } protected void add(OrganizationComponent organizationComponent){ //添加默认实现 throw new UnsupportedOperationException(); } protected void remove(OrganizationComponent organizationComponent){ //添加默认实现 throw new UnsupportedOperationException(); } //打印方法,做成抽象的,因为子类都需要实现 protected abstract void print(); public String getName() { return name; } public void setName(String name) { this .name = name; } public String getDes() { return des; } public void setDes(String des) { this .des = des; } } |
composite部分:
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 | package com.composite; import java.util.ArrayList; import java.util.List; /** * 大学 */ public class University extends OrganizationComponent { //list 中存放的是 college List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>(); //构造器 public University(String name, String des) { super (name, des); } //重写add @Override protected void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } //重写remove @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } //重写getName @Override public String getName() { return super .getName(); } //重写getDes @Override public String getDes() { return super .getDes(); } //重写print @Override protected void print() { System.out.println( "-----------" +getName()+ "------------" ); //遍历organizationComponents for (OrganizationComponent organizationComponent : organizationComponents) { organizationComponent.print(); } } } |
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 | package com.composite; import java.util.ArrayList; import java.util.List; public class College extends OrganizationComponent { //list 中存放的是 department List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>(); //构造器 public College(String name, String des) { super (name, des); } //重写add @Override protected void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } //重写remove @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } //重写getName @Override public String getName() { return super .getName(); } //重写getDes @Override public String getDes() { return super .getDes(); } //重写print @Override protected void print() { System.out.println( "-----------" +getName()+ "------------" ); //遍历organizationComponents for (OrganizationComponent organizationComponent : organizationComponents) { organizationComponent.print(); } } } |
leaf部分:
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 | package com.composite; import java.util.ArrayList; import java.util.List; /** * 专业 */ public class Department extends OrganizationComponent { //构造器 public Department(String name, String des) { super (name, des); } //add remove 方法就不用写了,因为他是叶子节点,下面不包含任何东西了 //重写getName @Override public String getName() { return super .getName(); } //重写getDes @Override public String getDes() { return super .getDes(); } //重写print @Override protected void print() { System.out.println(getName()); } } |
client部分:
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 | package com.composite; public class Client { public static void main(String[] args) { //从大到小创建对象 学校 OrganizationComponent university = new University( "清华大学" , "是中国顶尖大学" ); //创建学院 OrganizationComponent computerCollege = new College( "计算机学院" , "计算机学院" ); OrganizationComponent infoEngineerCollege= new College( "信息工程学院" , "信息工程学院" ); //创建各个学院下面的系(专业) computerCollege.add( new Department( "软件工程" , "软件工程不赖" )); computerCollege.add( new Department( "网络工程" , "网络工程不赖" )); computerCollege.add( new Department( "计算机科学与技术工程" , "计算机科学与技术工程不赖" )); infoEngineerCollege.add( new Department( "通信工程" , "通信工程不赖" )); infoEngineerCollege.add( new Department( "信息工程" , "信息工程不赖" )); //将两个学员加入到学校中 university.add(computerCollege); university.add(infoEngineerCollege); university.print(); //或者,我们只想打印计算机学院的信息 //computerCollege.print(); } } |
运行结果:
1 2 3 4 5 6 7 8 | -----------清华大学------------ -----------计算机学院------------ 软件工程 网络工程 计算机科学与技术工程 -----------信息工程学院------------ 通信工程 信息工程 |
组合模式在 JDK 集合的源码分析
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 | package com.composite; import java.util.HashMap; import java.util.Map; /** * 组合模式在 JDK 集合的源码分析 * 1) Java 的集合类-HashMap 就使用了组合模式 * * 2) 代码分析+Debug 源码 * * */ public class Composite { public static void main(String[] args) { /** * 1.Map 就是一个抽象的构造(类似我们的Component) * 2.HashMap 是一个中间的构建(Composite),实现了相关方法 put putAll * 3.Node 是HashMap的静态内部类,类似leaf叶子节点,这里没有put putAll 等方法 */ Map<Integer, String> hashMap = new HashMap<>(); hashMap.put( 0 , "东游记" ); Map<Integer, String> map = new HashMap<>(); map.put( 1 , "西游记" ); map.put( 2 , "红楼梦" ); hashMap.putAll(map); System.out.println(hashMap); } } |
运行结果:{0=东游记, 1=西游记, 2=红楼梦}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY