设计模式三大类:
设计模式的基本原则
一、创建型模式
(1)单例模式:
(2)简单工厂模式
(3)工厂模式
(4)抽象工厂模式
(5)建造者模式
二、结构型模式
(1)代理模式
(2)装饰模式
(3)适配器模式
(4)桥接模式
(5)外观模式
(6)享元模式
三、行为型模式
(1)观察者模式
1、一个类对另一个类的依赖性应当建立在最小的接口上
2、客户端程序不应该依赖它不需要的接口方法
1、父类的方法都要在子类中实现或重写,并且派生类只实现其抽象类中声明的方法,不应该写出多余的方法定义或实现
2、在客户端程序中只应该使用父类对象而不是直接使用子类对象,这样可以实现运行期间的绑定
使用单例模式可以保证一个类只生成唯一的实例对象(在整个程序空间中,该类只存在一个实例对象)
单例模式主要解决一个全局使用的类频繁的创建和销毁的问题。单例模式下可以确保某一个类只有一个实例
“保证一个类只有一个实例存在,同时提供访问该实例的全局访问方法”
例如: static A* m_instence static A*getInstence()
单例模式的设计步骤:
//Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
~Widget();
private:
Ui::Widget *ui;
public:
static Widget* getInstence();//全局静态方法
private slots:
void on_pushButton_clicked(); //测试用的槽函数
private:
explicit Widget(QWidget *parent = 0);//构造函数私有化
private:
static Widget* m_instence;//静态指针
};
Widget* Widget::m_instence = nullptr;
#endif // WIDGET_H
//Widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "form.h"
Widget* Widget::m_instence = nullptr;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
Widget* Widget::getInstence()
{
//单例模式
if(m_instence == nullptr)
{
m_instence = new Widget;
}
return m_instence;
}
void Widget::on_pushButton_clicked()
{
Form *f = new Form;
f->show();
this->close();
}
//main.cpp
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *w = Widget::getInstence();
w->show();
return a.exec();
}
测试:当在文本框输入后,跳转到跳转测试窗口,然后再返回测试窗口,输入的数据依然保持
1、懒汉式单例模式的优点:
不需要使用单例时不用创建,节省内存
(懒汉式可以动态地传入参数,但是第一次传进去之后,第二次再传因为它不是空的了,所以在实际运用时可以直接入参默认值)
2、但是这样的单例模式在多线程编程中又会发生一些问题:(懒汉式单例模式的缺点)
每次获取单例的时候要进行判断,降低了软件的性能,在多线程编程中可能会发生创建多个对象的问题(这样就不是单例了)
解决方法:线程锁,线程同步
饿汉式单例模式:
优点:对于多线程编程中比较安全
缺点:不管用还是不用都占内存,无法通过静态方法传入参数。
两者区别:
懒汉式单例模式:用的时候调用,不用的时候不调用
饿汉式单例模式:在main()函数之前初始化,或者在多线程编程的情况下使用
又称静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
模式中的角色:
工厂角色:负责实现创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品对象。
抽象角色:所有对象的父类,共有的公共接口,负责描述所有实例
具体产品角色:具体实例对象
需求分析:
有一个水果类Fruits,创造苹果、梨子...的水果
有一个工厂类Factory,加工苹果、梨子...
class Fruits
{
public:
virtual string getName() = 0;
};
//苹果
class Apple : public Fruits
{
public:
string getName()
{
return "Apple";
}
};
//梨
class Peer : public Fruits
{
public:
string getName()
{
return "Peer";
}
};
class Factory
{
public:
static Fruits* Create(Fruits* fruits)
{
Fruits* tmp = NULL;
if (fruits->getName() == "Apple")
{
tmp = new Apple();
}
else if (fruits->getName() == "Peer")
{
tmp = new Peer();
}
else
{
return NULL;
}
return tmp;
}
};
int main()
{
Fruits* apple = Factory::Create(new Apple);
cout << apple->getName() << endl;
Fruits* peer = Factory::Create(new Peer);
cout << peer->getName() << endl;
return 0;
}
简单工厂模式
优点:根据具体需求,创建具体类的对象,明确区分了类与类之间的不同,有利于整个软件体系结构的优化
缺点:非“高内聚”,当具体产品类不断增多时,可扩展性不够好
又称多态性工厂模式。核心的工厂类不再负责所有铲平的创建,而实将具体的创建工作交给子类完成,工厂类是一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,不负责具体产品类的实例化。
工厂模式主要解决接口选择问题,该模式下定义一个创建对象的接口,让其子类自己决定实例化哪个工厂类
模式中的角色:
抽象工厂角色:工厂模式的核心,任何工厂类都必须实现这个接口
具体工厂角色:抽象工厂的一个实现,负责实例化产品对象
抽象角色:所有对象的父类,共有的公共接口,负责描述所有实例所共有的接口
具体产品角色:具体实例对象
需求分析:
有一个水果类Fruits,创造苹果、梨子...的水果
有一个工厂类Factory,苹果工厂只能加工苹果,梨子加工厂只能加工梨子
//-----------水果---------------//
class Fruits
{
public:
virtual string getName() = 0;
};
//苹果
class Apple : public Fruits
{
public:
string getName()
{
return "Apple";
}
};
//梨
class Peer : public Fruits
{
public:
string getName()
{
return "Peer";
}
};
//-----------工厂---------------//
class Factory
{
public:
virtual Fruits* create() = 0;
};
//苹果工厂:在创造时创建苹果类对象,返回
class AppleFactory : public Factory
{
public:
Fruits* create()
{
return new Apple;
}
};
//梨工厂:在创造时创建梨类对象,返回
class PeerFactory : public Factory
{
public:
Fruits* create()
{
return new Peer;
}
};
//进入某水果加工厂,只能生产该水果
void func(Factory* factory)
{
//水果:父类指针指向子类对象
Fruits* fruits = factory->create();
cout << fruits->getName() << endl;
}
int main_factory()
{
func(new AppleFactory);
func(new PeerFactory);
return 0;
}
简单工厂模式 & 工厂模式:
工厂模式的核心是抽象工厂类,简单工厂模式的核心是具体类
工厂模式实现了开闭原则和可扩展性;可以应用于更复杂的需求。
工厂模式/多态性:每个具体的工厂类都有一个共有的接口/共同的抽象父类 (同一接口的不同实现)
实际上需求需要的可能不仅仅是抽象产品的实例,工厂类创建的是抽象产品的具体子类的实例。
模式中的角色:
抽象工厂角色:工厂模式的核心,任何工厂类都必须实现这个接口
具体工厂角色:抽象工厂的一个实现,负责实例化产品对象
抽象角色:所有对象的父类,共有的公共接口,负责描述所有实例所共有的接口
具体产品角色:具体实例对象
需求分析:
有一个水果类Fruits,创造苹果、梨子...的水果
有一个工厂类Factory,南方工厂加工南方苹果和南方梨子,北方加工厂加工北方苹果和北方梨子
//-----------水果---------------//
class Fruits
{
public:
virtual string getName() = 0;
};
//北方苹果
class northApple : public Fruits
{
public:
string getName()
{
return "north Apple";
}
};
//南方苹果
class southApple : public Fruits
{
public:
string getName()
{
return "south Apple";
}
};
//北方梨
class northPeer : public Fruits
{
public:
string getName()
{
return "north Peer";
}
};
//南方梨
class southPeer : public Fruits
{
public:
string getName()
{
return "south Peer";
}
};
//-----------工厂---------------//
class Factory
{
public:
virtual Fruits* createApple() = 0;
virtual Fruits* createPeer() = 0;
};
//北方工厂
class northFactory : public Factory
{
public:
Fruits* createApple()
{
return new northApple;
}
Fruits* createPeer()
{
return new northPeer;
}
};
//南方工厂
class southFactory : public Factory
{
public:
Fruits* createApple()
{
return new southApple;
}
Fruits* createPeer()
{
return new southPeer;
}
};
//进入某水果加工厂,只能生产该水果
void func(Factory* factory)
{
//水果:父类指针指向子类对象
Fruits* apple = factory->createApple();
Fruits* peer = factory->createPeer();
cout << apple->getName() << endl;
cout << peer->getName() << endl;
}
int main()
{
//工厂:父类指针指向子类对象
func(new northFactory);
func(new southFactory);
return 0;
}
建造者模式是一种创建型模式,用来隐藏符合对象的创建过程,它把符合对象的创建过程加以抽象,可以通过子类继承和重载的方式动态地创建具有符合属性的对象
建造者模式的角色:
需求分析:
房子类House:安装门、安装墙、安装地板
设计师类Designer:选择建造方式Builder,设计房子
建造类Builder:创造门、创造墙、创造地板、创建房子
普通建造师类CommBuilder:继承Builder
别墅建造师类VillaBuilder:继承Builder
#include
#include
using namespace std;
//-------------------房子--------------------//
class House
{
public:
void setDoor(string door)
{
m_door = door;
}
void setWall(string wall)
{
m_wall = wall;
}
void setFloor(string floor)
{
m_floor = floor;
}
private:
string m_door;
string m_wall;
string m_floor;
};
//-------------------设计--------------------//
class Designer
{
public:
void func_create(Builder* builder)
{
m_build = builder;
m_build->createDoor();
m_build->createFloor();
m_build->createWall();
m_house = m_build->getHouse();
}
House* getHouseDesigner()
{
return m_house;
}
private:
Builder* m_build;
House* m_house;
};
//-------------------建造--------------------//
class Builder
{
public:
virtual void createDoor() = 0;
virtual void createWall() = 0;
virtual void createFloor() = 0;
virtual House* getHouse() = 0;
};
class CommBuilder : public Builder
{
public:
CommBuilder()
{
m_house = new House;
}
virtual void createDoor()
{
m_house->setDoor("普通的门");
cout << "创建了普通的门" << endl;
}
virtual void createWall()
{
m_house->setDoor("普通的墙");
cout << "创建了普通的墙" << endl;
}
virtual void createFloor()
{
m_house->setDoor("普通的地板");
cout << "创建了普通的地板" << endl;
}
House* getHouse()
{
return m_house;
}
private:
House* m_house;
};
class VillaBuilder : public Builder
{
public:
VillaBuilder()
{
m_house = new House;
}
virtual void createDoor()
{
m_house->setDoor("别墅的门");
cout << "创建了别墅的门" << endl;
}
virtual void createWall()
{
m_house->setDoor("别墅的墙");
cout << "创建了别墅的墙" << endl;
}
virtual void createFloor()
{
m_house->setDoor("别墅的地板");
cout << "创建了别墅的地板" << endl;
}
House* getHouse()
{
return m_house;
}
private:
House* m_house;
};
int main()
{
Designer* d = new Designer;
//Builder* cb = new CommBuilder;
Builder* cb = new VillaBuilder;
d->func_create(cb);
House* h = cb->getHouse();
return 0;
}
工厂模式&建造者模式:
工厂模式不考虑对象的组装过程,最终直接生成一个想要的对象
工厂模式解决的问题是工厂生产产品
建造者模式是先具体实现对象的每一个部件,最后把部件组装成一个对象
建造者模式解决的问题是工厂控制产品生成器组装各个部件的过程,然后从产品生成器中得到产品
代理模式可以为其他对象提供一种代理以控制对这个对象的访问。
代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。
代理模式的角色:
需求分析:
店类Shop:抽象角色
书店类BookShop:真实角色,可以卖书,书店给了代理权给淘宝店
淘宝店类Taobao:代理角色,可以做营销(打折),然后卖书
#include
using namespace std;
class Shop
{
public:
virtual void sell() = 0;
private:
};
class BookShop : public Shop
{
public:
virtual void sell()
{
cout << "卖书" << endl;
}
private:
};
class Taobao : public Shop
{
public:
Taobao(Shop *bs) //淘宝是书店的代理
{
m_bs = bs;
}
virtual void sell()
{
discount();
cout << "让书店发货" << endl;
m_bs->sell();
}
void discount()
{
cout << "打折" << endl;
}
private:
Shop *m_bs;
};
int main()
{
Shop *pb = new BookShop;
cout << "-------------书店卖书---------" << endl;
pb->sell();
Shop* pt = new Taobao(pb);
cout << "------------淘宝店卖书---------" << endl;
pt->sell();
return 0;
}
适合于:
为其他对象提供一种代理以控制对这个对象的访问。
装饰模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。给基础类挂载其他功能
装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。
代理模式的角色:
需求分析:
游戏类Player:抽象构建角色
吃鸡玩家类chijiPlayer:具体构建角色,将要增加一些附加功能(会开车,会打枪)
CF玩家类CFPlayer:具体构建角色,将要增加一些附加功能(会跑步,会打枪)
玩家有枪类PlayerWithGun:玩家有了会开枪这个附加功能
玩家有车类PlayerWithCar:玩家有了开车这个附加功能
#include
using namespace std;
class Player
{
public:
virtual void play() = 0;
virtual void show() = 0;
};
class chijiPlayer : public Player
{
public:
virtual void play()
{
cout << "会拳击" << endl;
}
virtual void show()
{
cout << "吃鸡玩家" << endl;
}
private:
};
class CFPlayer : public Player
{
public:
virtual void play()
{
cout << "会跑步" << endl;
}
virtual void show()
{
cout << "穿越火线玩家" << endl;
}
private:
};
class PlayerWithGun : public Player
{
public:
PlayerWithGun(Player* play)
{
m_play = play;
}
virtual void play()
{
m_play->play();
cout << "会打枪" << endl;
}
virtual void show()
{
m_play->show();
}
private:
Player* m_play;
};
class PlayerWithCar : public Player
{
public:
PlayerWithCar(Player* play)
{
m_play = play;
}
virtual void play()
{
m_play->play();
cout << "会开车" << endl;
}
virtual void show()
{
m_play->show();
}
private:
Player* m_play;
};
int main_3()
{
cout << "--------------吃鸡--------------" << endl;
chijiPlayer* player = new chijiPlayer();
cout << "吃鸡 + 枪:" << endl;
PlayerWithGun* chijiPlayerGun = new PlayerWithGun(player);
chijiPlayerGun->play();
chijiPlayerGun->show();
cout << endl << "吃鸡 + 车:" << endl;
PlayerWithCar* chijiPlayerCar = new PlayerWithCar(player);
chijiPlayerCar->play();
chijiPlayerCar->show();
cout << endl << "吃鸡 + 枪 + 车:" << endl;
PlayerWithCar* chijiPlayerCarGun = new PlayerWithCar(chijiPlayerGun);
chijiPlayerCarGun->play();
chijiPlayerCarGun->show();
cout << endl << "--------------CF--------------" << endl;
CFPlayer* CFplayer = new CFPlayer();
cout << "CF + 枪:" << endl;
PlayerWithGun* CFPlayerGun = new PlayerWithGun(CFplayer);
CFPlayerGun->play();
CFPlayerGun->show();
cout << endl << "CF + 车:" << endl;
PlayerWithCar* CFPlayerCar = new PlayerWithCar(CFplayer);
CFPlayerCar->play();
CFPlayerCar->show();
cout << endl << "CF + 枪 + 车:" << endl;
PlayerWithCar* CFPlayerCarGun = new PlayerWithCar(CFPlayerGun);
CFPlayerCarGun->play();
CFPlayerCarGun->show();
return 0;
}
适用于:
1、需要扩展一个类的功能,或给一个类增加附加功能
2、需要动态地给一个对象增加功能,这些功能也可以动态地销毁
3、需要增加一些基本功能的排列组合以产生更多的功能
适配器模式可以改变已有类(或外部类)的接口形式。
适配器模式的角色:
需求分析:
5V类dian5V:客户所期待的,5v电压,与220v不能直接兼容
220V类dian220V:需要适配的类,输出220v电压,与5v不能直接兼容
适配器类Adapter:把源接口转换成目标接口
#include
using namespace std;
class dian5V
{
public:
void yondian()
{
cout << "输出5V电压" << endl;
}
};
class dian220V
{
public:
void yongdian()
{
cout << "输入220V电压" << endl;
}
};
class Adapter : public dian5V
{
public:
Adapter(dian220V* dian220)
{
m_dian220 = dian220;
}
void work()
{
m_dian220->yongdian();
cout << "将220V电压转换为5V" << endl;
this->yondian();
}
private:
dian220V* m_dian220;
};
int main_4()
{
dian220V* d = new dian220V;
Adapter* a = new Adapter(d);
a->work();
return 0;
}
桥接模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。
它的主要特点是把抽象与行为实现分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
桥接模式的角色:
需求分析:
引擎类Engine:抽象类
A引擎AEngine:Engine的子类
B引擎BEngine:Engine的子类
车类Car:抽象类,要通过安装引擎来实现
宝马车BWM:Car的子类,可以安装A引擎也可以安装B引擎
奔驰车Benz:Car的子类,可以安装A引擎也可以安装B引擎
#include
using namespace std;
class Engine
{
public:
virtual void installEngin() = 0;
private:
};
class AEngine : public Engine
{
public:
virtual void installEngin()
{
cout << "安装A引擎" << endl;
}
private:
};
class BEngine : public Engine
{
public:
virtual void installEngin()
{
cout << "安装B引擎" << endl;
}
private:
};
class Car
{
public:
virtual void installCar() = 0;
private:
Engine* m_engine;
};
class BMW : public Car
{
public:
BMW(Engine* engine)
{
m_engine = engine;
}
virtual void installCar()
{
m_engine->installEngin();
cout << "安装BMW的其他部件" << endl;
}
private:
Engine* m_engine;
};
class Benz : public Car
{
public:
Benz(Engine* engine)
{
m_engine = engine;
}
virtual void installCar()
{
m_engine->installEngin();
cout << "安装Benz的其他部件" << endl;
}
private:
Engine* m_engine;
};
int main()
{
AEngine* AE = new AEngine;
BEngine* BE = new BEngine;
cout << "---------------------BMW:A引擎---------------------" << endl;
BMW* bmwA = new BMW(AE);
bmwA->installCar();
cout << "---------------------BMW:B引擎---------------------" << endl;
BMW* bmwB = new BMW(BE);
bmwB->installCar();
cout << "---------------------Benz:A引擎---------------------" << endl;
Benz* benzA = new Benz(AE);
benzA->installCar();
cout << "---------------------Benz:B引擎---------------------" << endl;
Benz* benzB = new Benz(BE);
benzB->installCar();
return 0;
}
适用于:
桥接模式是将抽象部分与实现部分分离(解耦合),使它们都可以独立的变化
外观模式是由GoF提出的23种设计模式中的一种。
外观模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面
外观模式的角色:
适用于:
子系统中统一的一套接口,去批量调用子系统的接口
例如:用于游戏初始化是批量调用系统中的接口(界面初始化、通信初始化、网络初始化...)
享元模式通过与其他类似对象共享数据来减小内存占用。
享元模式的角色:
需求分析:
人类Person:抽象角色【年龄,姓名】
老师类Teacher:具体的角色【id,年龄,姓名】,Person的子类
工厂老师类FactoryTeacher:通过id查找老师中是否有该人,没有此人则存入信息,有此人则输出
#include
#include
#include
使用场景:
是以共享的方式,高效的支持大量的细粒度的对象。
观察者模式中分为观察者和被观察者。当被观察者发生改变时,观察者会收到通知。
观察者模式:定义对象间的一对多的依赖关系,是关联对象中的一种同步通信手段,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。主要为了解决对象状态改变给其他对象通知的问题,其实现类似于观察者在被观察者中注册了一个回调函数。
观察者模式的角色:
需求分析:
被观察者类Subject:添加观察者、删除观察者、通知
具体被观察者类,老师类Teacher:添加观察者、删除观察者、通知
具体被观察者类,校长类Xiaozhang:添加观察者、删除观察者、通知
观察者Observer:更新状态
具体观察者类,学生类Student:更新状态
//普通观察者模式
#include
#include
#include
using namespace std;
class Observer;
class Subject
{
public:
virtual void add(Observer *o) = 0;
virtual void remove(Observer* o) = 0;
virtual void notify(string msg) = 0;
protected:
list m_list;
};
class Observer
{
public:
virtual void update(string msg) = 0;
virtual void subscribe(Subject* s) = 0;
virtual void disSub(Subject* s) = 0;
protected:
string name;
};
class Teacher : public Subject
{
public:
Teacher()
{
m_list.clear();
}
virtual void add(Observer* o)
{
m_list.push_back(o);
}
virtual void remove(Observer* o)
{
m_list.remove(o);
}
virtual void notify(string msg)
{
list::iterator it = m_list.begin();
while (it != m_list.end() )
{
(*it)->update(msg);
it++;
}
}
private:
};
class Xiaozhang : public Subject
{
public:
Xiaozhang()
{
m_list.clear();
}
virtual void add(Observer* o)
{
m_list.push_back(o);
}
virtual void remove(Observer* o)
{
m_list.remove(o);
}
virtual void notify(string msg)
{
list::iterator it = m_list.begin();
while (it != m_list.end())
{
(*it)->update(msg);
it++;
}
}
private:
};
class Student : public Observer
{
public:
Student()
{
name = "";
}
Student(string name)
{
this->name = name;
}
virtual void update(string msg)
{
if (msg == "老师来了")
{
cout << name << "收起手机" << endl;
}
else if (msg == "老师走了")
{
cout << name << "掏出手机" << endl;
}
else if (msg == "校长来了")
{
cout << name << "没收手机" << endl;
}
else if (msg == "校长走了")
{
cout << name << "归还手机" << endl;
}
}
};
int main()
{
//创建学生
Student* s1 = new Student("wang");
Student* s2 = new Student("Li ");
Student* s3 = new Student("Xie ");
Student* s4 = new Student("Liu ");
Student* s5 = new Student("Zhao");
//创建老师
Teacher* t = new Teacher;
//老师在观察者列表中添加学生
t->add(s1);
t->add(s2);
t->add(s3);
t->add(s4);
t->add(s5);
//老师发布通知
t->notify("老师来了");
system("pause");
t->notify("老师走了");
return 0;
}
典型应用
- 侦听事件驱动程序设计中的外部事件
- 侦听/监视某个对象的状态变化
- 发布者/订阅者模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者
适用于:
定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。
上升为发布者/订阅者模型:
发布者/订阅者模型的角色:
#include
#include
#include
using namespace std;
class Observer;
class Subject
{
public:
virtual void add(Observer *o) = 0;
virtual void remove(Observer* o) = 0;
virtual void notify(string msg) = 0;
protected:
list m_list;
};
class Observer
{
public:
virtual void update(string msg) = 0;
virtual void subscribe(Subject* s) = 0;
virtual void disSub(Subject* s) = 0;
protected:
string name;
};
class Teacher : public Subject
{
public:
Teacher()
{
m_list.clear();
}
virtual void add(Observer* o)
{
m_list.push_back(o);
}
virtual void remove(Observer* o)
{
m_list.remove(o);
}
virtual void notify(string msg)
{
list::iterator it = m_list.begin();
while (it != m_list.end() )
{
(*it)->update(msg);
it++;
}
}
private:
};
class Xiaozhang : public Subject
{
public:
Xiaozhang()
{
m_list.clear();
}
virtual void add(Observer* o)
{
m_list.push_back(o);
}
virtual void remove(Observer* o)
{
m_list.remove(o);
}
virtual void notify(string msg)
{
list::iterator it = m_list.begin();
while (it != m_list.end())
{
(*it)->update(msg);
it++;
}
}
private:
};
class Student : public Observer
{
public:
Student()
{
name = "";
}
Student(string name)
{
this->name = name;
}
virtual void update(string msg)
{
if (msg == "老师来了")
{
cout << name << "收起手机" << endl;
}
else if (msg == "老师走了")
{
cout << name << "掏出手机" << endl;
}
else if (msg == "校长来了")
{
cout << name << "没收手机" << endl;
}
else if (msg == "校长走了")
{
cout << name << "归还手机" << endl;
}
}
virtual void subscribe(Subject* s)
{
s->add(this);
}
virtual void disSub(Subject* s)
{
s->remove(this);
}
};
class Director : public Observer
{
public:
virtual void update(string msg)
{
if (msg == "老师来了")
{
cout << "所有老师开会" << endl;
}
else if (msg == "老师走了")
{
cout << "所有老师散会" << endl;
}
}
virtual void subscribe(Subject* s)
{
s->add(this);
}
virtual void disSub(Subject* s)
{
s->remove(this);
}
};
int main()
{
//创建学生(观察者)
Student* s1 = new Student("wang");
Student* s2 = new Student("Li ");
Student* s3 = new Student("Xie ");
Student* s4 = new Student("Liu ");
Student* s5 = new Student("Zhao");
//创建主任(观察者)
Director* derector = new Director;
//创建老师
Teacher* t = new Teacher;
//创建校长
Xiaozhang* xz = new Xiaozhang;
//被观察者订阅
s1->subscribe(t);
s1->subscribe(xz); //s1订阅老师和校长
s2->subscribe(t);
s3->subscribe(t);
s4->subscribe(t);
s5->subscribe(t);
derector->subscribe(t); //主任订阅老师
//观察者发布通知
t->notify("老师来了");
xz->notify("校长来了");
system("pause");
t->notify("老师走了");
xz->notify("校长走了");
return 0;
}
单例模式在多线程下是不安全的,可能会同时创建多个实例,因此为了保证单例模式在多线程下是安全的,有以下几种方式:
装饰模式:一种用于代替继承的技术,无需通过继承就可以增加子类的扩展功能。把对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀
单例模式:一种常见的软件设计模式,该类负责创建自己的对象,同时确保只有单个对象被创建,整个类提供了一种访问其唯一的对象的方法,可以直接访问,不需要实例化该类的对象