设计模式 ---- 组合模式和装饰者模式

组合和装饰器模式

装饰器模式

先说装饰器模式,装饰器模式是为了向主体添加可以复用的功能,通常只有一个主体对象,(但是不排除,装饰器和组合模式混合,或者其他模式混合使用)

装饰器模式的特点,是对象嵌套层层包装


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);
posted on 2026-09-05 19:47  咸云闲鱼  阅读(4)  评论(0)    收藏  举报