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. Discovering the Computer Science Behind Postgres Indexes

    This is the last in a series of Postgres posts that Pat Shaughnessy wrote based on his presentation ...

  2. AndroidImagePicker 的使用

    github地址 https://github.com/easonline/AndroidImagePicker 效果图

  3. jquery中checkbox选中的问题之prop&attr惹的祸

    一个网上很多的例子如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  4. HackerRank "Larry's Array"

    I caught the sparkle in my mind and got AC1 ! It is a great great experience ! So the basic idea: pe ...

  5. 【java消息格式化】使用MessageFormat进行消息格式化

    主要介绍了: 消息格式化的基本使用: 格式化:匹配数字: 格式化:匹配日期: 格式化:匹配时间: 格式化:多次匹配: MessageFormat用来格式化一个消息,通常是一个字符串.MessageFo ...

  6. Yii里增删改查的操作方法

    一.AR $model=New user();//user是数据库中的一张表,有id,name,pwd字段 1.增加: <1. $model->name='张三': $model-> ...

  7. JVM参数(一)JVM类型以及编译器模式

    现在的JVM运行Java程序(和其它的兼容性语言)时在高效性和稳定性方面做的非常出色.自适应内存管理.垃圾收集.及时编译.动态类加载.锁优化——这里仅仅列举了某些场景下会发生的神奇的事情,但他们几乎不 ...

  8. 使用Maven编译项目时提示程序包javax.servlet.http不存在

    将apache-tomcat-8.0.23\lib下的servlet-api.jar拷贝到C:\Program Files\Java\jdk1.8.0_31\jre\lib\ext下即可

  9. C++引用与指针

    在做函数参数时, 引用不可以设置默认值, 指针可以 void fun(const string& url,  string* domain = NULL); 另const放在函数后面, 表示这 ...

  10. 树莓派_360wifi2_佳能MP236打印机

    入手树莓派后一直没时间弄,设想用360wifi做无线网卡,也一直不得解,今天成功写下经验 本人刷的是官方系统,版本为3.12.28,首先更新系统内核,参考以下网址: http://groenholdt ...