组合模式

组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。

目的:当整体和部分的功能具有极大的相似性的时候,使用该模式将整个结构简单化,对于整体和部分都提供统一的接口,方便使用。

使用情形:

  1. 常用于树形结构的表示,表示部分-整体的层次结构
  2. 整体、部分存在高度重合,需要用户忽略些许不同,使用统一接口的时候

 

Component:组合对象的接口声明,实现部分和整体的共同对外接口。

Leaf:具体到部分的类,不可再分的叶子对象,因此改部分的删除和添加本类对象常不进行具体实现

Composite:容器对象,用来存储子部分,相当于枝干,存在对叶子对象进行添加和删除的操作接口

 

在实现的时候,有两种可用于选择:

  1. 叶子对象和容器对象分离,继承于接口
  2. 叶子对象和容器对象合并,但一类,设定成员vector等进行子部分存储。

 

 

根据上面的uml可以知道两种使用的差别。

  1. 离:容易进行拓展、从实现上更有结构肝、对于各种类型的文件或者子部分可用实现自己的特殊需求
  2. 合并:逻辑简单、代码实现简单,但是不易进行拓展,对于各种子部分的特殊需求实现太过于复杂,所以常用于很明确不拓展的但类型情况处理

优点:

  1. 将复杂的对象分为清晰的层次结构,并且利于子部分的拓展
  2. 部分整体的统一接口,便于用户使用
  3. 对于复杂且接口相似的树结构进行简单化

 

缺点:

  1. 违反了依赖倒转
  2. 对于部分和整体的接口具有一定的限制性,需要双方接口存在高度的统一性
// CompositeModel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class CMyFile
{
protected:
    string m_name;
    //string path;
public:
    //查改
    virtual string getName() = 0;
    void setName(string str) { m_name = str; }
    
    //增删
    virtual void addFile(CMyFile* file) = 0;
    virtual void removeFile(int index) = 0;

    //显示
    virtual void show() = 0;
};

class CTxtFile:public CMyFile
{
public:
    string getName() { return  (m_name + ".txt"); }

    void addFile(CMyFile* file) {}
    void removeFile(int index) {}

    void show() { cout << "Text File :" + m_name + ".txt" << endl; }
};
class CVideoFile :public CMyFile
{
public:
    string getName() { return  (m_name + ".mp4"); }

    void addFile(CMyFile* file) {}
    void removeFile(int index) {}

    void show() { cout << "Video File :" + m_name + ".mp4" << endl; }
};
class CFolder :public CMyFile
{
private:
    vector<CMyFile*> m_file;
public:
    string getName() { return  m_name; }

    void addFile(CMyFile* file) { m_file.push_back(file); }
    void removeFile(int index) { m_file.erase(std::begin(m_file) + index); }

    void show() {
        cout << "Folder :" + m_name << endl;

        for (int i = 0; i < m_file.size(); ++i)
        {
            if(NULL == m_file[i])
                continue;
            m_file[i]->show();
        }
    }
};


class CMyFile2
{
protected:
    string m_name;
    string m_suffix;
    vector<CMyFile2*> m_file;
    //string path;
public:
    //查改
    string getName() { return m_name; }
    void setName(string str) { m_name = str; }

    string getSuffix() { return m_suffix; }
    void setSuffix(string suff) { m_suffix = suff; }
    //增删
    void addFile(CMyFile2* file) { m_file.push_back(file); }
    void removeFile(int index) { m_file.erase(std::begin(m_file) + index); }

    void show() {
        cout << m_name + m_suffix << endl;

        for (int i = 0; i < m_file.size(); ++i)
        {
            if (NULL == m_file[i])
                continue;
            m_file[i]->show();
        }
    }
};
int main()
{
    //File 1
    cout << "Test 1(more Class):" << endl;
    CMyFile* testFile1 = new CFolder;
    testFile1->setName("Folder 1");

    CMyFile *text = new CTxtFile;
    text->setName("Test1 Text File");

    CMyFile *video = new CVideoFile;
    video->setName("Test1 Video File");

    testFile1->addFile(text);
    testFile1->addFile(video);

    testFile1->show();

    cout << endl;
    cout << endl;
    //File 2
    cout << "Test 1(one Class):" << endl;
    CMyFile2* testFile2 = new CMyFile2;
    testFile2->setName("Folder 2");
    testFile2->setSuffix("");

    CMyFile2* text2 = new CMyFile2;
    text2->setName("Test2 Text File");
    text2->setSuffix(".txt");

    CMyFile2* video2 = new CMyFile2;
    video2->setName("Test2 video File");
    video2->setSuffix(".mp4");

    testFile2->addFile(text2);
    testFile2->addFile(video2);
    testFile2->show();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值