1.意图

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

2.动机

可以组合多个简单组件以形成一些较大的组件,这些组件又可以组合成更大的组件。Composite模式描述了如何使用递归组合,使得用户不必对这些类进行区别。

3.适用性

  • 表示对象的部分-整体层次结构。
  • 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

4.结构

5.代码实例

#include <memory>
#include <vector> class Graphic
{
public:
Graphic(std::shared_ptr<Graphic> pParent);
virtual void Add(std::shared_ptr<Graphic>& pGraphic);
virtual void Remove(std::shared_ptr<Graphic>& pGraphic);
virtual std::shared_ptr<Graphic> GetChild(int iIndex);
virtual std::shared_ptr<Graphic>& GetParent();
virtual void Opereate(); protected:
std::shared_ptr<Graphic> m_pParent; std::vector<std::shared_ptr<Graphic>> m_vecChildrenGraphics; }; class Circle : public Graphic
{
public:
Circle(std::shared_ptr<Graphic> pParent);
void Opereate();
}; class Retangle : public Graphic
{
public:
Retangle(std::shared_ptr<Graphic> pParent);
void Opereate();
}; class Line : public Graphic
{
public:
Line(std::shared_ptr<Graphic> pParent);
void Opereate();
}; class Picture : public Graphic
{
public:
Picture(std::shared_ptr<Graphic> pParent);
virtual void Add(std::shared_ptr<Graphic>& pGraphic);
virtual void Remove(std::shared_ptr<Graphic>& pGraphic);
virtual std::shared_ptr<Graphic> GetChild(int iIndex);
void Opereate();
};
#include "Graphic.h"
#include <iostream> Graphic::Graphic(std::shared_ptr<Graphic> pParent)
: m_pParent(pParent)
{
} void Graphic::Add(std::shared_ptr<Graphic>& pGraphic)
{
std::cout<< "Leaf Cannot Add Childrren" << std::endl;
} void Graphic::Remove(std::shared_ptr<Graphic>& pGraphic)
{
std::cout<< "Leaf Cannot Remove Childrren" << std::endl;
} std::shared_ptr<Graphic> Graphic::GetChild(int iIndex)
{
std::cout<< "Leaf Cannot Get Child" << std::endl;
return nullptr;
} std::shared_ptr<Graphic>& Graphic::GetParent()
{
return m_pParent;
} void Graphic::Opereate()
{
std::cout<< "Default Operate Executed" <<std::endl;
} Circle::Circle(std::shared_ptr<Graphic> pParent)
:Graphic(pParent)
{
} void Circle::Opereate()
{
std::cout << "Circle Operate Exeeuted" << std::endl;
} Retangle::Retangle(std::shared_ptr<Graphic> pParent)
:Graphic(pParent)
{
} void Retangle::Opereate()
{
std::cout << "Retangle Operate Exeeuted" << std::endl;
} Line::Line(std::shared_ptr<Graphic> pParent)
:Graphic(pParent)
{
} void Line::Opereate()
{
std::cout << "Line Operate Exeeuted" << std::endl;
} Picture::Picture(std::shared_ptr<Graphic> pParent)
: Graphic(pParent)
{
} void Picture::Add(std::shared_ptr<Graphic>& pGraphic)
{
m_vecChildrenGraphics.push_back(pGraphic); std::cout<< "ChildrenGraphics Add Success" <<std::endl;
} void Picture::Remove(std::shared_ptr<Graphic>& pGraphic)
{
for(auto iter=m_vecChildrenGraphics.begin();
iter!=m_vecChildrenGraphics.end();++iter)
{
if((*iter) == pGraphic)
{
m_vecChildrenGraphics.erase(iter);
std::cout<< "ChildrenGraphics remove Success"<<std::endl;
break;
}
}
} std::shared_ptr<Graphic> Picture::GetChild(int iIndex)
{
auto count = m_vecChildrenGraphics.size();
if(iIndex <= count -)
{
std::cout<< "Get Child Success" <<std::endl;
return m_vecChildrenGraphics[iIndex];
} return nullptr;
} void Picture::Opereate()
{
for(auto iter=m_vecChildrenGraphics.begin();
iter!=m_vecChildrenGraphics.end();++iter)
{
(*iter)->Opereate();
}
}
#include "Graphic.h"
#include <iostream> int main()
{
std::shared_ptr<Graphic> pPicture(new Picture(nullptr)); std::shared_ptr<Graphic> pCircle(new Circle(pPicture)); std::shared_ptr<Graphic> pRetangle(new Retangle(pPicture)); std::shared_ptr<Graphic> pLine(new Line(pPicture)); pPicture->Add(pCircle);
pPicture->Add(pRetangle);
pPicture->Add(pLine); pPicture->Opereate(); if(nullptr == pPicture->GetParent())
{
std::cout<< "pPicture is root" <<std::endl;
} auto pNode = pPicture->GetChild(); auto pParent = pNode->GetParent(); if(nullptr != pParent)
{
std::cout<<"Node has Parent"<<std::endl;
} std::cout << "Parent Operate:"<<std::endl; pParent->Opereate(); pNode->Opereate(); pNode->Add(pNode); pNode->Remove(pNode); pNode->GetChild(); pNode = pPicture->GetChild(); if(nullptr != pNode->GetParent())
{
std::cout<<"Node has Parent"<<std::endl;
} pNode->Opereate(); pNode->Add(pNode); pNode->Remove(pNode); pNode->GetChild(); pNode = pPicture->GetChild(); if(nullptr != pNode->GetParent())
{
std::cout<<"Node has Parent"<<std::endl;
} pNode->Opereate(); pNode->Add(pNode); pNode->Remove(pNode); pNode->GetChild(); pPicture->Remove(pCircle);
pPicture->Remove(pRetangle);
pPicture->Remove(pLine); while(); }

6.测试结果

7.效果

  • 定义了包含基本对象和组合对象的类层次结构 基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合。
  • 简化客户代码 客户可以一致地使用组合结构和单个对象。
  • 使得容易增加新类型的组件 新定义的Composite或Leaf子类自动地与已有的结构和客户代码一起工作,客户程序不需因新的Component类而改变。
  • 使设计变的更加一般化。

Composite(组合)--对象结构型模式的更多相关文章

  1. 组合模式/composite模式/对象结构型模式

    组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...

  2. Decorator(装饰)-对象结构型模式

    1.意图 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 2.别名 包装器 Wrapper. 3.动机 给某个对象而不是整个类添加一些功能.一个较为灵 ...

  3. Bridge(桥接)-对象结构型模式

    1.意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 2.动机 在抽象类与它的实现之间起到桥梁作用,使它们可以独立地变化. 3.适用性 不希望在抽象和它的实现部分之间有一个固定的绑定关系. ...

  4. Facade(外观)-对象结构型模式

    1.意图 为子系统中的一组接口提供一个一致的接口,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 2.动机 将一个系统划分成若干子系统有利于降低系统的复杂性.一个常见的设计目 ...

  5. Bridge模式——对象结构型模式

    今天看了Bridge模式,对其进行简单的总结,并给出几篇通俗易懂的文章链接. (一)意图--将抽象部分和它的实现部分分离,使它们都可以独立地变化. 适用于从多维度描述的类型,拆解开来,使其能沿着各维度 ...

  6. Adapter(适配器)-类对象结构型模式

    1.意图 将一个类接口转换成客户希望的另外一个接口.Adapter模式使那些原本不能一起工作的类,可以一起工作. 2.别名 包装器 Wrapper. 3.动机 一个应用可能会有一些类具有不同的接口,并 ...

  7. Proxy(代理)-对象结构型模式

    1.意图 为其它对象提供一种代理以控制对这个对象的访问. 2.别名 Surrogate. 3.动机 通过Proxy可以达到对一个对象的访问控制. 4.适用性 远程代理  为一个对象在不同地址空间提供局 ...

  8. Flyweight(享元)--对象结构型模式

    1.意图 运用共享技术有效地支持大量细粒度的对象. 2.动机 Flyweight模式描述了如何共享对象,使得可以细粒度地使用它们,而无需高昂的代价.flyweight是一个共享对象,它可以同时在多个场 ...

  9. 组合模式(Composite Pattern) ------------结构型模式

    组合模式使用面向对象的思想来实现树形结构的处理和构件,描述了如何将容器对象和叶子对象进行递归组合,实现简单,灵活性好. 组合模式(Composite Pattern):组合多个对象形成树形结构以表示具 ...

随机推荐

  1. checkbox提交多组数据到action

    突然想通过checkbox来提交多组数据到action,一时间想不起来怎么写,到网上流岚大婶们的笔迹之后,有了新发现! 方法一: 在action用一个String类型的变量来接受checkbox传过来 ...

  2. MFC 线程使用

    CWinThread*  m_pthread; //多线程对象 struct param//参数传递结构体 { int id; TASK t[20]; }; CNB400Dlg::CNB400Dlg( ...

  3. 7个混合式HTML5移动开发框架

    在这个时间开始学习移动开发真是最好不过了,每个人应该都有一些移动应用的创意,而且你并不需要任何的原生应用编程经验,你只需要一些HTML的相关知识,懂一些CSS和JavaScript就够了.如果你总听别 ...

  4. Makefile中的特殊宏定义以及实用选项

    Makefile中的一些特殊宏定义的名字跟shell中的位置变量挺相似的. $?    当前目标所依赖的文件列表中比当前目标文件还要新的文件 $@   当前目标我名字 $<   当前依赖文件的名 ...

  5. 理解Python装饰器

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权 ...

  6. Android String操作

    android String.valueOf(ch).getBytes("GBK") --------------------------------------------- S ...

  7. Python-Tkinter几何布局管理(转)

    所有的Tkinter组件都包含专用的几何管理方法,这些方法是用来组织和管理整个父配件区中子配件的布局的.Tkinter提供了截然不同的三种几何管理类:pack.grid和place. pack() p ...

  8. linux 安装软件程序

    1.用aptitude管理软件包 查看已安装的/未安装的等软件包 无法通过aptitude看到一个细节是所有跟某个特定软件包关联的所有文件的列表.利用dpkg命令能看到这个列表. dpkg -L pa ...

  9. [IIS]IIS扫盲(一)

    iis - IIS概念相关 1.IIS(Inter-IC Sound bus)又称I2S,是菲利浦公司提出的串行数字音频总线协议.目前很多音频芯片和MCU都提供了对IIS的支持.IIS总线只处理声音数 ...

  10. win7以管理员身份运行bat提示系统找不到指定的路径。

    windows7“以管理员身份运行”bat提示“系统找不到指定的路径.” 使用批处理安装服务,直接双击运行没有权限,右键“以管理员身份运行”却提示“系统找不到指定的路径.”,反复查看路径是正确的. 打 ...