`
zyjwy02
  • 浏览: 142111 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

设计模式之Composite(组合)

阅读更多

Composite模式定义:
对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

所以Composite模式使用到Iterator模式,和Chain of Responsibility模式类似。

Composite好处:
1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码
2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。

如何使用Composite?
首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component).

下面的代码是以抽象类定义,一般尽量用接口interface,

public abstract class Equipment
{
  private String name;
  //实价
  public abstract double netPrice();
  //折扣价格
  public abstract double discountPrice();
  //增加部件方法  
  public boolean add(Equipment equipment) { return false; }
  //删除部件方法
  public boolean remove(Equipment equipment) { return false; }
  //注意这里,这里就提供一种用于访问组合体类的部件方法。
  public Iterator iter() { return null; }
  
  public Equipment(final String name) { this.name=name; }
}

抽象类Equipment就是Component定义,代表着组合体类的对象们,Equipment中定义几个共同的方法。

public class Disk extends Equipment
{
  public Disk(String name) { super(name); }
  //定义Disk实价为1
  public double netPrice() { return 1.; }
  //定义了disk折扣价格是0.5 对折。
  public double discountPrice() { return .5; }
}

Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。
还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',这是树形结构中通常的情况,应该比较容易理解。现在我们先要定义这个组合体:

abstract class CompositeEquipment extends Equipment
{
  private int i=0;
  //定义一个Vector 用来存放'儿子'
  private Lsit equipment=new ArrayList();

  public CompositeEquipment(String name) { super(name); }

  public boolean add(Equipment equipment) {
     this.equipment.add(equipment);
     return true;
   }

  public double netPrice()
  {
    double netPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      netPrice+=((Equipment)iter.next()).netPrice();
    return netPrice;
  }

  public double discountPrice()
  {
    double discountPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      discountPrice+=((Equipment)iter.next()).discountPrice();
    return discountPrice;
  }
  

  //注意这里,这里就提供用于访问自己组合体内的部件方法。
  //上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
  public Iterator iter()
  {
    return equipment.iterator() ;
  {
  //重载Iterator方法
   public boolean hasNext() { return i<equipment.size(); }
  //重载Iterator方法
   public Object next()
   {
    if(hasNext())
       return equipment.elementAt(i++);
    else
        throw new NoSuchElementException();
   }
  

}

上面CompositeEquipment继承了Equipment,同时为自己里面的对象们提供了外部访问的方法,重载了Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实现.

我们再看看CompositeEquipment的两个具体类:盘盒Chassis和箱子Cabinet,箱子里面可以放很多东西,如底板,电源盒,硬盘盒等;盘盒里面可以放一些小设备,如硬盘 软驱等。无疑这两个都是属于组合体性质的。

public class Chassis extends CompositeEquipment
{
   public Chassis(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}

public class Cabinet extends CompositeEquipment
{
   public Cabinet(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}

至此我们完成了整个Composite模式的架构。

我们可以看看客户端调用Composote代码:

Cabinet cabinet=new Cabinet("Tower");

Chassis chassis=new Chassis("PC Chassis");
//将PC Chassis装到Tower中 (将盘盒装到箱子里)
cabinet.add(chassis);
//将一个10GB的硬盘装到 PC Chassis (将硬盘装到盘盒里)
chassis.add(new Disk("10 GB"));

//调用 netPrice()方法;
System.out.println("netPrice="+cabinet.netPrice());
System.out.println("discountPrice="+cabinet.discountPrice());

上面调用的方法netPrice()或discountPrice(),实际上Composite使用Iterator遍历了整个树形结构,寻找同样包含这个方法的对象并实现调用执行.

Composite是个很巧妙体现智慧的模式,在实际应用中,如果碰到树形结构,我们就可以尝试是否可以使用这个模式。

以论坛为例,一个版(forum)中有很多帖子(message),这些帖子有原始贴,有对原始贴的回应贴,是个典型的树形结构,那么当然可以使用Composite模式,那么我们进入Jive中看看,是如何实现的.

Jive解剖
在Jive中 ForumThread是ForumMessages的容器container(组合体).也就是说,ForumThread类似我们上例中的 CompositeEquipment.它和messages的关系如图:
[thread]
   |- [message]
   |- [message]
      |- [message]
      |- [message]
         |- [message]

我们在ForumThread看到如下代码:

public interface ForumThread {
   ....
   public void addMessage(ForumMessage parentMessage, ForumMessage newMessage)
         throws UnauthorizedException;

   public void deleteMessage(ForumMessage message)
         throws UnauthorizedException;

  
   public Iterator messages();
      ....

}

类似CompositeEquipment, 提供用于访问自己组合体内的部件方法: 增加 删除 遍历.

结合我的其他模式中对Jive的分析,我们已经基本大体理解了Jive论坛体系的框架,如果你之前不理解设计模式,而直接去看Jive源代码,你肯定无法看懂。

分享到:
评论

相关推荐

    基于TypeScript的命令行天气查询应用

    基于TypeScript的命令行天气查询应用

    中文处理_文字识别_PyQt5_百度AI_多功能识别系统db_1741775082.zip

    车牌识别项目

    API 接口文档模板:规范化 HTTPS 与 AES 加密的安全交互设计

    内容概要:本文详细介绍了标准化接口文档的撰写规范,涵盖了修订记录、接口描述、接口列表清单及详细规格等多个方面。强调了安全性与一致性的重要实践,包括使用HTTPS协议进行通讯确保安全性、POST方法提交数据、JSON格式及UTF-8字符编码的数据交换标准。同时,规定接口需要保持幂等性和错误处理机制如失败重试,并针对调出和调入的不同类型接口提供详细的描述与样例。 适用人群:适用于有经验的技术团队成员以及正在构建或维护Web API的服务提供商。 使用场景及目标:主要用于指导开发者正确地设计和部署高质量且安全可靠的网络应用程序编程接口(API),特别是在金融行业或者对数据隐私敏感的应用领域。 其他说明:文中还包括接口开发所需的完整代码片段和技术细节介绍,确保能够直接应用于生产环境。提供的加解密工具类可用于具体接口加密需求。

    mufeng510_LicensePlateRecognit_1741773780.zip

    车牌识别项目

    (源码)基于Arduino和ESP8266的智能药盒系统.zip

    # 基于Arduino和ESP8266的智能药盒系统 ## 项目简介 智能药盒系统(MedsButler)是一个专为老年人和病患设计的自动药物配送系统。该系统通过Arduino和ESP8266模块实现药物的定时配送,并通过振动提醒患者服药。系统由三个主要部分组成主控制器(Atmega2560)、ESP8266通信模块和患者手环。 ## 项目的主要特性和功能 1. 定时药物配送系统能够根据预设的时间表自动配送药物。 2. 无线通信使用ESP8266模块实现与主控制器的无线通信。 3. 振动提醒患者手环在服药时间通过振动提醒患者。 4. 模块化设计系统分为三个主要模块,便于维护和扩展。 ## 安装使用步骤 1. 硬件连接 将Atmega2560与ESP8266模块通过串行接口连接。 将患者手环的ESP8266模块与主控制器通过无线通信连接。 2. 软件配置 下载并安装Arduino IDE。

    南昌县某幼儿园.dwg

    南昌县某幼儿园.dwg

    50页-智慧园区建设运维及整体服务解决方案.pdf

    在当今数字化浪潮中,园区智慧化建设正成为推动区域经济发展和产业转型升级的关键力量。这份园区智慧化解决方案全面展示了如何通过集成大数据、云计算、物联网(IoT)、人工智能(AI)、地理信息系统(GIS)和建筑信息模型(BIM)等前沿技术,为传统产业园区插上数字的翅膀,打造“数字创新”产业园区。 数字技术赋能,重塑园区生态 传统产业园区往往面临运营效率低下、管理粗放、资源利用率不高等问题。而通过智慧化改造,园区可以实现从“清水房”到“精装房”的华丽蜕变。数字化技术不仅提升了园区的运营管理水平,降低了运营成本,还显著增强了园区的竞争力和吸引力。例如,通过构建园区数字模型(CIM),实现了多规数据融合,形成了园区规划“一张图”,为园区管理提供了直观、高效的可视化工具。此外,智能感知设施的应用,如环境监测、能耗监测等,让园区管理更加精细化、科学化。智慧能源管理系统通过实时监测和智能分析,帮助园区实现低碳绿色发展,而综合安防管控系统则通过AI+视频融合技术,为园区安全保驾护航。更有趣的是,这些技术的应用还让园区服务变得更加个性化和便捷,比如园区移动APP,让企业和员工可以随时随地享受园区服务,从会议室预定到智慧公寓管理,一切尽在“掌”握。 智慧运营中心,打造园区大脑 园区智慧化建设的核心在于构建智慧运营中心,这可以看作是园区的“数字大脑”。通过集成物联网服务平台、大数据分析平台、应用开发赋能平台等核心支撑平台,智慧运营中心实现了对园区内各类数据的实时采集、处理和分析。在这个“大脑”的指挥下,园区管理变得更加高效、协同。比如,建设工程项目智慧监管系统,通过基于二三维GIS底图的统一数字化监管,实现了对园区在建工程项目的进度控制、质量控制和安全控制的全方位监管。可视化招商系统则利用CIM模型,以多种方式为园区对外招商推介提供了数字化、在线化的展示窗口。而产业经济分析系统,则通过挖掘和分析产业数据,为园区产业发展提供了有力的决策支持。智慧运营中心的建设,不仅提升了园区的整体运营水平,还为园区的可持续发展奠定了坚实基础。 产业服务升级,激发创新活力 园区智慧化建设不仅关注基础设施和运营管理的升级,更重视产业服务的创新。通过整合平台资源、园区本地资源和外围资源,打造园区服务资源池,为园区内的企业和个人提供了全面的智慧管理、智慧工作和智慧生活服务。特别是工业互联网平台和工业云服务的建设,为园区内的企业提供了轻量化、智能化的生产服务。这些服务涵盖了车间信息化管理、云制造执行、云智能仓储、设备健康管理等多个方面,有效提升了企业的生产效率和竞争力。此外,通过产业经济分析系统,园区还能够对潜在客户进行挖掘、对经销商进行风控、对产品销量进行预测等,为企业的市场营销提供了有力支持。这些创新的产业服务,不仅激发了园区的创新活力,还为区域经济的转型升级注入了新的动力。总之,园区智慧化建设是一场深刻的变革,它正以前所未有的方式重塑着园区的生态、运营和服务模式,为园区的可持续发展开辟了广阔的前景。

    YOLOv5Lite由yolov5进化而来,模型大小仅为900kb,在Raspberry Pi 4B上为17M fp1.zip

    python、yolo、pytorch

    sisu-inject-bean-2.3.0-11.el7.x64-86.rpm.tar.gz

    1、文件内容:sisu-inject-bean-2.3.0-11.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/sisu-inject-bean-2.3.0-11.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    《哪吒2》电影评论数据

    数据内容包含:用户昵称、用户评分、评论时间、用户地址、评论内容

    docker-18.03.1-ce.tgz

    docker-18.03.1-ce.tgz

    计算机视觉_车牌识别_EasyPR_Android_移动应用_1741773975.zip

    车牌识别项目

    网络安全是指通过技术、管理和法律手段保护网络系统、数据及用户隐私,防止未经授权的访问、攻击和信息泄露,确保可用性、完整性和机密性

    网络安全是通过技术手段、管理策略和法律规范,保护网络系统、数据及用户隐私免受未经授权的访问、攻击或泄露,确保网络服务的可用性、数据的完整性和机密性。其核心内容包括: 1. 技术防护:如防火墙、入侵检测系统(IDS)、加密通信、漏洞修复等。 2. 管理措施:包括安全策略制定、访问控制、安全审计、应急响应等。 3. 法律与合规:遵循《网络安全法》《数据安全法》等法规,保障用户隐私与国家安全。 4. 安全意识:提升用户对钓鱼攻击、密码安全等风险的防范能力。 # 适用人群 - 企业/组织:IT运维人员、安全管理员、开发工程师(需保障业务系统安全)。 - 普通用户:需防范个人信息泄露、网络诈骗等风险。 - 政府与公共部门:确保关键基础设施(如电力、金融、通信)的安全运行。 - 教育领域:学生及教师需了解基础安全知识以应对网络威胁。 # 适用场景及目标 1. 企业场景: - 目标:防御黑客攻击、数据泄露、勒索软件等,保障业务连续性。 - 措施:部署网络隔离、多因素认证、定期渗透测试。 2

    chromedriver-linux64-136.0.7064.0.zip

    chromedriver-linux64-136.0.7064.0.zip

    expert.txt后端运行数据改进

    expert.txt后端运行数据改进

    技术运维-机房巡检表及巡检说明

    技术运维-机房巡检表及巡检说明

    微信小程序背景音乐播放器影音娱乐demo完整源码下载-精品源码.zip

    微信小程序背景音乐播放器影音娱乐demo完整源码下载_精品源码

    CCleaner用来清理注册表

    CCleaner用来清理注册表

    lilongweidev_GoodTrash_1741785110.zip

    图像处理项目实战

    车辆识别_YOLOv5_SVM_车牌检测识别系统_1741774643.zip

    车牌识别项目

Global site tag (gtag.js) - Google Analytics