设计模式(8)

1:原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

类型:创建类模式

代码:

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

// 人的抽象类
class Person
{
public:
	// 复杂的对象,需要复制的功能,应该提供一个自我复制的方法
	virtual Person* clone() = 0;
	virtual void show() = 0;
};

class Student :public Person
{
public:
	Student(){}
	Student(string name, int id)
	{
		this->name  = name;
		this->id = id;
	}

	virtual void show()
	{
		cout << "name = " << name << ", id = " << id << endl;
	}

	virtual Person* clone()
	{
#if 0
		// 1、调用赋值运算符
		Student *s1 = new Student();
		// 一个一个属性复制c
		/*
			s1->name = this->name;
			s1->id   = this->id;
		*/

		*s1 = *this;   // 调用默认的赋值运算符重载
#endif
		// 调用拷贝构造
		Student *s1 = new Student(*this);
		return s1;
	}

private:
	string name;
	int    id;
};

int main()
{
	Person *p1 = new Student("wang", 10);
	p1->show();



	// 复制一个学生
	Person *p2 = p1->clone();
	p2->show();

	delete p1;
	delete p2;

	return 0;
}
含义:

抽象层按需求提供功能和拷贝函数,利用抽象指针对对象进行拷贝和创建。

优点:使复制对象变得简单,使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。并且在复制对象时不会调用构造函数。


2  代理模式

含义    Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。    
所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

类型  结构型模式

代码   

#include <iostream>
using namespace std;

// 代理与被代理的类必须都有共同的方法,把他们的方法提炼出来写成基类
// 卖书的抽象基类
class Subject
{
public:
	virtual void sellBook() = 0;
};

// 实体店卖书
class RealBookStore:public Subject
{
public:
	virtual void sellBook()
	{
		cout << "实体店卖书...." << endl;
	}
};

// 代理类,淘宝:帮实体书店卖书
class Taobao:public Subject
{
public:
	Taobao()
	{
		rbs = new RealBookStore;
	}

	virtual void sellBook()
	{
		cout << "淘宝卖书...." << endl;

		// 变着花样卖书
		discount();
		rbs->sellBook();     // 实际卖的书
	}

	void discount()
	{
		cout << "打五折" << endl;
	}


private:
	RealBookStore *rbs;     // 要代理的对象
};

int main()
{
	Subject *s = new Taobao;
	s->sellBook();

	
	return 0;
}

含义 将功能封装成一个抽象类,基于该类衍射出代理子类


3  装饰模式

定义:   又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。
              装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

类型 :  结构者模型

代码:   

#include <iostream>

using namespace std;
// 公共的基类
class Car
{
public:
	virtual void show() = 0;
};

// 普通的车:能跑
class RunCar:public Car
{
public:
	virtual void show()
	{
		cout << "普通车,可以跑" << endl;
	}
};


// 装饰工厂,可以让车能飞 上天
class FlyCarDecorator:public Car
{
public:
	FlyCarDecorator(Car *car)
	{
		this->car = car;
	}

	
	virtual void show()
	{
		car->show();    // 原有车的功能
		// -----------------添加新功能

		fly();          // 新添加的功能
	}

	void fly()
	{
		cout << "飞车工厂出品,能上天" << endl;
	}
private:
	Car *car;
};


// 装饰工厂,可以让车能下海
class SwimCarDecorator:public Car
{
public:
	SwimCarDecorator(Car *car)
	{
		this->car = car;
	}


	virtual void show()
	{
		car->show();    // 原有车的功能
		// -----------------添加新功能

		swim();          // 新添加的功能
	}

	void swim()
	{
		cout << "海洋工厂出品, 车能下海" << endl;
	}
private:
	Car *car;
};

int main()
{
	Car * car = new RunCar;    // 普通的车
	car->show();

	cout << "------------------------" << endl;

	Car *flycar = new FlyCarDecorator(car);
	flycar->show();

	cout << "------------------------" << endl;
	Car *swimcar = new SwimCarDecorator(car);
	swimcar->show();

	cout << "------------------------" << endl;
	Car *swimFlyCar = new SwimCarDecorator(flycar);
	swimFlyCar->show();

	delete swimFlyCar;
	delete swimcar;
	delete flycar;
	delete car;

	return 0;
}include <iostream>

using namespace std;
// 公共的基类
class Car
{
public:
	virtual void show() = 0;
};

// 普通的车:能跑
class RunCar:public Car
{
public:
	virtual void show()
	{
		cout << "普通车,可以跑" << endl;
	}
};


// 装饰工厂,可以让车能飞 上天
class FlyCarDecorator:public Car
{
public:
	FlyCarDecorator(Car *car)
	{
		this->car = car;
	}

	
	virtual void show()
	{
		car->show();    // 原有车的功能
		// -----------------添加新功能

		fly();          // 新添加的功能
	}

	void fly()
	{
		cout << "飞车工厂出品,能上天" << endl;
	}
private:
	Car *car;
};


// 装饰工厂,可以让车能下海
class SwimCarDecorator:public Car
{
public:
	SwimCarDecorator(Car *car)
	{
		this->car = car;
	}


	virtual void show()
	{
		car->show();    // 原有车的功能
		// -----------------添加新功能

		swim();          // 新添加的功能
	}

	void swim()
	{
		cout << "海洋工厂出品, 车能下海" << endl;
	}
private:
	Car *car;
};

int main()
{
	Car * car = new RunCar;    // 普通的车
	car->show();

	cout << "------------------------" << endl;

	Car *flycar = new FlyCarDecorator(car);
	flycar->show();

	cout << "------------------------" << endl;
	Car *swimcar = new SwimCarDecorator(car);
	swimcar->show();

	cout << "------------------------" << endl;
	Car *swimFlyCar = new SwimCarDecorator(flycar);
	swimFlyCar->show();

	delete swimFlyCar;
	delete swimcar;
	delete flycar;
	delete car;

	return 0;
}

含义:对于对象要进行扩展的功能封装成抽象类,基于抽象类有多个装饰子类,当扩展功能时建立一个新的父类指针来继承旧的指针;


4      适配器模式

定义:Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。

类型:结构者类型

代码 : 

#include <iostream>

using namespace std;

// 想要用的是 5v
class Current5V
{
public:
	virtual void use5V() = 0;
};

// 实际用电是 220V
class Current220v
{
public:
	void use220v()
	{
		cout << "我是220v电压" << endl;
	}
};

// 适配器,是一种特殊的5v电压,是通过220v转换过来的
class Adapte :public Current5V
{
public:
	Adapte(Current220v *c220v)
	{
		this->current220v = c220v;
	}

	void use5V()
	{
		current220v->use220v();    // 本身使用的是220v电压
		cout << "经过转换, 开始使用5v电压" << endl; 
	}
private:
	Current220v *current220v;
};

int main()
{
	Current220v *c220v = new Current220v;   // 实际220v电压
	Current5V *c5v = new Adapte(c220v);     // 适配器接上电压,开始转换成5v使用

	c5v->use5V();   // 开始用
	return 0;
}

含义:当对象依赖与外部接口但接口中某些功能不是期望功能时,可以通过适配器重写该功能后使用;


5: 外观模式

含义:  Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。

类型:  结构型模式

代码:

#include<iostream>

using namespace std;

class SystemA
{
public:
	void dothing()
	{
		cout << "系统A 工作" << endl;
	}
};

class SystemB
{
public:
	void dothing()
	{
		cout << "系统B 工作" << endl;
	}
};

class SystemC
{
public:
	void dothing()
	{
		cout << "系统C 工作" << endl;
	}
};

class Facade
{
public:
	Facade()
	{
		sa = new SystemA;
		sb = new SystemB;
		sc = new SystemC;
	}

	void dothing()
	{
		sa->dothing();
		sb->dothing();
		sc->dothing();
	}
private:
	SystemA *sa;
	SystemB *sb;
	SystemC *sc;
};

int main()
{
	// 客户端自己操作
/*
	SystemA *sa = new SystemA;
	SystemB *sb = new SystemB;
	SystemC *sc = new SystemC;

	sa->dothing();
	sb->dothing();
	sc->dothing();
*/
	Facade *facade = new Facade;
	facade->dothing();
	return 0;
}

含义:为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。引入外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由外观角色来实现,从而降低了系统的耦合度

在遇到以下情况使用facade模式:
    1) 当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。
    这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。facade可以提供一个简单的缺省视图,
    这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。
    2) 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入 facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性 和可移植性。
    3) 当你需要构建一个层次结构的子系统时,使用 facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。


6 桥接模式

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

类型 构造型模式

代码  

#include <iostream>
using namespace std;
// 颜色的抽象类
class Color
{
public:
	virtual void fillColor() = 0;
};

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

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

class Black:public Color
{
public:
	virtual void fillColor()
	{
		cout << "填充 黑色" << endl;
	}
};


// 图形的抽象类
class Shape
{
public:
	virtual void setColor(Color *color) = 0; // 设置颜色
	virtual void fillColor() = 0;            // 填充
protected:
	Color *color;
};

class Circle:public Shape 
{
public:
	virtual void setColor(Color *color)
	{
		this->color = color;
	}
	virtual void fillColor()
	{
		cout << "我是 圆" << endl;
		color->fillColor();       // 填充颜色
	}
};

class Rectangle:public Shape 
{
public:
	virtual void setColor(Color *color)
	{
		this->color = color;
	}
	virtual void fillColor()
	{
		cout << "我是 矩形" << endl;
		color->fillColor();       // 填充颜色
	}
};

void fillColor(Shape *s, Color *c)
{
	s->setColor(c);
	s->fillColor();
}

int main()
{
	// 颜色
	Color *c1 = new Red;
	Color *c2 = new Yellow;
	Color *c3 = new Black;

	// 图形
	Shape *s1 = new Circle;
	Shape *s2 = new Rectangle;

	// 图形与颜色任意组合
	fillColor(s1, c2);    // 圆填充黄色
	fillColor(s1, c3);    // 圆填充黑色

	fillColor(s2, c1);    // 矩形填充红色
	fillColor(s2, c2);    // 矩形填充黄色
	return 0;
}

含义 : 降低实现功能对接口的依赖性,将同一类的接口化为抽象接口。


7 组合模式

定义: Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。

类型 : 构造型模式

代码

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

// 文件和文件夹统一操作:设置一个统一的操作方式
class IFile
{
public:
	virtual void showName() = 0;
	virtual void add(IFile *) = 0;        // 添加文件
	virtual void remove(IFile *) = 0;     // 删除文件
	virtual list<IFile*>* gechild() = 0;  // 获取文件列表
};

// 普通文件
class File : public IFile
{
public:
	File(string name)
	{
		this->name = name;
	}

	virtual void showName()
	{
		cout << name << endl;
	}
	virtual void add(IFile *)
	{
		return;
	}
	virtual void remove(IFile *)
	{
		return ;
	}
	virtual list<IFile*>* gechild() 
	{
		return NULL;
	}
private:
	string name;
};

// 目录
class Dir: public IFile
{
public:
	Dir(string name)
	{
		this->name = name;
		m_list = new list<IFile*>;
	}
	~Dir()
	{
		if (m_list != NULL)
		{
			// 先删除子文件
			while (!m_list->empty())
			{
				list<IFile*>::iterator it = m_list->begin();
				delete *it;
				m_list->erase(it);
			}
			delete m_list;
			m_list = NULL;
		}
	}

	virtual void showName()
	{
		cout << name << endl;
	}
	virtual void add(IFile *file)
	{
		m_list->push_back(file);
	}
	virtual void remove(IFile *file)
	{
		m_list->remove(file);
		delete file;
	}
	virtual list<IFile*>* gechild() 
	{
		return m_list;
	}
private:
	string name;
	list<IFile *>* m_list;
};

void init(IFile *root)
{
	IFile *dir1 = new Dir("电影");
	IFile *dir2 = new Dir("游戏");
	IFile *dir3 = new Dir("战狼");

	IFile *file1 = new File("大话西游.mp4");
	IFile *file2 = new File("羞羞的铁拳.mp4");
	IFile *file3 = new File("战狼1.mp4");
	IFile *file4 = new File("战狼2.mp4");

	IFile *file5 = new File("LOL.exe");
	IFile *file6 = new File("仙剑奇侠传.exe");

	IFile *file7 = new File("大话设计模式.pdf");
	IFile *file8 = new File("面试宝典.pdf");

	root->add(dir1);
	root->add(dir2);
	root->add(file7);
	root->add(file8);

	dir1->add(file1);
	dir1->add(file2);
	dir1->add(dir3);

	dir3->add(file3);
	dir3->add(file4);

	dir2->add(file5);
	dir2->add(file6);
}

// 显示结点
void show(IFile *node, int gap)
{
	for (int i = 0; i < gap; i++)
	{
		cout << "----";
	}

	// 1、打印自己
	if (node != NULL)
	{
		node->showName();
	}
	else
		return;

	// 2、打印子文件
	list<IFile*>* plist = node->gechild();
	if (plist != NULL)  // 代表是目录
	{
		for (list<IFile*>::iterator it = plist->begin(); it != plist->end(); it++)
		{
			show(*it, gap+1);
		}
	}
}

int main()
{
	IFile *root = new Dir("D盘");

	init(root);

	root->showName();

	//list<IFile*>* plist = root->gechild();
	//for (list<IFile*>::iterator it = plist->begin(); it != plist->end(); it++)
	//{
	//	(*it)->showName();
	//}

	show(root, 0);

	return 0;
}

含义 把一组相似的对象当作一个单一的对象,解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。


8 观察者模式

定义:Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
   Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

类型:行为类模型

代码:

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

class Observer;

// 抽象的通知者
class Subject
{
public:
	virtual void notify(string info) = 0;  // 将消息发送给所有观察者
	virtual void add(Observer *) = 0;      // 添加观察者
	virtual void remover(Observer *) = 0;  // 移除观察者

protected:
	list<Observer *> m_list;
};

// 抽象的观察者
class Observer
{
public:
	virtual void upadate(string info) = 0;  // 根据提供的消息进行自我更新
	virtual void subscribe(Subject *) = 0;  // 关注、注册、找个对象通知自己消息
	virtual void disScribe(Subject *) = 0;  // 取消关注
};

// 通知者:秘书
class Secretary: public Subject
{
public:
	virtual void add(Observer *o)
	{
		m_list.push_back(o);
	}

	virtual void remover(Observer *o)
	{
		m_list.remove(o);
	}

	virtual void notify(string info)
	{
		 // 挨个通知
		for (list<Observer*>::iterator it = m_list.begin(); it != m_list.end(); it++)
		{
			(*it)->upadate(info);   
		}
	}
};

// 玩游戏
class PlayGame:public Observer
{
public:
	virtual void subscribe(Subject *s)
	{
		s->add(this);
	}

	virtual void disScribe(Subject *s)
	{
		s->remover(this);
	}

	virtual void upadate(string info)
	{
		if (info == "老板来了")
		{
			cout << "把游戏收起来,假装好好工作" << endl;
		}
		else if (info == "老板走了")
		{
			cout << "很开心, 继续玩游戏" << endl;
		}
	}
};

// 看电影
class SeeMovie:public Observer
{
public:
	virtual void subscribe(Subject *s)
	{
		s->add(this);
	}

	virtual void disScribe(Subject *s)
	{
		s->remover(this);
	}

	virtual void upadate(string info)
	{
		if (info == "老板来了")
		{
			cout << "把电影起来,假装好好工作" << endl;
		}
		else if (info == "老板走了")
		{
			cout << "很开心, 继续看电影" << endl;
		}
	}
};

// 聊天
class Chat:public Observer
{
public:
	virtual void subscribe(Subject *s)
	{
		s->add(this);
	}

	virtual void disScribe(Subject *s)
	{
		s->remover(this);
	}

	virtual void upadate(string info)
	{
		if (info == "老板来了")
		{
			cout << "把QQ关了,假装好好工作" << endl;
		}
		else if (info == "老板走了")
		{
			cout << "很开心, 继续聊天" << endl;
		}
	}
};

int main()
{
	Subject *s = new Secretary;

	Observer *w1 = new PlayGame;
	Observer *w2 = new SeeMovie;
	Observer *w3 = new Chat;

	w1->subscribe(s);     // 告诉秘书,老板来了通知一声
	w2->subscribe(s);     // 告诉秘书,老板来了也通知一声
	w3->subscribe(s);     // 告诉秘书,老板来了也通知一声


	cout << "老板来了"<< endl;
	s->notify("老板来了");

	w3->disScribe(s);     // 要好好工作了

	cout << "----------------" << endl;
	cout << "老板走了"<< endl;
	s->notify("老板走了");

	return 0;

含义: 创建一个通知类对象,利用栈来保存观察者对象。当关注的数据发生变化时,挨个通知。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值