我的理解是:
- 单例模式和工厂模式都是在对
对象的构造
上下功夫。 - 代理模式、装饰器模式、适配器模式 都是对
原有类的重构
,通过继承公共基类,并添加对应类的成员变量。 - 观察者模式(行为型模式),主要关注的是对象之间的通信。
1. 单例模式(懒汉和饿汉)
一个类不管创建多少次对象,用于只会得到该类型一个对象的示例,比如:日志模块;数据库模块;
class Singleton
{
public :
static Singleton &getInstance()
{
static Singleton instance ;
return instance ;
}
private :
Singleton() {} ; # 构造函数私有化
~Singleton() {} ;
Singleton (const Singleton&) = delete ;
Singleton & operator = (const Singleton &) = delete ;
}
2. 工厂模式(简单工厂、工厂方法、抽象工厂):
将对象具体的实例化细节封装起来
- 简单工厂:把对象的创建封装在一个接口函数里面,通过传入不同的标识,返回创建的对象。 但是不符合软件设计的 [ 开-闭 ] 原则 ,也就是说需要频繁的在 SimpleFactory 中进行修改
class Car
{
public :
Car(const string &name) : _name(name) {}
virtual void show() = 0 ;
protected :
string _name ;
} ;
class BMW : public Car
{
public :
BMW(const string &name) : Car(name) {}
void show()
{
cout << "获取一辆宝马汽车" << endl ;
}
} ;
class AUDI : public Car
{
public :
AUDI(const string &name) : Car(name) {}
void show()
{
cout << "获取一辆奥迪汽车" << endl ;
}
} ;
// 简单工厂
enum CarType{ bmw , audi } ;
class SimpleFactory
{
public :
Car* createCar(CarType ct)
{
switch (ct)
{
case bmw :
return new BMW("X1") ;
case audi :
return new AUDI("A6") ;
default:
cerr << "传入工厂的参数不正确: " << ct << endl ;
break;
}
}
} ;
int main()
{
// 这是已往的做法,C++ 多态
// Car *p1 = new BMW("X1") ;
// Car *p2 = new AUDI("A6") ;
// 简单工厂
SimpleFactory *factory = new SimpleFactory() ;
Car *p1 = factory->createCar(bmw) ;
Car *p2 = factory->createCar(audi) ;
p1->show() ;
p2->show() ;
delete p1 ;
delete p2 ;
delete factory ;
return 0 ;
}
- 工厂方法:提供了一个纯虚函数(创建产品),定义派生类(具体产品的工厂)负责创建对应的产品;但是很多产品是有关联关系的,属于一个产品簇,不应该放在不同的工厂里创建,会导致工程类增多不好维护;另外也不符合实际逻辑
// 工厂方法
class Factory
{
public :
virtual Car* createCar(const string& name) = 0 ;
};
// 宝马工厂
class BMWFactory : public Factory
{
public :
Car* createCar(const string& name)
{
return new BMW(name) ;
}
} ;
// 奥迪工厂
class AUDIFactory : public Factory
{
public :
Car* createCar(const string& name)
{
return new AUDI(name) ;
}
} ;
int main()
{
unique_ptr<Factory> bmwfactory(new BMWFactory()) ;
unique_ptr<Factory> audifactory(new AUDIFactory()) ;
unique_ptr<Car> p1(bmwfactory->createCar("X6")) ;
unique_ptr<Car> p2(audifactory->createCar("A8")) ;
p1->show() ;
p2->show() ;
return 0 ;
}
- 抽象工厂:把一个产品簇的所有产品创建的接口函数,放在一个抽象工厂里面,派生类负责创建该产品簇里面的所有产品。
// 系列产品 1
class Car
{
public :
Car(const string &name) : _name(name) {}
virtual void show() = 0 ;
protected :
string _name ;
} ;
class BMW : public Car
{
public :
BMW(const string &name) : Car(name) {}
void show()
{
cout << "获取一辆宝马汽车" << endl ;
}
} ;
class AUDI : public Car
{
public :
AUDI(const string &name) : Car(name) {}
void show()
{
cout << "获取一辆奥迪汽车" << endl ;
}
} ;
// 系列产品 2
class Light
{
public :
virtual void show() = 0 ;
} ;
class BMWLight : public Light
{
public :
void show() { cout << "BMW light" << endl ; }
};
class AUDILight : public Light
{
public :
void show() { cout << "AUDI light" << endl ; }
} ;
// 工厂方法 => 抽象工厂 (对有一组关联关系的产品簇,提供产品对象的统一创建)
class AbstractFactory
{
public :
virtual Car* createCar(const string& name) = 0 ; // 工厂方法 , 创建汽车
virtual Light* createLight() = 0 ; // 工厂方法 , 创建汽车关联的产品,车灯
};
// 宝马工厂
class BMWFactory : public AbstractFactory
{
public :
Car* createCar(const string& name)
{
return new BMW(name) ;
}
Light *createLight()
{
return new BMWLight() ;
}
} ;
// 奥迪工厂
class AUDIFactory : public AbstractFactory
{
public :
Car* createCar(const string& name)
{
return new AUDI(name) ;
}
Light *createLight()
{
return new AUDILight() ;
}
} ;
int main()
{
unique_ptr<AbstractFactory> bmwfactory(new BMWFactory()) ;
unique_ptr<AbstractFactory> audifactory(new AUDIFactory()) ;
unique_ptr<Car> p1(bmwfactory->createCar("X6")) ;
unique_ptr<Car> p2(audifactory->createCar("A8")) ;
unique_ptr<Light> l1(bmwfactory->createLight()) ;
unique_ptr<Light> l2(audifactory->createLight()) ;
p1->show() ;
p2->show() ;
l1->show() ;
l2->show() ;
return 0 ;
}
3. 代理 Proxy 模式
通过代理类控制实际对象的访问权限 (类的组合关系) ; 代理类和委托类都是继承于 VideoSite
class VideoSite
{
public :
virtual void freeMovie() = 0 ;
virtual void vipMovie() = 0 ;
virtual void ticketMovie() = 0 ;
} ;
// 委托类
class FixBugVideoSite : public VideoSite
{
public :
virtual void freeMovie()
{
cout << "观看免费电影" << endl ;
}
virtual void vipMovie()
{
cout << "观看 VIP 电影" << endl ;
}
virtual void ticketMovie()
{
cout << "用券观看电影" << endl ;
}
} ;
// 代理类 代理 FixBugVideoSite
class FreeVideoSiteProxy : public VideoSite
{
public :
FreeVideoSiteProxy() { pVideo = new FixBugVideoSite() ; }
~FreeVideoSiteProxy() { delete pVideo ; }
virtual void freeMovie()
{
pVideo->freeMovie() ; // 通过代理对象的 freeMovie ,来访问真正委托类的 freeMovie() ;
}
virtual void vipMovie()
{
cout << "您目前只是普通游客, 需要升级成 VIP , 才能观看 VIP 电影" << endl ;
}
virtual void ticketMovie()
{
cout << "您目前没有券, 需要购买电影券,才可以观看电影" << endl ;
}
private :
VideoSite *pVideo ;
} ;
// 代理类 代理 FixBugVideoSite
class VipVideoSiteProxy : public VideoSite
{
public :
VipVideoSiteProxy() { pVideo = new FixBugVideoSite() ; }
~VipVideoSiteProxy() { delete pVideo ; }
virtual void freeMovie()
{
pVideo->freeMovie() ; // 通过代理对象的 freeMovie ,来访问真正委托类的 freeMovie() ;
}
virtual void vipMovie()
{
pVideo->vipMovie() ;
}
virtual void ticketMovie()
{
cout << "您目前没有券, 需要购买电影券,才可以观看电影" << endl ;
}
private :
VideoSite *pVideo ; // 类之间进行组合: FixBugVideoSite 已经完成了全部的功能
} ;
void watchMovice(unique_ptr<VideoSite> &ptr)
{
ptr->freeMovie() ;
ptr->vipMovie() ;
ptr->ticketMovie() ;
}
int main()
{
unique_ptr<VideoSite> p1(new FreeVideoSiteProxy()) ; // 用户智能访问代理对象
unique_ptr<VideoSite> p2(new VipVideoSiteProxy()) ;
watchMovice(p1) ;
watchMovice(p2) ;
return 0 ;
}
4. 装饰器模式:主要是增加现有类的功能
// 装饰器模式
class Car
{
public :
virtual void show() = 0 ;
} ;
class BMW : public Car
{
public :
void show ()
{
cout << "这是辆宝马汽车,配置有:基类" << endl ;
}
} ;
class AUDI : public Car
{
public :
void show ()
{
cout << "这是辆奥迪汽车,配置有:基类" << endl ;
}
} ;
// 装饰器1 定速巡航 都是通过继承父类 Car ,并且构造函数需要定义成员变量接受上传过来的 类对象
class ConcreteDecorator01 : public Car
{
public :
ConcreteDecorator01(Car *p) : pCar(p) {}
void show()
{
pCar->show() ;
cout << ", 定速巡航" << endl ;
}
private :
Car *pCar ;
} ;
// 装饰器2 自动刹车
class ConcreteDecorator02 : public Car
{
public :
ConcreteDecorator02(Car *p) : pCar(p) {}
void show()
{
pCar->show() ;
cout << ", 自动刹车" << endl ; // 调用对应的函数
}
private :
Car *pCar ;
} ;
int main()
{
unique_ptr<Car> p1 (new ConcreteDecorator01(new BMW())) ;
unique_ptr<Car> p2 (new ConcreteDecorator02(new AUDI())) ;
unique_ptr<Car> p3 (new ConcreteDecorator02(p1.get())) ;
p1->show() ;
p2->show() ;
p3->show() ;
return 0 ;
}
5. 适配器模式:让不兼容的接口可以在一起工作
class VGA // VGA 接口类
{
public :
virtual void play() = 0 ;
} ;
// TV01 表示支持 VGA 接口的投影仪
class TV01 : public VGA
{
public :
void play()
{
std::cout << "通过 VGA 接口连接投影仪 , 进行视频播放" << endl ;
}
} ;
// 进了一批新的投影仪,但是新的投影仪只支持 HDMI 接口
class HDMI
{
public :
virtual void play() = 0 ;
} ;
class TV02 : public HDMI
{
public :
void play()
{
std::cout << "通过 HDMI 接口连接投影仪 , 进行视频播放" << endl ;
}
} ;
// 实现一个电脑类(只支持 VGA 接口)
class Computer
{
public :
// 由于电脑只支持 VGA 接口,所以该方法的参数也只能支持 VGA 接口的指针/引用
void playVideo(VGA *pVGA)
{
pVGA->play() ;
}
} ;
/*
方法1 : 换一个支持 HDMI 接口的电脑,代码重构
方法2 : 买一个转换头,将 VGA 信号转化成 HDMI 信号, 添加适配器类
*/
class VGAToHDMIAdapter : public VGA
{
public :
VGAToHDMIAdapter(HDMI *p) : pHDMI(p) {}
void play() // 该方法就相当于转换头,做不同接口的信号转换
{
pHDMI->play() ;
}
private:
HDMI *pHDMI ;
};
int main()
{
Computer computer ;
computer.playVideo(new TV01()) ;
// 直接传入 TV02 是不行的,因为 computer 只支持 VGA 接口
// computer.playVideo(new TV02()) ;
// 故添加一个适配器类,重写对应的方法
computer.playVideo(new VGAToHDMIAdapter(new TV02()) ) ;
return 0 ;
}
6. 观察者模式(发布-订阅模式):
行为型模式,主要关注的是对象之间的通信。当一个对象的状态发生改变时,其他对象都会接收到相应的通知。
// 观察者抽象类
class Observer
{
public :
// 处理消息的接口
virtual void handle(int msgid) = 0 ;
} ;
// 第一个观察者实例
class Obsever1 : public Observer
{
public :
void handle(int msgid)
{
switch (msgid)
{
case 1:
cout << "Observer1 recv 1 msg " << endl ;
break;
case 2:
cout << "Observer1 recv 2 msg " << endl ;
break;
case 3:
cout << "Observer1 recv 3 msg " << endl ;
break;
default:
break;
}
}
};
// 第二个观察者实例
class Obsever2 : public Observer
{
public :
void handle(int msgid)
{
switch (msgid)
{
case 2:
cout << "Observer2 recv 2 msg " << endl ;
break;
case 3:
cout << "Observer2 recv 3 msg " << endl ;
break;
default:
break;
}
}
};
// 第三个观察者实例
class Obsever3 : public Observer
{
public :
void handle(int msgid)
{
switch (msgid)
{
case 3:
cout << "Observer3 recv 3 msg " << endl ;
break;
default:
break;
}
}
};
// 主题类
class Subject
{
public :
// 给主题增加观察者对象
void addObserver(Observer *obser , int msgid)
{
_subMap[msgid].push_back(obser) ;
}
// 主题检测发生改变,通知相应的观察者对象处理事件
void dispatch(int msgid)
{
auto it = _subMap.find(msgid) ;
if(it != _subMap.end()){
for (Observer *pObser : it->second)
{
pObser->handle(msgid) ;
}
}
}
private :
unordered_map<int , list<Observer* >> _subMap ;
} ;
int main()
{
Subject subject ;
Observer *p1 = new Obsever1() ;
Observer *p2 = new Obsever2() ;
Observer *p3 = new Obsever3() ;
subject.addObserver(p1 , 1) ;
subject.addObserver(p1 , 2) ;
subject.addObserver(p1 , 3) ;
subject.addObserver(p2 , 2) ;
subject.addObserver(p3 , 3) ;
int msgid = 0 ;
for(;;)
{
cout << "输入消息 msgid : " ;
cin>>msgid ;
if(msgid == -1) break ;
subject.dispatch(msgid) ;
}
return 0 ;
}
参考文献:
1.C++设计模式 - 单例模式
2.C++设计模式 - 简单工厂,工厂方法和抽象工厂
3.C++设计模式 - 迭代器模式
4.C++设计模式 - 观察者Observer模式