设计模式 ---- 组合模式和装饰者模式
组合和装饰器模式
装饰器模式
先说装饰器模式,装饰器模式是为了向主体添加可以复用的功能,通常只有一个主体对象,(但是不排除,装饰器和组合模式混合,或者其他模式混合使用)
装饰器模式的特点,是对象嵌套层层包装
class Cat{
public:
virtual void Eat() = 0;
}
// 猫的实体类
class DemoCat : public Cat{
public:
void Eat() override{
std::cout << "Demo cat Fun : Eat()" << std::endl;
}
}
// 猫的装饰器
class HatCatDecorator : public Cat{
private:
Cat* cat;
public:
HatCatDecorator(Cat* catTemp) : cat(catTemp){}
void Eat() override{
std::cout << "HatCatDecorator Fun : Eat()" << std::endl;
cat -> Eat();
}
}
在主业务种使用
DemoCat catIns;
HatCatDecorator* dec(&catIns);
dec -> Eat();
这里程序会输出
HatCatDecorator Fun : Eat()
Demo cat Fun : Eat()
这里的“dec”是一个Cat的装饰器,装饰了DemoCat实体"catIns",catIns是Cat接口的具体实现
装饰器是将主体一层一层加东西,加功能(装饰器本身和被装饰对象都实现 Cat 接口,这样装饰器就可以和背钻功能是的实例一样调用相同的3接口---方法)
组合模式
组合模式是:把一个个对象组织成一个整体,组合后的整体又是一个可以被组合的对象
抽象基类:抽象基类不是现实世界中所有对象本来就拥有的共同属性,而是为了让用户能够统一操作 Leaf 和 Composite
这个接口类是用户需要的类,是为了满足用户需求而特别创造存在的,比如在植物大战僵尸种,用户使用火爆辣椒,清除一行的僵尸,那么就可以将一行的僵尸组合成一个group,在爆炸发生后,直接调用ZombieGroup的remove,直接移除所有僵尸,如果有需要,僵尸可以发射投射物,但是火爆辣椒也可以将其烧掉,也可以继承该接口,然后添加经组合进该zombiegroup
现实中 File 和 Folder 并不是简单的父子关系
但是为了让用户能够:
这里举一个上古例子,文件系统
fileSys->showType();
我们人为抽象出了:
class FileSystem
{
public:
virtual void showType() = 0;
};
然后:
class File : public FileSystem
{
...
};
class Folder : public FileSystem
{
...
};
所以这个基类的价值确实不是:
“File 和 Folder 天生就有一个叫 FileSystem 的东西。”
而是:
为了让 Leaf 和 Composite 对外提供统一的操作接口
详细示例
//抽象接口
class FileSystem
{
public:
virtual void show() = 0;
virtual ~FileSystem() = default;
};
//文件
class File : public FileSystem
{
public:
void show() override
{
std::cout << "File\n";
}
};
//文件夹
class Folder : public FileSystem
{
private:
std::vector<FileSystem*> children;
public:
void add(FileSystem* file)
{
children.push_back(file);
}
void show() override
{
std::cout << "Folder\n";
for (auto child : children)
{
child->show();
}
}
};
主业务逻辑
Folder root;
root.add(new File);
root.add(new File);
Folder subFolder;
subFolder.add(new File);
root.add(&subFolder);
浙公网安备 33010602011771号