组合模式:允许将对象组合成树形结构来表现“整体/部分”层次结构,组合能让客户以统一的方式处理叶节点对象以及组合对象。
eg:文件和文件夹
我们称包含其他组件的组件为组合对象(文件夹),而没有包含其他组件的组件为叶节点对象(文件)。
对叶节点对象可能会限制某些行为。
类图:
实现如下:
component.h:
#ifndef COMPONENT_H
#define COMPONENT_H
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Component {
public:
virtual void add(Component* c) = 0;
virtual void print() = 0;
virtual string getName() = 0;
bool isDirectory;
protected:
string m_name;
};
#endif // COMPONENT_H
file.h:
#ifndef FILE_H
#define FILE_H
#include "component.h"
class File : public Component {
public:
File(string name);
virtual void add(Component* c) override
{
}
virtual string getName() override
{
return m_name;
}
virtual void print() override;
};
File::File(string name)
{
m_name = name;
isDirectory = false;
}
void File::print()
{
cout << "文件: " << m_name << " ";
}
#endif // FILE_H
directory.h:
#ifndef DIRECTORY_H
#define DIRECTORY_H
#include "component.h"
class Directory : public Component {
public:
Directory(string name);
virtual void add(Component* c) override;
virtual void print() override;
virtual string getName() override;
private:
vector<Component* > m_components;
};
Directory::Directory(string name)
{
m_name = name;
isDirectory = true;
}
void Directory::add(Component* c)
{
m_components.push_back(c);
}
string Directory::getName()
{
return m_name;
}
void Directory::print()
{
for(int i = 0; i < m_components.size(); i++)
{
if(m_components[i]->isDirectory)
{
cout << "文件夹:" << m_components[i]->getName() << " ";
}
else
{
m_components[i]->print();
}
}
cout << endl;
}
#endif // DIRECTORY_H
main.cpp:
/*
* 组合模式
*
* date:2023-9-16
*/
#include "file.h"
#include "directory.h"
int main()
{
Component* root = new Directory("根目录");
Component* directoryMusic = new Directory("音乐");
Component* directoryVideo = new Directory("视频");
Component* others = new File("其他");
Component* music1 = new File("平凡之路.mp3");
Component* music2 = new File("日落大道.mp3");
Component* video1 = new File("C++.mp4");
Component* video2 = new File("Python.mp4");
root->add(directoryMusic);
root->add(directoryVideo);
root->add(others);
directoryMusic->add(music1);
directoryMusic->add(music2);
directoryVideo->add(video1);
directoryVideo->add(video2);
root->print();
directoryMusic->print();
directoryVideo->print();
}
运行截图: