博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Composite——设计模式学习笔记
阅读量:5866 次
发布时间:2019-06-19

本文共 4922 字,大约阅读时间需要 16 分钟。

Composite模式

一 意图

  将对象组合成树形结构以表示“部分——整体”的层次结构。Composite使得用户对单个对象操作和组合对象的操作使用具有一致性。

二 动机

  绘图编辑器和图形捕捉系统图形应用程序中,总是存在简单的图形到简单的组件再到复杂的组件,

但他们在本质上都是图形(各种基本的图形组合或者递归组合)。

这可以分成两个部分:基本图元和组件图形。对于基本的图元可以单独定义类;对于组件图形可以使用图元容器(Container)。

  结果就是:在使用时,对于同样的都是图形的图元和组件必须加以区分对待(图元对象Or容器对象)。对于庞大的图形系统,这无疑是非常复杂的!

  解决方法:Composite模式递归组合,实现系统对图元还是组件都一致性对待。

      

对于Line或者Rectangle或者Picture都是Graphic,都具有相同的Graphic属性。

但对于Picture来说它是组合基本图元的方式组成的组件,本身会具有新的特性。

所以在Graphic图形中存在派生类组件的结构:

    

      

三 适用性及其结构

1 表示对象的部-整体层次结构

2 忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

3 结构:

      

Component:为组合中的对象生命接口

      在适当情况下,实现所有类共有的接口的缺省行为

      声明一个接口用于访问和管理Component的子组件

      在递归结构中定义一个接口,用于访问一个父部件。

Leaf:在组合中表示叶节点对象

Composite:定义所有子部件的行为,实现与子部件相关的操作。

Composite实现任意组合方式构建定制新的Component。

4 性能分析

  Leaf和Composite同为Component,实际上之间是区别,Composite是各个Component的组合,

需要对各个Component进行维护,Leaf是不需要这些维护的。

所以这些维护接口是Composite自身提供还是Component提供这些维护的接口,比如:addChild,removeChild等。

  透明性:由基类Component提供所有Composite需要的基本一些接口管理其中的ChildComponent,

如addChild,removeChild等,这样就Leaf或者Composite具有一致性,而在客户端无需区分Leaf还是Composite。

  安全性:基类只提供Leaf相关的接口,作为Composite需要管理器中的ChildComponent需要自己提供。

保证Leaf的操作安全性。这样导致Leaf和Composite的不一致性需要区别对待,会造成系统的复杂性。

         这个在应用中我觉得,如果我们大量的操作都是基于Leaf的直接使用,而很少用到Composite,可以采取安全性,

但是这造成的结果就是:扩展性非常差。但通常在使用中大多数都是基于Composite方式,便于扩展和代码重用,

所以对ChildComponent的管理是非常重要的。在系统中都可以随处可见透明性的Composite模式,以构建一颗树形的对象模型。

 

四 代码实现

以电脑主板为例,电脑主板包括:CPU,内存,扩展槽,芯片组,时钟发生器,IDE接口和软驱,电源模块,I/O接口……

选取其中的:CPU,芯片组,I/O接口为例

1 Equicpment基类

View Code
/*----------------------------------------------------------------*/ /* class Equipment                                                */ /*----------------------------------------------------------------*/ class Equipment {
#define EQUIP_MAX_NUM (5) public: Equipment() {
cout<<" Equipment constructor "<
startEquipment(); } } } virtual void startEquipment() {
cout<<"Equipment startEquipment"<

2 Chip基类

View Code
/*----------------------------------------------------------------*/ /* class Chip                                                     */ /*----------------------------------------------------------------*/ class Chip: public Equipment {
public: Chip() {
cout<<" Chip constructor "<

3 Cpu部分

View Code
//CPU部分 /*----------------------------------------------------------------*/ /* class CpuProcessor                                             */ /*----------------------------------------------------------------*/ class CpuProcessor: public Chip {
public: CpuProcessor() {
cout<<" CpuProcessor constructor "<
addChildEquip(cpu); this->addChildEquip(slot); } virtual void startEquipment() {
this->start(); cout<<" CpuEquipment startEquipment "<
<

4 ChipSet部分

View Code
//ChipSet芯片组 /*----------------------------------------------------------------*/ /* class GraphicsChip                                             */ /*----------------------------------------------------------------*/ class GraphicsChip: public  Chip {
public: GraphicsChip() {
cout<<" GraphicsChip constructor "<
addChildEquip(gChip); this->addChildEquip(sChip); } virtual void startEquipment() {
this->start(); cout<<" ChipSet startEquipment "<
<

5 I/O接口部分

View Code
//I/O接口 /*----------------------------------------------------------------*/ /* class IOEquipment                                               */ /*----------------------------------------------------------------*/ class IOEquipment: public Equipment {
public: IOEquipment() {
cout<<" IOEquipment constructor "<
addChildEquip(kIO); this->addChildEquip(mIO); this->addChildEquip(uIO); } virtual void startEquipment() {
this->start(); cout<<" IOEquipmentSet startEquipment "<
<

6 MotherboardEquipment 主板

View Code
//主板 /*----------------------------------------------------------------*/ /* class IOEquipmentSet                                           */ /*----------------------------------------------------------------*/ class MotherboardEquipment: public Equipment {
public: MotherboardEquipment() {
cout<<" MotherboardEquipment constructor "<
<
addChildCpu(); ChipSet* chipEquip = new ChipSet(); chipEquip->addChildChip(); IOEquipmentSet* ioEquip = new IOEquipmentSet(); ioEquip->addChildIO(); this->addChildEquip(cpuEquip); this->addChildEquip(chipEquip); this->addChildEquip(ioEquip); } };

例子可能并非很完善和合理,仅仅是为了演示一下Composite模式。

五 实例分析

         将以手机上屏幕显示控件为例。控件涉及到UI显示布局和消息传递处理(按键触屏)

      

      

在Frame类中通过众多基类指针,将所有的对象组成一个树形结构。有助于对象管理和内存管理。

如果父类对象释放那么其子对象没有存在的必要了,根据这棵树就能遍历所有子对象,并将其释放掉

(当然并不是在这里,这里仅包含的是Frame对象的树结构)主要是用于界面显示布局层次和消息传递响应。

转载地址:http://xjjnx.baihongyu.com/

你可能感兴趣的文章
PAT A1015
查看>>
PAT A1081 分数计算
查看>>
热点账户问题和常用解决方案【上】
查看>>
一些关于Rust在2019年的思考
查看>>
浅谈前端路由
查看>>
小程序hover-class点击态效果——小程序体验
查看>>
如何利用开放数据域为微信小游戏添加社交关系链玩法
查看>>
手把手教你学Vue-2(组件开发)
查看>>
2018记一次前端面试笔试考题一
查看>>
【js】——前端无插件导出excel:自定义sheet、插入图片、设置打印、页边距、页脚等...
查看>>
java9迁移注意事项
查看>>
轻松搭建以太坊私有链
查看>>
练手项目3:访问图像网站,查找某类型图片,下载查询结果
查看>>
leetcode 695 Max Area of Island
查看>>
redis主从同步原理概述
查看>>
nodejs模块加载机制
查看>>
与Python的无缝集成----基本特殊方法.(Mastering Objecting-oriented Python 笔记)
查看>>
React.js 小书 Lesson17 - 前端应用状态管理 —— 状态提升
查看>>
linux ubuntu 安装/卸载/删除python-igraph方法
查看>>
将本地项目上传github
查看>>