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;
含义: 创建一个通知类对象,利用栈来保存观察者对象。当关注的数据发生变化时,挨个通知。