设计模式总共有23种,可分为3大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。
1. 工厂模式
工厂模式属于创建者模式,提供了一种创建对象的最佳方式。
工厂模式的实现方式有简单工厂模式、工厂方法模式、抽象工厂模式,每个实现方式都存在优和劣。
简单工厂模式与工厂模式的结构组成是:
1. 工厂类:工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。(可分为抽象工厂和具体工厂)
2. 抽象产品类:是具体产品类的继承的父类或实现的接口。
3. 具体产品类:工厂类所创建的对象就是此具体产品实例。
以汽车厂为例:
Cars为汽车的抽象类(基类),接口函数为Show(),用于显示文本。
Benzi、Audi、Bmw为具体汽车品牌的类,它们都继承于Cars抽象类。
// 汽车抽象类
class Cars
{
public:
virtual ~Cars() {
}
virtual void Show() = 0;
};
// 奔驰
class Benzi: public Cars
{
public:
void Show()
{
std::cout << "我是Benzi" << std::endl;
}
};
// 奥迪
class Audi: public Cars
{
public:
void Show()
{
std::cout << "我是Audi" << std::endl;
}
};
// 宝马
class Bmw: public Cars
{
public:
void Show()
{
std::cout << "我是Bmw" << std::endl;
}
};
CarsFactory为工厂类,类里实现根据汽车类型创建对应产品对象的CreateCars(CARS_TYPE type)函数。
enum CARS_TYPE
{
BENZI,
AUDI,
BMW
};
// 总车厂
class CarsFactory
{
public:
// 根据鞋子类型创建对应的鞋子对象
Cars *CreateCars(CARS_TYPE type)
{
switch (type)
{
case BENZI:
return new Benzi();
break;
case AUDI:
return new Audi();
break;
case BMW:
return new Bmw();
break;
default:
return NULL;
break;
}
}
};
main函数,先是构造了工厂对象,然后创建指定类型的具体产品对象,然后输出对应文本。因为采用的是new
的方式创建了对象,用完了要通过delete
释放资源资源。
int main()
{
// 构造工厂对象
CarsFactory carsFactory;
// 从工厂对象创建benzi对象
Cars *pBenzi = carsFactory.CreateCars(BENZI);
if (pBenzi != NULL)
{
pBenzi->Show();
// 释放资源
delete pBenzi;
pBenzi = NULL;
}
// 从工厂对象创建audi对象
Cars *pAudi = carsFactory.CreateCars(AUDI);
if (pAudi != NULL)
{
pAudi ->Show();
// 释放资源
delete pAudi ;
pAudi = NULL;
}
// 从工厂对象创建bmw对象
Cars *pBmw = carsFactory.CreateCars(BMW);
if (pBmw != NULL)
{
pBmw ->Show();
// 释放资源
delete pBmw ;
pBmw = NULL;
}
return 0;
}
2. 抽象工厂模式
汽车厂为了扩大业务,不只生产汽车了,还生产摩托车。抽象工厂模式可以创建多个工厂和多个产品族。
抽象工厂模式的组成:
1. 抽象工厂类:工厂方法模式的核心类,提供创建具体产品的接口,由具体工厂类实现。
2. 具体工厂类:继承于抽象工厂,实现创建对应具体产品对象的方式。
3. 抽象产品类:它是具体产品继承的父类(基类)。
4. 具体产品类:具体工厂所创建的对象,就是此类。
创建基类(抽象产品类):
// 汽车抽象类
class Cars
{
public:
virtual ~Cars() {
}
virtual void Show() = 0;
};
// 奔驰
class BenziCar: public Cars
{
public:
void Show()
{
std::cout << "我是Benzi car" << std::endl;
}
};
// 摩托车抽象类
class Motors
{
public:
virtual ~Motors() {
}
virtual void Show() = 0;
};
// 奔驰
class BenziMotor: public Motors
{
public:
void Show()
{
std::cout << "我是Benzi motor" << std::endl;
}
};
Factory为抽象工厂,提供了创建汽车CreateCars()和摩托车产品CreateMotors()对象的接口。
BenziProducer为具体工厂,实现了创建奔驰汽车和奔驰摩托车的方式。
// 总厂
class Factory
{
public:
virtual Cars *CreateCars() = 0;
virtual Motors *CreateMotors() = 0;
virtual ~Factory() {
}
};
// benzi生产者/生产链
class BenziProducer : public Factory
{
public:
Cars *CreateCars()
{
return new BenziCar();
}
Motors *CreateMotors()
{
return new BenziMotor();
}
};
main函数,构造benzi工厂对象,然后创建benzi产品族的汽车和摩托车对象。同样,对象不再使用时,需要手动释放资源。
int main()
{
// ================ 生产Benzi流程 ==================== //
// 生产线
Factory *benziProducer = new BenziProducer();
// 生产汽车
Cars *benziCar = benziProducer ->CreateCars();
// 生产摩托车
Motors *benziMotor = benziProducer ->CreateMotors();
benziCar->Show();
benziMotor->Show();
// 释放资源
delete benziCar;
delete benziMotor;
delete benziProducer;
return 0;
}
3. 单例模式
单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。
单例模式可以保证线程安全,即给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同。懒汉式只有使用时才会创建实例,这种情况要考虑线程安全;饿汉式初始化就会创建实例,需要时直接调用,不用考虑安全问题。
饿汉式实现:
头文件:
// 饿汉实现 /
class Singleton
{
public:
// 获取单实例
static Singleton* GetInstance();
// 释放单实例,进程退出时调用
static void deleteInstance();
// 打印实例地址
void Print();
private:
// 将其构造和析构成为私有的, 禁止外部构造和析构
Singleton();
~Singleton();
// 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值
Singleton(const Singleton &signal);
const Singleton &operator=(const Singleton &signal);
private:
// 唯一单实例对象指针
static Singleton *g_pSingleton;
};
源文件:
// 代码一运行就初始化创建实例 ,本身就线程安全
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton();
Singleton* Singleton::GetInstance()
{
return g_pSingleton;
}
void Singleton::deleteInstance()
{
if (g_pSingleton)
{
delete g_pSingleton;
g_pSingleton = nullptr;
}
}
void Singleton::Print()
{
std::cout << "我的实例内存地址是:" << this << std::endl;
}
Singleton::Singleton()
{
std::cout << "构造函数" << std::endl;
}
Singleton::~Singleton()
{
std::cout << "析构函数" << std::endl;
}
main程序:
#include <iostream>
#include <memory>
#include <mutex>
class Singleton {
public:
static std::shared_ptr<Singleton> getSingleton();
void print() {
std::cout << "Hello World." << std::endl;
}
~Singleton() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
private:
Singleton() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
static std::shared_ptr<Singleton> singleton = nullptr;
static std::once_flag singletonFlag;
std::shared_ptr<Singleton> Singleton::getSingleton() {
std::call_once(singletonFlag, [&] {
singleton = std::shared_ptr<Singleton>(new Singleton());
});
return singleton;
}
4. 建造者模式
建造者模式可以将复杂对象的构建与它的表示分离,使得相同的构建过程可以得到不同的表示。如果说工厂模式和抽象工厂模式更注重产品整体,那建造者模式则更在乎产品的组成和细节。
5. 原型模式
原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
以上。