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. 鼠标滚动事件兼容性 wheel、onwheel

    wheelEvent = "onwheel" in document.createElement("div") ? "wheel" : // ...

  2. linux项目-之监控-nagios

    nagios core plugins 对象 主机(交换机,路由器,防火墙,服务器,虚拟机等),主机组 服务(主机上提供的服务如80,3306,1521,21等)/资源(cpu,内存使用情况,磁盘,网 ...

  3. Centos6.5下安装protobuf及简单使用

    1.protobuf是google公司提出的数据存储格式,详细介绍可以参考:https://code.google.com/p/protobuf/ 2.下载最新的protobuf,下载地址:https ...

  4. [内核同步]Linux内核同步机制之completion

    转自:http://blog.csdn.net/bullbat/article/details/7401688 内核编程中常见的一种模式是,在当前线程之外初始化某个活动,然后等待该活动的结束.这个活动 ...

  5. try-catch(C# 参考)

    https://msdn.microsoft.com/zh-cn/library/0yd65esw.aspx Try-catch 语句包含一个后接一个或多个 catch 子句的 try 块,这些子句指 ...

  6. 继承extends

    class Person{ String name; int age; void eat(){ System.out.println("吃饭"); } void introduce ...

  7. SpringMVC 中获取所有的路由配置。

    ApplicationContext context = TMSContextLookup.getApplicationContext(); String[] controllerList = con ...

  8. 根据 MySQL 状态优化 ---- 3. key_buffer_size

    查看 MySQL 服务器运行的各种状态值: mysql> show global status: 3. key_buffer_size key_buffer_size 是设置 MyISAM 表索 ...

  9. 压测 linux + jexus + mono + asp.net mvc

    环境: 1.centos 7 + jexus 5.8.1 + mono 4.4.2 + asp.net mvc 4 做了一点小优化: 一.调整文件描述符数量限制编辑 /etc/security/lim ...

  10. C++ 如何有效地使用对话框

    Q:如何在对话框中加入工具条 在 OnInitDialog 中加入下面代码: BOOL CYourDlg::OnInitDialog() { CDialog::OnInitDialog(); // C ...