C++常用设计模式
1. 单例模式
单例模式有懒汉单例模式和饿汉单例模式,单例模式是该类不管创建多少次,都是共享的同一个类,懒汉模式与饿汉模式的最大区别在于在类被加载是是否被初始化(懒汉模式在类被加载是没有被初始化,而饿汉模式进行了初始化)
- 懒汉单例模式
class A
{
private:
A(){}//私有化构造函数
static A* m_A;//静态成员变量
class B{
public:
~B()
{
if(m_A)
{
delete m_A;
m_A=NULL;
}
}
}
static B* m_B; //用于析构
public:
static A* getA()
{
if(!m_A)//这是导致懒汉单例模式不安全的原因,可以加锁,并进行双重判断
m_A=new A();
return m_A;
}
}
A* A::m_A=NULL;//这点是与饿汉模式不同的地方
- 饿汉单例模式
class A
{
private:
A(){}//私有化构造函数
static A* m_A;//静态成员变量
class B{
public:
~B()
{
if(m_A)
{
delete m_A;
m_A=NULL;
}
}
}
static B* m_B; //用于析构
public:
static A* getA()
{//是安全的
return m_A;
}
}
A* A::m_A=new A();
2. 工厂模式
工厂模式分为:简单工厂模式、工厂方法模式和抽象工厂模式,工厂模式是通过工厂类去实现不同产品,根据传入参数类型的变化来改变其行为
- 简单工厂模式
在工厂类中进行进行类型判断,根据类型不同new出不同的产品的对象
typedef enum ProductTypeTag
{
typeA,
typeB,
typeC
}PRODUCTTYPE;
//抽象产品
class product
{
public:
product(){}
virtual~product(){}
virtual void show() = 0;
};
//产品A
class productA :public product
{
public:
productA(){}
virtual ~productA(){}
void show()
{
cout << "产品A" << endl;
}
};
//产品B
class productB :public product
{
public:
productB() {}
virtual ~productB() {}
void show()
{
cout << "产品B" << endl;
}
};
//产品C
class productC :public product
{
public:
productC(){}
virtual ~productC() {}
void show()
{
cout << "产品C"<< endl;
}
};
//工厂类
class factor
{
public:
factor(){}
~factor(){}
product* getProduct(PRODUCTTYPE type)//生产产品
{
switch (type)
{
case typeA:
return new productA();
case typeB:
return new productB();
case typeC:
return new productC();
default:
return NULL;
}
}
};
- 工厂方法模式
每扩展一个新的产品就需要一个新的工厂去实现
//抽象产品
class product
{
public:
product() {}
virtual~product() {}
virtual void show() = 0;
};
//产品A
class productA :public product
{
public:
productA() {}
virtual ~productA() {}
void show()
{
cout << "产品A" << endl;
}
};
//产品B
class productB :public product
{
public:
productB() {}
virtual ~productB() {}
void show()
{
cout << "产品B" << endl;
}
};
//产品C
class productC :public product
{
public:
productC() {}
virtual ~productC() {}
void show()
{
cout << "产品C" << endl;
}
};
//抽象工厂
class factor
{
public:
factor(){}
virtual ~factor(){}
virtual product* getProduct()=0;//生产产品
};
//具体工厂类A
class factorA :public factor
{
public:
factorA(){}
~factorA(){}
product* getProduct()
{
return new productA();
}
};
//具体工厂类B
class factorB :public factor
{
public:
factorB() {}
~factorB() {}
product* getProduct()
{
return new productB();
}
};
//具体工厂类C
class factorC :public factor
{
public:
factorC() {}
~factorC() {}
product* getProduct()
{
return new productC();
}
};
- 抽象工厂模式
将多个产品分成一个族,用同一个工厂实现一个族,如两个产品基类A,B,由A,B又派生出A1,A2,B1,B2; 可以将这分配给两个工厂去完成,1类工厂去完成A1,B1;2类工厂去完成A2,B2;
当要获得一个产品时,只需找到正确工厂,调用生产A或B类的接口就可以,而不需要具体的类型A1,B1,A2,B2
//产品A的抽象类
class A
{
public:
A(){}
virtual~A(){}
virtual void show()=0;
};
//产品A的具体类1
class A1:public A
{
public:
A1(){}
~A1(){}
void show()
{
cout << "产品A1" << endl;
}
};
//产品A的具体类2
class A2:public A
{
public:
A2(){}
~A2(){}
void show()
{
cout << "产品A2" << endl;
}
};
//产品B的抽象类
class B
{
public:
B(){}
virtual~B(){}
virtual void show()=0;
};
//产品B的具体类1
class B1:public B
{
public:
B1(){}
~B1(){}
void show()
{
cout << "产品B1" << endl;
}
};
//产品B的具体类2
class B2:public B
{
public:
B2(){}
~B2(){}
void show()
{
cout << "产品B2" << endl;
}
};
//抽象工厂
class factor
{
public:
factor(){}
virtual~ factor(){}
virtual A* getA()=0;//生产A类产品
virtual B* getA()=0;//生产B类产品
};
//1类具体工厂
class factor1:public factor
{
public:
factor1(){}
~ factor1(){}
A* getA()//生产A类1产品
{
return new A1();
}
virtual B* getA()//生产B类1产品
{
return new B1();
}
};
//2类具体工厂
class factor2:public factor
{
public:
factor2(){}
~ factor2(){}
A* getA()//生产A类2产品
{
return new A2();
}
virtual B* getA()//生产B类2产品
{
return new B2();
}
};
3. 代理模式
代理模式是给一个对象提供一个代理对象,代理类实现的接口与被代理类实现的接口相同
//抽象类
class A
{
public:
A(){}
virtual ~A(){}
virtual void show()=0;
};
//被代理类
class B:public A
{
public:
B(int num):number(num){}
~B(){}
void show()
{
cout << "被代理类" << number << endl;
}
private:
int number;
};
//代理类
class C:public A
{
public:
C(int number):aa(new B(number)){}
~C(){delete aa;}
void show()
{
aa->show();
}
private:
A* aa;
};
4. 策略模式
刚开始的时候容易将策略模式与代理模式混淆,策略模式不需要实现与其相同的接口
class A
{
public:
A(){}
virtual ~A(){}
virtual void show()=0;
};
class B:public A
{
public:
B(int a):number(a){}
~B(){}
void show()
{
cout << "类B" << number << endl;
}
ptivate:
int number;
};
class C//与类B不是同一个类派生出来,不需要实现相同接口
{
public:
C(int a):aa(new B(a)){}
~C()
{
delete aa;
}
void showvalue()
{
aa->show();
}
private:
A* aa;
};
5. 适配器模式
将一个类的接口转化成客户端所希望的接口,使之间不能兼容的可以一起工作,适配器是继承或依赖于被适配类,类似于国内电脑在国外用时,充电器要用转接口才能使用;(对不合要求的接口进行封装)
继承被适配类实现如下
//被适配类(双端队列)
class Deque
{
public:
void push_back(int x)
{
cout << "Deque push_back:" << x << endl;
}
void push_front(int x)
{
cout << "Deque push_front:" << x << endl;
}
void pop_back()
{
cout << "Deque pop_back" << endl;
}
void pop_front()
{
cout << "Deque pop_front" << endl;
}
};
//目标类()
class target
{
public:
virtual void pop()=0;
virtual void push(int x)=0;
};
class A:public target,private Deque
{
public:
void pop()
{
pop_front();
}
void push(int x)
{
push_back(x);
}
};
不使用继承实现
//被适配类(双端队列)
class Deque
{
public:
void push_back(int x)
{
cout << "Deque push_back:" << x << endl;
}
void push_front(int x)
{
cout << "Deque push_front:" << x << endl;
}
void pop_back()
{
cout << "Deque pop_back" << endl;
}
void pop_front()
{
cout << "Deque pop_front" << endl;
}
};
//目标类()
class target
{
public:
virtual void pop()=0;
virtual void push(int x)=0;
};
class A:public target
{
public:
void pop()
{
De.pop_front();
}
void push(int x)
{
De.push_back(x);
}
private:
Deque De;
};
6. 观察者模式
观察者模式是实现一种一对多的模型,当被观察者状态发生变化时,观察者都会得到通知并有所作为,如关注一个博主,当博主更新状态时,关注了这个博主的人会收到提示
#include <iostream>
#include <list>
using namespace std;
/*实现观察模式*/
//抽象观察者
class Observer {
public:
virtual void Update() = 0;//有更新
};
//抽象被观察者
class Subject {
public:
Subject(){}
virtual void Attach(Observer*) = 0;
virtual void Detach(Observer*) = 0;
virtual void Notify() = 0;
void setState(int state) {
m_state = state;
Notify();
}
int getState()const {
return m_state;
}
protected:
list<Observer*> m_ObserverList;
int m_state;
};
//具体被观察者
class ConcreteSubject : public Subject
{
public:
ConcreteSubject(){}
virtual void Attach(Observer* ob)
{
this->m_ObserverList.push_back(ob);
cout << "观察成功" << endl;
}
virtual void Detach(Observer* ob)
{
this->m_ObserverList.remove(ob);
}
virtual void Notify()
{
list<Observer*>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update();
++it;
}
}
};
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(Subject* subject) {
m_subject = subject;
m_subject->Attach(this);
}
void Update() {
cout << "被观察者更新:" << m_subject->getState() << endl;
}
private:
Subject* m_subject;
};
int main()
{
Subject* sub = new ConcreteSubject();
Observer* Ob = new ConcreteObserver(sub);
sub->setState(5);
system("pause");
}
7. 模板模式
当多个类有相同的方法,并且逻辑相同,只是细节上有差异时,可以考虑使用模板模式。具体的实现上可以将相同的核心算法设计为模板方法,具体的实现细节有子类实现。
class Computer
{
public:
void product()
{
installCpu();
installRam();
installGraphicsCard();
}
protected:
virtual void installCpu() = 0;
virtual void installRam() = 0;
virtual void installGraphicsCard() = 0;
};
class ComputerA : public Computer
{
protected:
void installCpu() override
{
cout << "ComputerA install Inter Core i5" << endl;
}
void installRam() override
{
cout << "ComputerA install 2G Ram" << endl;
}
void installGraphicsCard() override
{
cout << "ComputerA install Gtx940 GraphicsCard" << endl;
}
};
class ComputerB : public Computer
{
protected:
void installCpu() override
{
cout << "ComputerB install Inter Core i7" << endl;
}
void installRam() override
{
cout << "ComputerB install 4G Ram" << endl;
}
void installGraphicsCard() override
{
cout << "ComputerB install Gtx960 GraphicsCard" << endl;
}
};