组合模式 / 部分整体模式
基本介绍
1.组合模式,又称部分整体模式
2.创建了对象组的树形结构,将对象组合成树状结构来表示“整体 - 部分”的层次关系
3.组合模式使得用户对单个对象和组合对象的访问具有一致性,即:让客户以一致的方式处理个别对象以及组合对象
角色
1.Component:抽象构件,是 Leaf 与 Composite 共同继承的类或者是共同实现的接口,包含所有子类共有属性,声明、实现所有子类共有方法,以抛出不支持操作的异常对象的方式处理管理子节点的方法
2.Leaf:叶子构件,表示叶子节点,没有子节点,定义组合内元素的行为
3.Composite:容器构件,表示容器节点,包含子节点(容器节点或叶子节点),其提供一个集合来对子节点进行维护,以迭代的方式对子节点进行处理,可能不具有叶子节点的某些行为
JDK 中的 HashMap
1.Map 接口中的 put 方法为抽象方法,类似组织模式的管理子节点的方法
2.AbstractMap
(1)是 Map 接口中的抽象类,类似于组合模式的 Component
(1)其中重写 put 方法时,默认实现,抛出不支持操作的异常对象
3.HashMap
(1)是 AbstractMap 的子类,类似于组合模式的 Composite
(2)真正实现 put 方法,以维护 Leaf
4.Node
(1)HashMap 的静态内部类,类似于组合模式的 Leaf
(2)没有 put 方法
事项
1.优点
(1)简化客户端操作:客户端只需要面对一致的对象而不用考虑容器构件或叶子构件的问题
(2)具有较强的扩展性:当要更改组合对象时,只需要调整内部的层次关系,客户端不用做出任何改动
(3)方便创建复杂的层次结构:客户端无需知道组成细节,即可添加容器构件或叶子构件从而创建出复杂的树形结构
2.缺点
(1)要求较高的抽象性, 节点和叶子存在较大差异性,如较多方法和属性不一样,不适合创建组织模式
(2)其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
3.应用场景
(1)需要遍历组织结构,或者处理的对象具有树形结构
(2)如树形菜单,文件、文件夹的管理
代码示例
import java.util.ArrayList;
import java.util.List;
public class Composite {//客户端
public static void main(String[] args) {
Organization universityA = new University("A大学");
Organization collegeB = new College("B系");
Organization collegeC = new College("C系");
Department departmentD = new Department("D专业");
Department departmentE = new Department("E专业");
Department departmentF = new Department("F专业");
Department departmentG = new Department("G专业");
universityA.add(collegeB);
universityA.add(collegeB);
collegeB.add(departmentD);
collegeB.add(departmentE);
collegeC.add(departmentF);
collegeC.add(departmentG);
System.out.println("A大学的组织结构");
universityA.print();
System.out.println("B系的组织结构");
collegeB.print();
System.out.println("C系的组织结构");
collegeC.print();
}
}
abstract class Organization {
public String name;
public Organization(String name) {
this.name = name;
}
public void add(Organization organization) {
throw new UnsupportedOperationException();//默认实现,抛出不支持操作的异常对象
}
public abstract void print();
}
class University extends Organization {//容器节点
List<Organization> colleges = new ArrayList<>();//存放容器节点:College类型
public University(String name) {
super(name);
}
@Override
public void add(Organization organization) {
colleges.add(organization);
}
@Override
public void print() {
System.out.println(name);
for (Organization college : colleges) {
college.print();
}
}
}
class College extends Organization {//容器节点
List<Organization> departments = new ArrayList<>();//存放容器节点:Department类型
public College(String name) {
super(name);
}
@Override
public void add(Organization organization) {
departments.add(organization);
}
@Override
public void print() {
System.out.println(name);
for (Organization department : departments) {
department.print();
}
}
}
class Department extends Organization {//叶子节点
public Department(String name) {
super(name);
}
@Override
public void print() {
System.out.println(name);
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战