【设计模式学习笔记】组合模式与桥接模式案例详解(C++实现)

目录

一、组合模式

1. 什么是组合模式

2. 组合模式案例

 二、桥接模式

1. 什么是桥接模式

 2. 桥接模式案例


一、组合模式

1. 什么是组合模式

Composite Pattern,组合模式,是一种结构型模式。

组合模式将对象组合成树形结构以表示“整体-部分”的层次结构,并使得用户对单个对象和组合对象的使用具有一致性。

组合模式构造了一个树形的对象结构,并且通过一个属性对象可以可以访问整棵树的对象。

组合模式的三种角色:

  • Component:抽象角色,代表树形结构的抽象结点,它定义了所有实现类的统一接口(属性、方法、行为),并提供了访问和管理子结点的接口;简言之,Component定义了Leaf和Composite共同的操作接口,比如增加子结点,删除子结点等行为,是一个抽象基类。
  • Leaf:叶子结点,叶子结点中没有子结点,类似于树中的叶子结点,或文件系统中的文件。
  • Composite :枝结点,可以存储子结点,并实现子结点的操作,类似于文件系统的文件夹。

2. 组合模式案例

首先定义一个抽象类,为Leaf和Composite提供统一接口,假设要做一个文件系统,文件夹(Composite)中可以放入文件和文件夹,文件(Leaf)中不可以放入任何子结点。

class Component
{
public:
	virtual void display() = 0; //显示当前文件或文件夹名称
	virtual void add(Component* node) = 0; //在当前文件夹增加一个文件或文件夹
	virtual void remove(Component* node) = 0; //在当前文件夹删除一个文件或文件夹
	virtual vector<Component*>* get_child() = 0; //获取文件夹下属文件或文件夹
};

定义一个文件类,文件中不可加入子结点

class Leaf : public Component
{
private:
	string name;
public:
	Leaf(string name)
	{
		this->name = name;
	}
	virtual void display()
	{
		cout << "Leaf: " << this->name << endl;
	}
	virtual void add(Component* node)
	{
		cout << "叶子结点,无法加入" << endl;
	}
	virtual void remove(Component* node)
	{
		cout << "叶子结点,无此操作" << endl;
	}
	virtual vector<Component*>* get_child()
	{
		cout << "叶子结点,无子结点" << endl;
		return NULL;
	}
};

定义一个文件夹类,可以加入问价或文件夹

class Composite : public Component
{
private:
	string name;
	vector<Component*>* vec;
public:
	Composite(string name)
	{
		this->name = name;
		vec = new vector<Component*>;
	}
	~Composite()
	{
		if (vec != NULL)
		{
			delete vec;
			vec = NULL;
		}
	}
	virtual void display()
	{
		cout << "Composite: " << this->name << endl;
	}
	virtual void add(Component* node)
	{
		vec->push_back(node);
	}
	virtual void remove(Component* node)
	{
		for (vector<Component*>::iterator it = vec->begin(); it != vec->end(); it++)
		{
			if (*it == node)
			{
				vec->erase(it);
			}
		}
	}
	virtual vector<Component*>* get_child()
	{
		cout << "*" << this->name << " child: " << "*\n";
		for (vector<Component*>::iterator it = vec->begin(); it != vec->end(); it++)
		{
			(*it)->display();
		}
		return vec;
	}
};

客户端操作

int main()
{
	Component* root = NULL;
	Leaf* l1 = NULL;
	Leaf* l2 = NULL;
	Composite* dir = NULL;

	root = new Composite("/root");
	l1 = new Leaf("1.cpp");
	l2 = new Leaf("2.cpp");
	dir = new Composite("/home");

	root->add(dir);
	dir->add(l1);
	dir->add(l2);

	cout << "============" << endl;
	root->display();
	root->get_child();
	dir->get_child();
	cout << "============" << endl;

	delete dir;
	delete l2;
	delete l1;
	delete root;

	system("pause");
	return 0;
}

 二、桥接模式

1. 什么是桥接模式

 Bridge Pattern,桥接模式,是一种结构型设计模式。

桥接模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。

也就是说,通过桥接模式可以实现抽象部分与实现部分的解耦合,使得抽象和实现都可以独立的发生变化,当通过继承不能实现开闭原则的时候,就可以考虑桥接模式。比如,图形和颜色,把图形设计一个抽象类,颜色设计一个抽象类,然后根据需要的图形去实现图形类,并根据需要的颜色实现颜色类,通过两个抽象类就可以实现颜色和图形的组合。

  • Abstractions:抽象类接口,包含了一个对行为实现类Implementor的引用,也就是说二者具有关联关系。
  • Refined Abstraction:抽象类接口的实现类,实现了Abstractions中定义的接口,并可以调用Implementor中的方法(包含了Implementor的引用)。
  • Implementor:行为实现类接口,定义了一系列操作。
  • Concretelmp lementor:具体实现类,实现了Implementor中的操作。

 2. 桥接模式案例

实现对不同图形上不同颜色,首先定义两个抽象类,颜色类和图形类

class Color
{
public:
	virtual void get_color() = 0;
};

class Graph
{
protected:
	Color* mGraphColor;
public:
	Graph(Color* mGraphColor)
	{
		this->mGraphColor = mGraphColor;
	}
	virtual void smear_color() = 0; //给图形上色
};

定义三个具体的颜色

class Red : public Color
{
public:
	virtual void get_color()
	{
		cout << "红色" << endl;
	}
};

class Blue : public Color
{
public:
	virtual void get_color()
	{
		cout << "蓝色" << endl;
	}
};

class Yellow : public Color
{
public:
	virtual void get_color()
	{
		cout << "黄色" << endl;
	}
};

实现具体的图形

class Circle : public Graph
{
public:
	Circle(Color* mGraphColor) : Graph(mGraphColor) {};
	virtual void smear_color()
	{
		cout << "圆形 + ";
		mGraphColor->get_color();
	}
};

class Triangle : public Graph
{
public:
	Triangle(Color* mGraphColor) : Graph(mGraphColor) {};
	virtual void smear_color()
	{
		cout << "三角形 + ";
		mGraphColor->get_color();
	}
};

客户端操作,为图形上色

int main()
{
	Color* m_color = NULL;

	m_color = new Red;
	Circle* m_circle = new Circle(m_color);
	m_circle->smear_color();

	delete m_color;
	m_color = new Blue;
	Triangle* m_triangle = new Triangle(m_color);
	m_triangle->smear_color();

	delete m_color;
	delete m_triangle;
	delete m_circle;

	system("pause");
	return 0;
}

posted @ 2022-04-19 11:00  Mindtechnist  阅读(64)  评论(0编辑  收藏  举报  来源