一、依赖倒置原则
定义:1、高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
2、抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
二、开发封闭原则
定义:对扩展开放,对修改关闭。
三、单一职责原则
定义:一个类应该仅有一个引起它变化的原因。
四、里氏替换原则
定义:子类必须能够替换它们的父类。
五、接口隔离原则
定义:不应该强迫客户程序依赖它们不用的方法
六、优先使用对象组合,而不是类继承
七、迪米特法则也叫最少知识原则
定义:如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用,如果一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
c++之简单工厂模式
简单工厂模式定义
它又被叫做静态工厂方法模式,是由一个工厂对象去决定创建出哪一种产品类的实例,
在工厂模式家族中,是最简单但是很实用的模式,
优缺点
优点:根据客户的需要,去动态实例化相关的类,去除了客户对具体产品的依赖。
缺点:每次增加新的功能,就需要去修改现有工厂代码,违反了“开闭原则”。
代码实现
首先需要提供一个抽象产品类,和具体产品的实现类。并需要一个生产的工厂类。
以下以生产酒为场景,介绍简单工厂模式的代码实现。
#include <iostream>
using namespace std;
//酒的抽象接口
class IWine
{
public:
virtual ~IWine(){}
virtual void createWine() = 0;
};
//啤酒
class Beer :public IWine
{
public:
void createWine()
{
cout << "生产啤酒" << endl;
}
};
//白酒
class Spirit :public IWine
{
public:
void createWine()
{
cout << "生产白酒" << endl;
}
};
//红酒
class RedWine :public IWine
{
public:
void createWine()
{
cout << "生产红酒" << endl;
}
};
//酒工厂 简单工厂模式
class ProducWineFactory
{
public:
ProducWineFactory(){}
~ProducWineFactory()
{
if (wine)
{
delete wine;
wine = nullptr;
}
}
IWine * createWine(char type)
{
switch (type)
{
case 'B': //啤酒
{
wine = new Beer;
}
break;
case 'S': //白酒
{
wine = new Spirit;
}
break;
case 'R': //红酒
{
wine = new RedWine;
}
break;
default:
break;
}
return wine;
}
private:
IWine *wine = nullptr;
};
int main() //客户端
{
ProducWineFactory wineFactoty;
IWine *pwine = wineFactoty.createWine('R');
if (pwine)
{
pwine->createWine();
}
return 0;
}
c++之抽象工厂模式
象工厂模式和工厂方法模式类似,因此也被称为工厂家族模式,属于创建型设计模式。
定义:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类。
以下的例子说明:
市场上有神奇公司和希望公司,他们同时可以生产鼠标和电池,但是两个公司的鼠标和电池型号却是不一样的。
IMouseProduct(抽象鼠标产品)
IBatteryProduct(抽象电池产品)
MagicBattery(神奇公司具体电池产品)
MagicMouse(神奇公司具体鼠标产品)
HopeBattery(希望公司具体电池产品)
HopeMouse(希望公司具体鼠标产品)
IFactory(抽象工厂)
MagicFactory(神奇公司工厂-生产神奇鼠标和电池)
HopeFactory(希望公司工厂-生产希望鼠标和电池)
代码:
#include <iostream>
using namespace std;
//抽象鼠标
class IMouseProduct{
public:
virtual void createMouse() = 0;
};
//抽象电池
class IBatteryProduct{
public:
virtual void createBattery() = 0;
};
//神奇公司电池
class MagicBattery :public IBatteryProduct
{
public:
virtual void createBattery(){
cout << "生产神奇电池" << endl;
}
};
//神奇公司鼠标
class MagicMouse :public IMouseProduct
{
public:
virtual void createMouse(){
cout << "生产神奇鼠标" << endl;
}
};
//希望公司电池
class HopeBattery :public IBatteryProduct
{
public:
virtual void createBattery(){
cout << "生产希望电池" << endl;
}
};
//希望公司鼠标
class HopeMouse :public IMouseProduct
{
public:
virtual void createMouse(){
cout << "生产希望鼠标" << endl;
}
};
//抽象工厂
class IFactory
{
public:
virtual IMouseProduct *createMouseProuct() = 0;
virtual IBatteryProduct *createBatteryProduct() = 0;
};
//神奇工厂 生产鼠标和键盘
class MagicFactory :public IFactory
{
public:
virtual IMouseProduct *createMouseProuct()
{
return new MagicMouse;
}
virtual IBatteryProduct *createBatteryProduct()
{
return new MagicBattery;
}
};
//希望工厂 生产鼠标和键盘
class HopeFactory :public IFactory
{
public:
virtual IMouseProduct *createMouseProuct()
{
return new HopeMouse;
}
virtual IBatteryProduct *createBatteryProduct()
{
return new HopeBattery;
}
};
//客户端
int main()
{
//神奇工厂
//IFactory *fac = new MagicFactory;
//希望工厂
IFactory *fac = new HopeFactory;
if (fac)
{
fac->createBatteryProduct()->createBattery();
fac->createMouseProuct()->createMouse();
delete fac;
fac = nullptr;
}
return 0;
}
可以看到在客户端中,只需要实例化对应的具体工厂对象给IFactory即可生产不同的产品,不需要改变其他的代码。
c++之策略模式
策略模式是行为型模式,它是一种定义一系列算法的方法,所有的这些算法完成的都是相同的工作,只是实现不同。所以可以用相同的方式去调用所有的算法,降低了算法类与使用算法的类之间的耦合度。
代码:
#include <iostream>
using namespace std;
/*
策略模式
*/
//抽象算法
class ConnectDevice
{
public:
virtual void connect() = 0;
};
//tcp连接
class TcpConnect :public ConnectDevice
{
public:
virtual void connect()
{
cout << "Tcp连接" << endl;
}
};
//RS232连接
class RsConnect :public ConnectDevice
{
public:
virtual void connect()
{
cout << "rs232连接" << endl;
}
};
//串口连接
class UartConnect :public ConnectDevice
{
public:
virtual void connect()
{
cout << "串口连接" << endl;
}
};
//维护具体算法
class ContextConnect{
public:
void ContextConnectFun(ConnectDevice *con)
{
if (con)
{
con->connect();
}
}
};
//客户端
int main()
{
ContextConnect *context = new ContextConnect;
if (context)
{
//由实例化不同的策略,调用不同的算法
ConnectDevice *con = nullptr;
con = new TcpConnect();
context->ContextConnectFun(con);
con = new RsConnect();
context->ContextConnectFun(con);
con = new UartConnect();
context->ContextConnectFun(con);
delete context;
context = nullptr;
if (con)
{
delete con;
con = nullptr;
}
}
return 0;
}
c++之观察者模式
观察者模式属于行为型模式,即当对象间存在一对多关系时,则考虑使用观察者模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。
栗子场景:课堂上,李老师(具体通知者)叫小明(具体观察者)和大红(具体观察者)坐下,然后再单独叫小明站起来。
代码:
#include <iostream>
#include <list>
using namespace std;
//抽象观察者
class Observer{
public:
virtual void update(std::string) = 0;
};
//具体观察者小明
class ConcreateObserverXiaoMing :public Observer
{
public:
virtual void update(std::string s)
{
cout << "XiaoMing"<< s.c_str() << endl;
}
};
//具体观察者大红
class ConcreateObserverDaHong :public Observer
{
public:
virtual void update(std::string s)
{
cout << "DaHong " << s.c_str() << endl;
}
};
//抽象通知者
class Subject{
public:
virtual void Attach(Observer *ob) = 0;
virtual void Detach(Observer *ob) = 0;
virtual void Notify() = 0;
};
//具体通知者 李老师
class ConcreateSubjectLiLaoshi :public Subject
{
public:
//增加观察者
virtual void Attach(Observer *ob)
{
if (ob != nullptr)
{
m_observer.push_back(ob);
}
}
//移除观察者
virtual void Detach(Observer *ob)
{
if (ob != nullptr)
{
m_observer.remove(ob);
}
}
//通知
virtual void Notify()
{
//list<Observer*>::iterator iter = m_observer.begin();
auto iter = m_observer.begin();
for (; iter != m_observer.end(); iter++)
{
(*iter)->update(m_staus);
}
}
void setStatus(std::string s)
{
m_staus = s;
}
private:
list<Observer*> m_observer;
std::string m_staus;
};
int main()
{
ConcreateSubjectLiLaoshi conSub;
ConcreateObserverXiaoMing xiaoMing;
ConcreateObserverDaHong daHong;
conSub.Attach(&xiaoMing);
conSub.Attach(&daHong);
conSub.setStatus("坐下");
conSub.Notify();
conSub.Detach(&daHong);
conSub.setStatus("站起来");
conSub.Notify();
return 0;
}
c++之外观模式
外观模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
定义:为子系统中的一组接口提供一个一致的接口,使得这些子系统更加容易被使用
栗子场景:最近股市特别火,小王也尝试着去买卖一下股票,试一下当操盘手的感觉
代码:
#include <iostream>
using namespace std;
//股票A
class SharesA{
public:
void buySharesA()
{
cout << "股票A买入" << endl;
}
void sellSharesA()
{
cout << "股票A卖出" << endl;
}
};
//股票B
class SharesB{
public:
void buySharesB()
{
cout << "股票B买入" << endl;
}
void sellSharesB()
{
cout << "股票B卖出" << endl;
}
};
//股票C
class SharesC{
public:
void buySharesC()
{
cout << "股票C买入" << endl;
}
void sellSharesC()
{
cout << "股票C卖出" << endl;
}
};
//外观类--小王
class XiaoWangFacade{
public:
//买入股票的组合1
void buyMethodOne()
{
a.buySharesA();
b.buySharesB();
}
void sellMethodOne()
{
a.sellSharesA();
b.sellSharesB();
}
//买入股票的组合2
void buymethodTwo()
{
b.buySharesB();
c.buySharesC();
}
void sellMethodTwo()
{
b.sellSharesB();
c.sellSharesC();
}
private:
SharesA a;
SharesB b;
SharesC c;
};
//客户端
int main()
{
XiaoWangFacade xmf;
//小王买入一组股票A与B
xmf.buyMethodOne();
//小王卖出一组股票A与B
xmf.sellMethodOne();
//小王买入一组股票B和C
xmf.buymethodTwo();
//小王卖出一组股票B和C
xmf.sellMethodTwo();
return 0;
}
小王这几天买卖股票,在牛市里追涨杀跌,结果还是亏损了1000块钱
c++之状态模式
状态模式
定义:当一个对象的内在状态改变时,允许改变它的行为,这个对象看起来像是改变了其类。
它属于行为型模式
栗子场景:一天根据当前的时间段,来决定一个人是吃早饭还是午饭以及晚饭。即根据时间的状态变化,改变人吃什么的行为。
代码:
#include <iostream>
#include <Windows.h>
using namespace std;
class Eat;
class MealStatus
{
public:
virtual void doEat(Eat *eat) = 0;
};
class Eat{
public:
Eat(MealStatus *m) :m_status(nullptr)
{
m_status = m;
}
~Eat()
{
if (m_status)
{
delete m_status;
m_status = nullptr;
}
}
void request()
{
m_status->doEat(this);
}
void setStatus(MealStatus* s)
{
m_status = s;
}
void setHour(int h)
{
m_hour = h;
}
int getHour()
{
return m_hour;
}
private:
MealStatus* m_status;
int m_hour;
};
//夜宵
class NightSnack :public MealStatus
{
public:
NightSnack(){}
void doEat(Eat *eat)
{
cout << "吃夜宵时间段来了,吃货的一天准备结束啦" << " current-time=" << eat->getHour() << endl;
}
};
//晚餐
class Dinner :public MealStatus
{
public:
Dinner(){}
void doEat(Eat *eat)
{
if (eat->getHour() < 21)
{
cout << "吃晚饭时间段" << " current-time=" << eat->getHour() << endl;
}
else
{
eat->setStatus(new NightSnack);
eat->request();
}
}
};
//午餐
class Lunch :public MealStatus
{
public:
Lunch(){}
void doEat(Eat *eat)
{
if (eat->getHour()<14)
{
cout << "吃午饭时间段" << " current-time="<<eat->getHour()<<endl;
}
else
{
eat->setStatus(new Dinner);
eat->request();
}
}
};
//早餐
class Breakfast :public MealStatus
{
public:
Breakfast(){}
void doEat(Eat *eat)
{
if (eat->getHour() < 9)
{
cout << "吃早饭时间段" << " current-time=" << eat->getHour()<< endl;
}
else
{
eat->setStatus(new Lunch);
eat->request();
}
}
};
int main()
{
Eat *eat = new Eat(new Breakfast);
//切换状态
eat->setHour(8);
eat->request();
eat->setHour(13);
eat->request();
eat->setHour(20);
eat->request();
eat->setHour(24);
eat->request();
if (eat)
{
delete eat;
eat = nullptr;
}
return 0;
}
c++之原型模式
原型模式
定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
它属于创建者模式,其实就是通过一个对象再创建另外一个对象的副本,但是不需要知道任何创建对象所需要的细节。
优点:
1、当一个对象经过一段时间后,它内部的状态已经发生了变化,这时候,程序的其他业务需要当前状态下 的对象去进行其他的操作。这时候如果直接在new一个新的对象出来,它的状态就对应不上了。这时候采用原型模式,就可以获取一个状态一致的对象。
2、有时候创建对象时,构造函数需要的参数却很多,但是我们又不完全的知道每个参数的具体含义,就可以使用原型模式来创建一个新的对象,从而不必去理会创建的过程。
3、恰当的使用原型模式,可以减少代码量,提高程序的效率。
代码:
#include <iostream>
using namespace std;
//原型
class Prototype
{
public:
Prototype(int n) :m_num(0)
{
m_num = n;
}
int getNum()
{
return m_num;
}
virtual Prototype* clone() = 0;
private:
int m_num;
};
//具体原型实例A
class PrototypeA :public Prototype
{
public:
PrototypeA(int num) :Prototype(num)
{
}
Prototype* clone()
{
return new PrototypeA(*this);
}
};
//具体原型实例B
class PrototypeB :public Prototype
{
public:
PrototypeB(int num) :Prototype(num)
{
}
Prototype* clone()
{
return new PrototypeB(*this);
}
};
//客户端
int main()
{
PrototypeA *proA = new PrototypeA(10);
cout << "proA-num=" << proA->getNum() << " 对象&=" << proA << endl;
PrototypeA *newproA = static_cast<PrototypeA*>(proA->clone());
cout << "newproA-num=" << newproA->getNum() <<" 对象&="<< newproA << endl;
PrototypeB *newproB = static_cast<PrototypeB*>(proA->clone());
cout << "newproB-num=" << newproB->getNum() << " 对象&=" << newproB << endl;
if (proA)
{
delete proA;
proA = nullptr;
}
if (newproA)
{
delete newproA;
newproA = nullptr;
}
if (newproB)
{
delete newproB;
newproB = nullptr;
}
return 0;
}
c++之适配器模式
定义:将一个类的接口转换为用户希望的另外一个接口,使得原本因为接口不兼容而不能一起工作的类能在一起工作。
它属于结构型模式,
代码:
#include <iostream>
using namespace std;
//客户需要的接口类 即对外提供的类
class IProvide
{
public:
virtual void Connect() = 0;
};
//需要适配的类
class Tcp{
public:
void tcpConnect()
{
cout << "tcp连接" << endl;
}
};
//适配类
class Adapter :public IProvide
{
public:
Adapter() :m_tcp(nullptr)
{
m_tcp = new Tcp;
}
//对外提供的接口
void Connect(){
//实际调用的接口
m_tcp->tcpConnect();
}
private:
Tcp *m_tcp;
};
//客户端
int main()
{
IProvide *p = new Adapter;
p->Connect();
if (p)
{
delete p;
p = nullptr;
}
return 0;
}
c++之享元模式
享元模式属于结构型模式。
定义:运用共享技术有效地支持大量细粒度的对象。
优点:减少单个实例的数目,来避免相似类的开销。
主要用于减少创建对象的数量,以减少内存的占用消耗和提高软件性能。
享元模式尝试重用现有的对象,如果没有找到,才会创建新的对象。
因为我们知道,对象是占据一定内存的,即使是一个空类,在c++中也占据1个字节的大小。
重复利用可以减少浪费,还能维护上一次的状态。
享元模式主要使用场景:
1、在设计之初,考虑到当系统中可能有很多对象的时候
2、这些对象还很占内存、操作重复
怎么使用:
一般会建立对应的关系表,维护已经创建的对象,通过创建对象时给他们的唯一标识,
从而通过标识从关系表中再次取出。
栗子场景:人在江湖飘,哪有不挨刀,加入一个门派接受保护成为了武林人士的首选。
其中Sects对应Flyweight,concreteSects对应concreateFlyweight,SectsFactory对应FlyweightFactory。
#include <iostream>
#include <map>
using namespace std;
//侠客类
class KnightErrant
{
public:
KnightErrant(string n) :m_name("")
{
m_name = n;
}
string getName()
{
return m_name;
}
private:
string m_name; //侠客的名字
};
//抽象门派
class Sects{
public:
virtual void JoinSects(KnightErrant ke) = 0;
};
//具体门派
class ConcreteSects:public Sects
{
public:
ConcreteSects(string n) :m_name("")
{
m_name = n;
}
void JoinSects(KnightErrant ke)
{
cout <<"大侠:"<< ke.getName().c_str()
<< " 加入" << m_name.c_str()<< endl;
}
private:
string m_name;
};
//享元工厂类
class SectsFactory
{
public:
~SectsFactory()
{
auto it = m_sectsMap.begin();
for (; it != m_sectsMap.end(); it++)
{
if (it->second)
{
delete it->second;
it->second = nullptr;
}
}
}
Sects* getSects(string name)
{
if (m_sectsMap.find(name) == m_sectsMap.end())
{
m_sectsMap[name] = new ConcreteSects(name);
}
return m_sectsMap[name];
}
int getSectsCount()
{
int cnt = 0;
auto it = m_sectsMap.begin();
for (; it != m_sectsMap.end(); it++)
{
cnt++;
}
return cnt;
}
private:
map<string, Sects*> m_sectsMap;
};
//客户端
int main()
{
SectsFactory *sectsFac = new SectsFactory;
Sects *sects = sectsFac->getSects("华山派");
sects->JoinSects(KnightErrant("令狐冲"));
sects->JoinSects(KnightErrant("任你行"));
sects = sectsFac->getSects("嵩山派");
sects->JoinSects(KnightErrant("鸠摩智"));
sects = sectsFac->getSects("峨眉派");
sects->JoinSects(KnightErrant("宋青书"));
cout << "当前武林门派的个数:" << sectsFac->getSectsCount() << endl;
if (sectsFac)
{
delete sectsFac;
sectsFac = nullptr;
}
return 0;
}
c++之桥接模式
定义:把抽象部分和它的实现部分分离,使得它们都可以独立的变化
栗子场景:华山派和崆峒派先后获得了武林秘籍辟邪剑谱和九阴真经,于是开始苦练此功…
UML类图
代码:
#include<iostream>
using namespace std;
class Sects;
//功夫
class Kungfu
{
public:
virtual void practice() = 0;
};
//九阴真经
class JiuyinZj :public Kungfu
{
public:
virtual void practice()
{
cout << "@九阴真经。注:玄门内功,至阴至柔" << endl;
}
};
//辟邪剑谱
class PixieJp :public Kungfu
{
public:
virtual void practice()
{
cout << "@辟邪剑谱,注:欲练此功,必先自宫" << endl;
}
};
//门派
class Sects{
public:
Sects() :m_kungfu(nullptr){}
void setMartialarts(Kungfu* m)
{
this->m_kungfu = m;
}
Kungfu* getKungfu()
{
return m_kungfu;
}
virtual void practice() = 0;
private:
Kungfu *m_kungfu; //桥接
};
//华山
class HuaShan :public Sects
{
public:
void practice()
{
getKungfu()->practice();
}
};
//崆峒
class KongTong :public Sects
{
public:
void practice()
{
getKungfu()->practice();
}
};
//客户端
int main()
{
Sects *sects = new HuaShan;
cout << "华山派弟子正在练习:" << endl;
sects->setMartialarts(new JiuyinZj);
sects->practice();
sects->setMartialarts(new PixieJp);
sects->practice();
sects = new KongTong;
cout << "崆峒派弟子正在练习:" << endl;
sects->setMartialarts(new JiuyinZj);
sects->practice();
sects->setMartialarts(new PixieJp);
sects->practice();
if (sects)
{
delete sects;
sects = nullptr;
}
return 0;
}
c++之模板方法模式
模板方法属于属于行为型模式
定义:定义一个操作中的算法骨架,将一些步骤延迟到子类中实现。
优点:使得子类可以不改变一个算法的结构,就可以重定义改算法的某些特定的步骤,将不变的行为移动到父类,用于去除子类中的重复代码,提供了一个很好的代码复用平台。
场景栗子:连接设备的分为TCP和串口连接
代码:
#include <iostream>
using namespace std;
class IConnect
{
public:
int connectDevice()
{
configArgs();
cout << "配置完毕" << endl;
if (!connect())
{
return -1;
}
cout << "连接成功" << endl;
return 0;
}
protected:
virtual void configArgs() = 0;
virtual bool connect() = 0;
};
class TcpConnect : public IConnect
{
public:
virtual void configArgs()
{
cout << "tcp连接" << endl;
}
virtual bool connect()
{
cout << "开始tcp连接" << endl;
return true;
}
};
class UartConnect : public IConnect
{
public:
virtual void configArgs()
{
cout << "串口连接" << endl;
}
virtual bool connect()
{
cout << "开始uart连接" << endl;
return true;
}
};
//客户端
int main()
{
IConnect *con = new TcpConnect;
con->connectDevice();
cout << "-----------------" << endl;
con = new UartConnect;
con->connectDevice();
if (con)
{
delete con;
con = nullptr;
}
return 0;
}
c++之命令模式
命令模式
定义:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
场景栗子:通信兵接收到司令官的命令,将这些命令发送给作战部队。
代码
#include<iostream>
#include <list>
using namespace std;
class Signalman;
class Action;
class Command
{
public:
Command(Action *action)
{
m_action = action;
}
virtual void ExecuteOrder() = 0;//执行命令
protected:
Action *m_action;
};
//行动
class Action
{
public:
void attack(string name)
{
cout << "进攻高地" << name.c_str() << endl;
}
void retreat()
{
cout << "所有队伍撤退" << endl;
}
private:
};
class AttackCommand :public Command
{
public:
AttackCommand(Action *act,string name) :Command(act){
m_name = name;
}
void ExecuteOrder(){
m_action->attack(m_name);
}
private:
string m_name;
};
class RetreatCommand :public Command
{
public:
RetreatCommand(Action *act) :Command(act){}
void ExecuteOrder(){
m_action->retreat();
}
};
//通信兵
class Signalman
{
public:
//通知军队
void noticeArmy()
{
for (Command*c : m_commandList)
{
c->ExecuteOrder();
}
}
//设置命令
void setCommand(Command* command)
{
m_commandList.push_back(command);
}
//取消命令
void cancelCommand(Command* command)
{
m_commandList.remove(command);
}
private:
list<Command*> m_commandList;
};
//客户端
int main()
{
Action *act = new Action;
Command *attack1 = new AttackCommand(act,"333");
Command *attack2 = new AttackCommand(act, "298");
Command *retreat = new RetreatCommand(act);
Signalman *man = new Signalman;
man->setCommand(attack1);
man->setCommand(attack2);
//下发进攻命令
man->noticeArmy();
cout << "----------久攻不下,损失惨重--------------" << endl;
man->cancelCommand(attack1);
man->cancelCommand(attack2);
man->setCommand(retreat);
//下发撤退命令
man->noticeArmy();
if (act){
delete act;
act = nullptr;
}
if (man){
delete man;
man = nullptr;
}
if (attack1){
delete attack1;
attack1 = nullptr;
}
if (attack2){
delete attack2;
attack2 = nullptr;
}
if (retreat){
delete retreat;
retreat = nullptr;
}
return 0;
}
c++之职责链模式
定义:使得多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着该链传递该请求,直到有一个对象处理它为止。
属于行为型模式。
代码:
#include <iostream>
using namespace std;
class Handle{
public:
void setHandle(Handle *h)
{
m_handle = h;
}
virtual void handleRequest(int score) = 0;
Handle *m_handle;
};
class ConcreteHandleA :public Handle
{
public:
void handleRequest(int score)
{
if (score < 60)
{
cout << score << " 不及格,调入普通班级" << endl;
}
else
{
if (m_handle)
m_handle->handleRequest(score);
}
}
};
class ConcreteHandleB :public Handle
{
public:
void handleRequest(int score)
{
if (score >= 60 && score<80)
{
cout << score << " 及格,调入良好班级" << endl;
}
else
{
if (m_handle)
m_handle->handleRequest(score);
}
}
};
class ConcreteHandleC :public Handle
{
public:
void handleRequest(int score)
{
if (score >= 90)
{
cout << score << " 优秀,调入尖子班" << endl;
}
}
};
//客户端
int main()
{
ConcreteHandleA *a = new ConcreteHandleA;
ConcreteHandleB *b = new ConcreteHandleB;
ConcreteHandleC *c = new ConcreteHandleC;
a->setHandle(b);
b->setHandle(c);
int stuScore[] = { 30, 10, 80, 90, 99, 75, 49 };
for (int x : stuScore)
{
a->handleRequest(x);
}
if (a)
{
delete a;
a = nullptr;
}
if (b)
{
delete b;
b = nullptr;
}
if (c)
{
delete c;
c = nullptr;
}
}
c++之迭代器模式
迭代器模式
定义:提供一种方法顺序访问一个集合对象中的元素,但是又不暴露该对象的内部显示
这里采用了类模板来定义类,强化对模板的运用。
代码:
#include <iostream>
#include <list>
#include <vector>
using namespace std;
//抽象迭代器类
template<typename T>
class Iterator
{
public:
virtual T firstItem() = 0;
virtual T nextItem() = 0;
virtual T currentItem() = 0;
virtual bool isEnd() = 0;
};
//抽象聚合类
template<typename T>
class Aggregate
{
public:
virtual int count() = 0;
virtual void pushItem(const T& str) = 0;
virtual T removeItem(const int index) = 0;
virtual Iterator<T>* createIterator() = 0;
};
//具体聚合类
template<typename T>
class ConcreteAggregate :Aggregate<T>
{
public:
ConcreteAggregate() :m_pIter(nullptr){}
~ConcreteAggregate()
{
if (m_pIter)
{
delete m_pIter;
m_pIter = nullptr;
}
}
int count()
{
return m_listItem.size();
}
void pushItem(const T& str)
{
m_listItem.push_back(str);
}
T removeItem(const int index)
{
T res;
if (index < count())
{
res = m_listItem[index];
}
return res;
}
Iterator<T>* createIterator()
{
m_pIter = new ConcreteIterator<T>(this);
return m_pIter;
}
private:
vector<T> m_listItem;
Iterator<T> *m_pIter;
};
//具体迭代器类
template<typename T>
class ConcreteIterator :public Iterator<T>
{
public:
ConcreteIterator(Aggregate<T>* pA) :m_cnt(0), m_pConcreteA(nullptr)
{
m_pConcreteA = pA;
}
T firstItem()
{
return m_pConcreteA->removeItem(0);
}
T nextItem()
{
m_cnt++;
if (m_cnt < m_pConcreteA->count())
{
return m_pConcreteA->removeItem(m_cnt);
}
return T();
}
T currentItem()
{
return m_pConcreteA->removeItem(m_cnt);
}
bool isEnd()
{
return ((m_cnt >= m_pConcreteA->count()) ? true : false);
}
private:
Aggregate<T> *m_pConcreteA;
int m_cnt;
};
//客户端
int main()
{
ConcreteAggregate<string> *p = new ConcreteAggregate < string > ;
p->pushItem("宫保鸡丁");
p->pushItem("鱼香肉丝");
p->pushItem("翡翠白菜");
p->pushItem("青椒牛肉");
Iterator<string> *it = p->createIterator();
if (it)
{
string item = it->firstItem();
cout << "胖虎今天要吃的是菜是" << endl;
while (!it->isEnd())
{
cout << it->currentItem().c_str() << endl;
it->nextItem();
}
}
cout << "====================" << endl;
ConcreteAggregate<int> *p1 = new ConcreteAggregate<int>;
p1->pushItem(999);
p1->pushItem(888);
p1->pushItem(666);
p1->pushItem(555);
Iterator<int> *pIter = p1->createIterator();
if (pIter)
{
int item = pIter->firstItem();
cout << "小明今天要学习的数字是" << endl;
while (!pIter->isEnd())
{
cout << pIter->currentItem() << endl;
pIter->nextItem();
}
}
if (p)
{
delete p;
p = nullptr;
}
if (p1)
{
delete p1;
p1 = nullptr;
}
return 0;
}
c++之建造者模式
建造者模式
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
属于创建型模式
代码:
#include <iostream>
#include <vector>
#include <iostream>
using namespace std;
//电脑产品
class Computer
{
public:
void addPart(string p)
{
m_vecParts.push_back(p);
}
void showDetails()
{
cout << "电脑建造过程:" << endl;
for (string x : m_vecParts)
{
cout << x.c_str() << endl;
}
}
private:
vector<string> m_vecParts;
};
class Builder
{
public:
virtual ~Builder(){}
virtual void buildScreen() = 0;
virtual void buildKeyboard() = 0;
virtual Computer* getComputer() = 0;
};
class ConcreteBuilderA :public Builder
{
public:
ConcreteBuilderA() :m_computer(nullptr)
{
m_computer = new Computer;
}
~ConcreteBuilderA()
{
if (m_computer)
{
delete m_computer;
m_computer = nullptr;
}
}
void buildScreen()
{
m_computer->addPart("电脑屏幕A");
}
void buildKeyboard()
{
m_computer->addPart("内设键盘A");
}
Computer* getComputer()
{
return m_computer;
}
private:
Computer *m_computer;
};
class ConcreteBuilderB :public Builder
{
public:
ConcreteBuilderB() :m_computer(nullptr)
{
m_computer = new Computer;
}
~ConcreteBuilderB()
{
if (m_computer)
{
delete m_computer;
m_computer = nullptr;
}
}
void buildScreen()
{
m_computer->addPart("电脑屏幕B");
}
void buildKeyboard()
{
m_computer->addPart("内设键盘B");
}
Computer* getComputer()
{
return m_computer;
}
private:
Computer *m_computer;
};
class Director
{
public:
void build(Builder *build)
{
build->buildScreen();
build->buildKeyboard();
}
};
//客户端
int main()
{
Director *director = new Director;
Builder *buildA = new ConcreteBuilderA;
Builder *buildB = new ConcreteBuilderB;
director->build(buildA);
Computer *computerA = buildA->getComputer();
computerA->showDetails();
director->build(buildB);
Computer *computerB = buildB->getComputer();
computerB->showDetails();
if (director)
{
delete director;
director = nullptr;
}
if (buildA)
{
delete buildA;
buildA = nullptr;
}
if (buildB)
{
delete buildB;
buildB = nullptr;
}
return 0;
}
c++之代理模式
代理模式
代理模式属于结构型模式。
定义:
代理即一个类代表另一个类的功能。
比如篮球运动员通过经纪人与老板谈薪,那么经纪人就是篮球运动员的代理。
在代理模式中,通过创建一个具有需要代理对象的代理,以便向外界提供需要的功能。
加深理解:
在某些情况下,一个类对象不适合或者不能直接引用另一个类对象,
所以可以交给代理类去完成这个中介的作用,是不是感觉和中介模式有点像。
其实中介模式和代理模式概念是比较接近,但是实际实现却是不同的。
假设有A、B、C三个类,A与B想交流,但是A却因为某种原因,不能直接和B交流
所以需要通过C来代理,而C这个代理其实只封装了A的对象。相当于C就是A的全权代表了。
这个就是代理模式。
中介模式呢,A、B想交流,但是需要通过C来牵线,在C这个类中,封装了A与B的对象。
而代理模式C只封装了A,这就是中介模式和代理模式的不同点。
在现实中,中介模式和买房卖房很像,代理模式和律师帮忙打官司很像。
类图:
应用场景:
现在苹果公司需要生产AirPods耳机,委托立讯精密代理生产。
代码:
#include <iostream>
using namespace std;
//抽象工厂
class IFactory
{
public:
virtual ~IFactory() {}
virtual void createProduct() = 0;
};
//苹果AirPods耳机工厂
class AppleAirpodsFactory :public IFactory
{
public:
void createProduct()
{
cout << "生产苹果AirPods耳机" << endl;
}
};
//立讯精密公司代理生产
class ILXCompanyProxy :public IFactory
{
public:
ILXCompanyProxy(IFactory* f) :m_factory(nullptr)
{
m_factory = f;
}
void createProduct()
{
cout << "立讯精密代理:" << endl;
m_factory->createProduct();
}
private:
IFactory* m_factory;
};
//客户端
int main()
{
IFactory* factory = new AppleAirpodsFactory;
ILXCompanyProxy* proxy = new ILXCompanyProxy(factory);
proxy->createProduct();
if (factory) delete factory;
if (proxy) delete proxy;
getchar();
return 0;
}
c++之备忘录模式
备忘录模式
定义:捕获一个对象的内部状态,并在该对象之外保存这个状态。以后就可以将该对象恢复到之前被保存的状态。
UML类图:
以上
Originator是发起者,它负责创建一个备忘录Memento,记录当前时刻它的内部状态,并可使用备忘录Memento恢复内部状态。
Memento是备忘录,负责存储Originator对象的当前状态。
Caretaker是管理者,只负责保存备忘录Memento对象,但是不能对备忘录的内容进行任何操作。
场景模拟:
以前特别喜欢玩s11Pk版,有时候玩了一段时间,发现进展和预想的不一样,上将军邢道荣被敌方抓了,但又不想重新开始,于是重新读档,回到之前的状态,继续玩。
栗子代码:
其中
类图Originator对应San11PkPlayer.
Memento对应San11PkStorage.
Caretaker对应ManageSan11PkStorage.
#include <iostream>
#include <vector>
using namespace std;
class San11PkStorage;
//备忘录角色
class San11PkStorage{
public:
San11PkStorage(std::string weather,vector<std::string> mapRoles)
{
this->m_weather = weather;
this->m_inMaproles = mapRoles;
}
//private: //为了方便,这里直接用public
public:
std::string m_weather; //天气
vector<std::string> m_inMaproles; //在地图上的角色
//...
};
//备忘录管理员角色
class ManageSan11PkStorage{
public:
void setS11(San11PkStorage *s11)
{
m_s11 = s11;
}
San11PkStorage* getS11()
{
return m_s11;
}
private:
San11PkStorage *m_s11;
};
//发起人角色
class San11PkPlayer
{
public:
//保存
San11PkStorage* saveS11Status()
{
return new San11PkStorage(m_weather, m_inMaproles);
}
//恢复
void recoveryS11Status(const San11PkStorage &s11s)
{
this->m_weather = s11s.m_weather;
this->m_inMaproles = s11s.m_inMaproles;
}
//展示数据
void showS11()
{
cout << "现在的季节是:" << m_weather.c_str() << endl;
auto iter = m_inMaproles.begin();
for (; iter != m_inMaproles.end(); iter++)
{
cout << "当前地图上的角色有:" << (*iter).c_str() << endl;
}
}
//private:
public:
std::string m_weather; //天气
vector<std::string> m_inMaproles; //在地图上的角色
};
//客户端
int main()
{
San11PkPlayer* pS11 = new San11PkPlayer;
//现在的状态
cout << "================开始玩游戏...===============" << endl;
pS11->m_weather = "冬天";
vector<std::string> vec;
vec.push_back("张辽");
vec.push_back("貂蝉");
vec.push_back("邢道荣");
pS11->m_inMaproles = vec;
pS11->showS11();
//保存当前状态
ManageSan11PkStorage *manager = new ManageSan11PkStorage;
manager->setS11(pS11->saveS11Status());
cout << "================玩了一段时间,不想玩了,读档再来===============" << endl;
vec.at(0) = "张飞";
vec.pop_back();
pS11->m_inMaproles = vec;
pS11->m_weather = "春天";
pS11->showS11();
cout << "================读档后===============" << endl;
pS11->recoveryS11Status(*manager->getS11());
pS11->showS11();
if (manager)
{
delete manager;
manager = nullptr;
}
if (pS11)
{
delete pS11;
pS11 = nullptr;
}
return 0;
}
c++之工厂方法模式
定义:
工厂方法模式属于创建型模式,用于定义一个用于创建对象的接口,让子类决定实例化哪一个类,即将实际创建工作推迟到子类当中进行。
它的核心角色有4个,分别是抽象工厂以及具体工厂,抽象产品以及具体产品。
类图:
通过类图可知,工厂方法即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,而这个具体的工厂就只负责生产对应的产品。
工厂方法模式完全符合开发封闭原则,扩展性强。
应用场景:
假设我们想生产啤酒和白酒,可以考虑新建一个啤酒工厂和一个白酒工厂,然后把这两个工厂的共同点抽象出来,即抽象工厂类
,把啤酒和白酒的共同点抽象出来,即酒类。为什么要抽象出来呢,一是便于接下来复用抽象类,可能我们后面还需要一个生产红酒,就可以让红酒类继承抽象酒类,
红酒工厂继承抽象工厂类,可以减少相同的代码量,二是可以用抽象类指针实现不同子类的接口,实现多态,便于后期扩展和维护代码。
代码:
#include <iostream>
using namespace std;
//抽象产品
class IWine
{
public:
virtual ~IWine() {}
virtual void createWine() = 0;
};
//抽象工厂类
class IFactory
{
public:
virtual ~IFactory() {}
virtual IWine* createFactory() = 0;
};
//啤酒-具体产品
class Beer :public IWine
{
public:
void createWine()
{
cout << "生产啤酒" << endl;
}
};
//白酒-具体产品
class Spirit :public IWine
{
public:
void createWine()
{
cout << "生产白酒" << endl;
}
};
//啤酒工厂-生产啤酒
class BeerFactory :public IFactory
{
public:
IWine* createFactory()
{
return new Beer;
}
};
//白酒工厂-生产白酒
class SpiritFactory :public IFactory
{
public:
IWine* createFactory()
{
return new Spirit;
}
};
int main() //客户端
{
IFactory *factory = new BeerFactory;
//IFactory *factory = new SpiritFactory;
factory->createFactory()->createWine();
if (factory) delete factory;
getchar();
return 0;
}
c++之单例模式
单例模式
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例可以分为饿汉单例和懒汉单例
饿汉式:类定义的时候就去实例化
优点:以空间换时间,不用担心多线程同步的问题
缺点:如果没有被使用,会浪费内存空间
懒汉式: 直到第一次使用时才实例化对象
优点:以时间换空间
缺点:需要考虑多线程同步的问题
代码:
#include <iostream>
#include <mutex>
using namespace std;
/*
饿汉式单例
饿汉式:类定义的时候就去实例化
优点:以空间换时间,不用担心多线程同步的问题
缺点:如果没有被使用,会浪费内存空间
问题:析构函数没有被调用
*/
class GloablLogHungry{
public:
GloablLogHungry(){
cout << "GloablLogHungry构造" << endl;
}
~GloablLogHungry(){
cout << "GloablLogHungry析构" << endl;
}
static GloablLogHungry* Instance(){
return m_instance;
}
void LogNorInfo()
{
cout << "饿汉单例记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "饿汉单例记录错误日志" << endl;
}
private:
static GloablLogHungry* m_instance;
};
GloablLogHungry* GloablLogHungry::m_instance = new GloablLogHungry();
/*
懒汉式:直到使用时才实例化对象
优点:以时间换空间
缺点:需要考虑多线程同步的问题
*/
/*
懒汉式单例 new
存在问题:析构函数没有执行 因为使用了new,如果没有显式的delete,会造成内存泄漏,
可以采用智能指针解决这个问题
*/
class GloablLogLazy{
public:
~GloablLogLazy(){
cout << "GloablLogLazy析构" << endl;
}
static GloablLogLazy* Instance(){
//局部静态对象
if (m_instance == nullptr)
{
std::lock_guard<std::mutex> lock(mutex); //上锁 自动释放
if (m_instance == nullptr) //防止其余线程继续创造实例
{
m_instance = new GloablLogLazy;
}
}
return m_instance;
}
void LogNorInfo()
{
cout << "懒汉单例1记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "懒汉单例1记录错误日志" << endl;
}
private:
static std::mutex m_mutex;
static GloablLogLazy *m_instance;
GloablLogLazy(){
cout << "GloablLogLazy构造" << endl;
} //防止对象被实例化
};
/*
懒汉式单例2 使用局部静态对象
优点:具有线程安全性,不需要释放堆内存
*/
class GloablLogLazylocal{
public:
~GloablLogLazylocal(){
cout << "GloablLogLazylocal析构" << endl;
}
//方式1
static GloablLogLazylocal* Instance(){
static GloablLogLazylocal instance;
return &instance;
}
void LogNorInfo()
{
cout << "懒汉单例2记录正常日志" << endl;
}
void LogErrorInfo()
{
cout << "懒汉单例2记录错误日志" << endl;
}
private:
GloablLogLazylocal(){
cout << "GloablLogLazylocal构造" << endl;
} //防止对象被实例化
};
int main()
{
//GloablLogLazy::Instance()->LogNorInfo();
//GloablLogLazy::Instance()->LogErrorInfo();
//推荐使用
GloablLogLazylocal::Instance()->LogNorInfo();
GloablLogLazylocal::Instance()->LogErrorInfo();
//GloablLogHungry::Instance()->LogNorInfo();
//GloablLogHungry::Instance()->LogErrorInfo();
return 0;
}
c++之装饰模式
装饰模式属于结构型模式,所谓装饰,即修饰的意思。
定义:动态的给一个对象添加一些额外的职责
优点:对于增加功能而言,装饰模式比生产子类更加灵活。
何时使用:
在不改变原来的类和关系的情况下,动态地扩展这个类对象所具有的功能,当然也支持撤销添加的功能。
优点:
装饰模式与继承的目的都是扩展对象的功能,但是装饰模式却可以提供比继承更多灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,我们可以创造出很多不同表现的组合。
缺点:
比起继承而言,代码更复杂了。因为出现了很多装饰类,导致代码变得臃肿。
UML类图:
应用场景:
我们使用一些形容词来修饰鼠标和键盘。
代码(c++):
#include <iostream>
#include <vector>
#include <iostream>
using namespace std;
class Component {
public:
virtual ~Component() {}
virtual void decorate() = 0;
};
class ConcreteComponent :public Component
{
public:
void decorate()
{
cout << "酷炫的 ";
}
};
class Decorator :public Component
{
public:
Decorator() :m_component(nullptr) {}
void setComponent(Component *c)
{
m_component = c;
}
void decorate()
{
if (m_component)
m_component->decorate();
}
protected:
Component* m_component;
};
class ConcreteDecoratorA :public Decorator
{
public:
void run() {
decorate(); //装饰机械键盘
cout << "机械键盘" << endl;
}
};
class ConcreteDecoratorB :public Decorator
{
public:
void run() {
decorate(); //装饰鼠标
cout << "鼠标" << endl;
}
};
//客户端
int main()
{
ConcreteComponent* pC = new ConcreteComponent;
ConcreteDecoratorA* pA = new ConcreteDecoratorA;
ConcreteDecoratorB* pB = new ConcreteDecoratorB;
pA->setComponent(pC); //使用pC来装饰pA
pA->run();
pB->setComponent(pC); //使用pC来装饰pB
pB->run();
if (pC) delete pC;
if (pA) delete pA;
if (pB) delete pB;
getchar();
return 0;
}
c++之中介者模式
中介者模式属于行为型模式。
定义:采用一个中介对象来封装一系列的对象交互。
优点:使得各个对象不需要显式的相互引用,达到解耦的效果。
UML类图
栗子场景:买房和卖房都担心被骗,然后通过房产中介做交互
代码
#include <iostream>
#include <string>
using namespace std;
class HousePerson;
class BuyHousePerson;
class SellHousePerson;
//抽象中介类
class Mediator{
public:
virtual void sendMessage(string msg, HousePerson *p) = 0;
};
//抽象炒房客
class HousePerson{
public:
HousePerson(Mediator *mediator)
{
m_mediator = mediator;
}
protected:
Mediator *m_mediator;
};
//买房的人
class BuyHousePerson :public HousePerson
{
public:
BuyHousePerson(Mediator *mediator) :HousePerson(mediator){}
void sendMsg(string msg)
{
m_mediator->sendMessage(msg,this);
}
void notify(string msg)
{
cout << "买房者得到消息:" << msg << endl;
}
};
//卖房的人
class SellHousePerson :public HousePerson
{
public:
SellHousePerson(Mediator *mediator) :HousePerson(mediator){}
void sendMsg(string msg)
{
m_mediator->sendMessage(msg, this);
}
void notify(string msg)
{
cout << "卖-房者得到消息:" << msg << endl;
}
};
//具体中介类
class ConcreteMediator :public Mediator
{
public:
void sendMessage(string msg, HousePerson *p)
{
if (p == bh)
{
sh->notify(msg);
}
else
{
bh->notify(msg);
}
}
public:
BuyHousePerson *bh;
SellHousePerson *sh;
};
//客户端
int main()
{
ConcreteMediator *pM = new ConcreteMediator;
BuyHousePerson *pBh = new BuyHousePerson(pM);
SellHousePerson* pSh = new SellHousePerson(pM);
pM->bh = pBh;
pM->sh = pSh;
pBh->sendMsg("卖不卖,一口价780W");
pSh->sendMsg("不卖,至少800W!");
if (pM)
{
delete pM;
pM = nullptr;
}
if (pBh)
{
delete pBh;
pBh = nullptr;
}
if (pSh)
{
delete pSh;
pSh = nullptr;
}
return 0;
}