【结构型模式】组合模式

ops/2024/10/10 15:01:31/

一、组合模式概述

        组合模式的定义与意图将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。(对象结构型)

  • 组合模式分析
    • 1.当容器对象的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行,牵一而动百,其中使用了递归调用的机制来对整个结构进行处理;
    • 2.由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使程序非常复杂。
  • 如何一致地对待容器对象和叶子对象?
    • 组合模式通过一种巧妙地设计方案使得用户可以一致性地处理整个树形结构或者树形结构地一部分,它描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它进行区分,可以一致地对待容器对象和叶子对象。
  • 安全组合模式
    • 1.抽象构件Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法;
    • 2.对于叶子对象,客户端不可能调用到这些方法;
    • 3.缺点是不够透明,客户端不能完全针对抽象编程。必须有区别地对待叶子构件和容器构件。
  • 透明组合模式
    • 1.抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()、以及getChild()等方法;
    • 2.在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象;
    • 3.缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的。
  • 组合模式的优缺点
    • 优点
      • 1.可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构将进行控制;
      • 2.客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码;
      • 3.增加新的容器构件和叶子构件都很方便,符合开闭原则;
      • 4.为树形结构的面向对象实现提供了一种灵活的解决方案。
    • 缺点
      • 在增加新构件时很难对容器中的构件类型进行限制。
  • 适用环境
    • 1.在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待他们;
    • 2.在一个使用面向对象语言开发的系统中需要处理一个树形结构;
    • 3.在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

二、代码实现

        组合模式的结构:

  • Component(抽象构件)
  • Leaf(叶子构件)
  • Composite(容器构件)

        某教育机构组织结构如下图所示:

        在该教育机构的OA系统中可以给各级办公室下发公文,试采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。

        2.1 Component(抽象构件类:AbstractHead)
package composite.OAteacher;
//(1)Component抽象构件类:AbstractHead
public abstract class AbstractHead {public abstract void receiveDocument();
}
        2.2 Leaf(叶子构件:AdminOffice、ProvostOffice)
package composite.OAteacher;
//(2.1)Leaf叶子构件类:AdminOffice
public class AdminOffice extends AbstractHead {	private String officeName;	public AdminOffice(String officeName){this.officeName = officeName;}	public void receiveDocument(){System.out.println(officeName + "收到文件");}
}
package composite.OAteacher;
//(2.2)Leaf叶子构件类:ProvostOffice
public class ProvostOffice extends AbstractHead {private String officeName;	public ProvostOffice(String officeName){this.officeName = officeName;}	public void receiveDocument(){System.out.println(this.officeName + "收到文件...");}	
}
        2.3 Composite(容器构件:Branch,定义构件行为)
package composite.OAteacher;import java.util.*;
//(3)composite:定义组件行为,比如下发文件动作
public class Branch extends AbstractHead {	private String branchName;ArrayList list = new ArrayList();	public Branch(String branchName){this.branchName = branchName;}	public void addSubOrg(AbstractHead elment){list.add(elment);}	public void removeSubOrg(AbstractHead element){list.remove(element);}	public void receiveDocument(){		System.out.println("-----------------------------------------");for(Object object: list){//System.out.println(object.getClass());if(object.getClass().toString().equals("class Branch")){				((Branch)object).issudedDocument();}else((AbstractHead)object).receiveDocument();			}		}public void issudedDocument(){System.out.println(branchName + "下发文件......");this.receiveDocument();}
}
        2.4 main方法实现组合模式
package composite.OAteacher;
//(5)客户端测试类:Client
/** 题目:
某教育机构组织结构如下图所示:
在该教育机构的OA系统中可以给各级办公室下发公文,现采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。*/
public class Client {	public static void main(String args[]){	AbstractHead office11 = new ProvostOffice("长沙教学点教务办公室");AbstractHead office12 = new ProvostOffice("长沙教学点行政办公室");Branch b1 = new Branch("长沙教学点");b1.addSubOrg(office11);b1.addSubOrg(office12);AbstractHead office21 = new ProvostOffice("湘潭教学点教务办公室");AbstractHead office22 = new ProvostOffice("湘潭教学点行政办公室");Branch b2 = new Branch("湘潭教学点");b2.addSubOrg(office21);b2.addSubOrg(office22);AbstractHead office31 = new ProvostOffice("湖南分校教务办公室");AbstractHead office32 = new ProvostOffice("湖南分校行政办公室");Branch b3 = new Branch("湖南分校");b3.addSubOrg(office31);b3.addSubOrg(office32);b3.addSubOrg(b1);b3.addSubOrg(b2);AbstractHead office41 = new ProvostOffice("北京总部教务办公室");AbstractHead office42 = new ProvostOffice("北京总部行政办公室");Branch b4 = new Branch("北京总部");b4.addSubOrg(office41);b4.addSubOrg(office42);b4.addSubOrg(b3);b4.issudedDocument();//b4.receiveDocument();		}
}
        2.5 UML图

三、代码结构图


http://www.ppmy.cn/ops/13646.html

相关文章

SpringBoot基于RabbitMQ实现消息可靠性

文章目录 1. ☃️概述2. ☃️生产者消息确认2.1 ❄️❄️概述2.2 ❄️❄️实战⛷️⛷️⛷️2.2.1 修改配置⛷️⛷️⛷️2.2.2 定义 Return 回调⛷️⛷️⛷️2.2.3 定义ConfirmCallback 3. ☃️消息持久化3.1 ❄️❄️交换机持久化3.2 ❄️❄️队列持久化3.3 ❄️❄️消息持久化…

协议的定制之序列化与反序列化 | 守护进程

目录 一、再谈协议 二、序列化与反序列化 三、网络计算器的简单实现 四、网络计算器完整代码 五、代码改进 六、守护进程 七、Json序列化与反序列化 八、netstat 一、再谈协议 是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述。简单的说了,网络…

解决:第一次用python的pip报错

报错内容如下: Fatal error in launcher: Unable to create process using "C:\Users\admin\AppData\Local\Programs\Python\Python312\python.exe" "C:\Program Files\Python\Python312\Scripts\pip.exe" : ??????????? 参考 如何…

强化训练:day4

文章目录 前言1. 简写单词1.1 题目描述1.2 解题思路1.3 代码实现 2. dd爱框框2.1 题目描述2.2 解题思路2.3 代码实现 3. 除2!3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 今天的题目是:BC149 简写单词、dd爱框框、除2!,分别涉…

OpenHarmony语言基础类库【@ohos.url (URL字符串解析)】

说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import Url from ohos.url URLParams9 URLParams接口定义了一些处理URL查询字符串的实用方法。 constructor9 constructor(init?…

ZooKeeper的分布式锁

ZooKeeper的分布式锁机制主要利用ZooKeeper的节点特性,通过创建和删除节点来实现锁的控制。 实现步骤: 创建锁节点:当一个进程需要访问共享资源时,它会在ZooKeeper中创建一个唯一的临时顺序节点作为锁。尝试获取锁:进…

vue+springboot实验个人信息,修改密码,忘记密码功能实现

前端部分 新增Person(个人页面),Password(修改密码页面),还需要对Manager,login页面进行修改 router文件夹下的index.js: import Vue from vue import VueRouter from vue-router i…

从图灵奖看计算中的随机性与伪随机性

从图灵奖看计算中的随机性与伪随机性 目录 从图灵奖看计算中的随机性与伪随机性 一、引言 二、随机性的本质与应用 三、图灵奖得主对随机性的研究 四、伪随机性的应用 五、案例研究:伪随机数生成器的发展 六、最佳实践 一、引言 在计算机科学的广阔天地中&…