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. Office web app server2013详细的安装和部署

    转自:http://blog.csdn.net/u011355311/article/details/9360293 SharePoint 2013集成Office web apps server20 ...

  2. Property ClientHeight does not exist 问题解决

    delphi的TFrame继承自另一个TFrame时,最好通过File->New->Other...->Delphi Projects->Inheritable Items 的 ...

  3. [系统集成] OpenLDAP使用AD密码

    关于OpenLDAP和AD帐号的整合,网上有大量的文档,绝大多数都不符合我们的需求,下面的方案是我经过调研.测试.修改.最终采用的. . 需求概述 公司网络中有两种帐号:OpenLDAP帐号和AD帐号 ...

  4. ruby中http请求方法整理

    #POST请求 请求包是json包 返回body并转换成json对象def post_json *args uri = URI.parse args[0] req = Net::HTTP::Post. ...

  5. struts1&&Hibernate Demo1

    用struts1和Hibernate实现简单登录案例 主要思路:通过用户名name验证 如果一致则验证成功. 附上源码: 1.建立student表,这里使用的是mysql数据库,以下为该表的DDL: ...

  6. codeforces 356 C. Compartments 构造 贪心

    一辆车,有n个车厢,每个车厢刚好有4个人 车上有n个学生,第i个车厢有a[i]个学生 如果一个车厢里面的学生数 <= 2,这个车厢里的学生会不开心 如果一个车厢里面的学生数 > 2,这个车 ...

  7. string引用类型解惑

    先上代码: string b = "123"; private void Form1_Load(object sender, EventArgs e) { Test(b); Mes ...

  8. git branch几个简单操作

    1.git branch  该命令会列出当先项目中的所有分支信息,其中以*开头的表示当前所在的分支.参数-r列出远程仓库中的分支,而-a则远程与本地仓库的全部分支. 2.git branch deve ...

  9. angularjs如何在视图渲染结束之后,或者render之后执行指令中的link方法呢?

    angularjs如何在视图渲染结束之后,或者render之后执行指令中的link方法 关键字: $timeout app.directive("myDirective",func ...

  10. 就是这么简单!使用Rest-assured 测试Restful Web Services

    使用 Rest-assured 测试 Restful Web Services 转载注明出处: http://www.cnblogs.com/wade-xu/p/4298819.html 这里向大家介 ...