单例模式
单例模式(Singleton Pattern)的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
单例模式有三个特点:
- 单例类只有一个实例对象;
- 单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
懒汉单例
所谓懒汉,就是用的时候才会创建单例。为了避免多线程可能创建多份实例的问题,可以在创建实例时加上锁。另外,如果单例对象是指针时,还应该考虑其释放的问题。以下代码使用了智能指针,会管理指针的释放问题。为了隐藏析构函数(不让外部手动析构指针),也增加了指针管理类SingleDeletor。
//SingleLazy.h
#pragma once
#include <mutex>
#include <string>
class SingleLazy;
class SingleDeletor
{
public:
void operator()(SingleLazy* single)
{
delete single;
}
};
class SingleLazy
{
SingleLazy() = default;
~SingleLazy() {}
SingleLazy(const SingleLazy&) = delete;
SingleLazy& operator=(const SingleLazy&) = delete;
static std::mutex m_mutex;
static std::shared_ptr<SingleLazy> m_ptrSingle;
friend class SingleDeletor;
public:
static std::shared_ptr<SingleLazy> singleton()
{
if (m_ptrSingle == NULL)
{
m_mutex.lock();
if (m_ptrSingle == NULL)
m_ptrSingle = std::shared_ptr<SingleLazy>(new SingleLazy,SingleDeletor());
m_mutex.unlock();
}
return m_ptrSingle;
}
std::string getString()
{
return "SingleLazy";
}
};
std::mutex SingleLazy::m_mutex;
std::shared_ptr<SingleLazy> SingleLazy::m_ptrSingle;
饿汉单例
在类加载的时候就将单例实例创建好,所以多线程调用时没有问题,但是存在浪费内存的问题。
//SingleHungry.h
#pragma once
class SingleHungry
{
SingleHungry() = default;
SingleHungry(const SingleHungry&) = delete;
SingleHungry& operator=(const SingleHungry&) = delete;
static std::shared_ptr<SingleHungry> m_ptrSingle;
public:
static std::shared_ptr<SingleHungry> singleton()
{
if (m_ptrSingle == NULL)
m_ptrSingle = std::shared_ptr<SingleHungry>(new SingleHungry);
return m_ptrSingle;
}
std::string getString()
{
return "SingleHungry";
}
};
std::shared_ptr<SingleHungry> SingleHungry::m_ptrSingle = SingleHungry::singleton();
测试代码
//main.cpp
#include "SingleLazy.h"
#include "SingleHungry.h"
using namespace std;
int main()
{
cout << SingleLazy::singleton()->getString() << endl;
cout << SingleHungry::singleton()->getString() << endl;
cout << "Hello CMake." << endl;
return 0;
}
工厂模式
工厂模式(Factory Pattern)用一个简单的类来创建实例的过程便称为工厂,用工厂方式代替外部new操作的一种设计模式。这是一种创建型模式,它提供了一个创建对象的最佳方式。在工厂模式中,我们创建对象时不会对上层暴露创建逻辑,而是通过使用一个共同结构来指向新创建的对象。
简单工厂
有一个工厂,可以生产自行车、摩托车、小汽车。
class Product
{
public:
Product() {}
virtual ~Product() {}
virtual std::string produceDate()
{
return "2022/01/01";
}
};
class Bicycle :public Product
{
public:
Bicycle() {}
};
class Motorcycle :public Product
{
public:
Motorcycle() {}
};
class Car :public Product
{
public:
Car() {}
};
class SimpleFactory
{
public:
enum ProductType
{
eBicycle = 0, ///< 自行车
eMotorcycle, ///< 摩托车
eCar ///< 汽车
};
public:
static Product* createProduct(ProductType type)
{
switch (type) {
case eBicycle:
return new Bicycle();
case eMotorcycle:
return new Motorcycle();
case eCar:
return new Car();
default:
break;
}
return nullptr;
}
};
方法工厂
为了提高产能,将小汽车、摩托车、自行车拆分成单独的产线,形成单独的工厂。
#pragma once
#include <iostream>
using namespace std;
class Product
{
public:
Product() {}
virtual ~Product() {}
virtual std::string produceDate()
{
return "2022/01/01";
}
};
class Bicycle :public Product
{
public:
Bicycle() {}
};
class Motorcycle :public Product
{
public:
Motorcycle() {}
};
class Car :public Product
{
public:
Car() {}
};
class Factory
{
public:
virtual Product* createProduct() = 0;
};
class BicycleFactory :public Factory
{
public:
BicycleFactory() {}
virtual Product* createProduct()
{
std::cout << "create a bicycle" << std::endl;
return new Bicycle();
}
};
class MotorcycleFactory :public Factory
{
public:
MotorcycleFactory() {}
virtual Product* createProduct()
{
std::cout << "create a motorcycle" << std::endl;
return new Motorcycle();
}
};
class CarFactory :public Factory
{
public:
CarFactory() {}
virtual Product* createProduct()
{
std::cout << "create a car" << std::endl;
return new Car();
}
};
int main()
{
CarFactory carFac;
Car* pCar = dynamic_cast<Car*>(carFac.createProduct());
return 0;
}
抽象工厂
行李箱生意市场前景可观,为了避免重新建厂,在现有三个厂的基础上,增加产线。自行车厂生产自行车和自行车行李箱、摩托车厂生产摩托车和摩托车行李箱、汽车厂生产汽车和汽车行李箱。
#pragma once
#include <iostream>
using namespace std;
class Product
{
public:
Product() {}
virtual ~Product() {}
virtual std::string produceDate()
{
return "2022/01/01";
}
};
class Bicycle :public Product
{
public:
Bicycle() {}
};
class Motorcycle :public Product
{
public:
Motorcycle() {}
};
class Car :public Product
{
public:
Car() {}
};
//行李箱
class Cass
{
public:
Cass() {}
virtual ~Cass() {}
virtual std::string produceDate()
{
return "2022/01/01";
}
};
class BicycleCass :public Cass
{
public:
BicycleCass() {}
};
class MotorcycleCass :public Cass
{
public:
MotorcycleCass() {}
};
class CarCass :public Cass
{
public:
CarCass() {}
};
class Factory
{
public:
virtual Product* createProduct() = 0;
virtual Cass* createCass() = 0;
};
class BicycleFactory :public Factory
{
public:
BicycleFactory() {}
virtual Product* createProduct()
{
std::cout << "create a bicycle" << std::endl;
return new Bicycle();
}
virtual Cass* createCass()
{
std::cout << "create a bicyclecass" << std::endl;
return new BicycleCass();
}
};
class MotorcycleFactory :public Factory
{
public:
MotorcycleFactory() {}
virtual Product* createProduct()
{
std::cout << "create a motorcycle" << std::endl;
return new Motorcycle();
}
virtual Cass* createCass()
{
std::cout << "create a motorcyclecass" << std::endl;
return new MotorcycleCass();
}
};
class CarFactory :public Factory
{
public:
CarFactory() {}
virtual Product* createProduct()
{
std::cout << "create a car" << std::endl;
return new Car();
}
virtual Cass* createCass()
{
std::cout << "create a carcass" << std::endl;
return new CarCass();
}
};
int main()
{
CarFactory carFac;
Car* pCar = dynamic_cast<Car*>(carFac.createProduct());
CarCass* pCarCass = dynamic_cast<CarCass*>(carFac.createCass());
return 0;
}
观察者模式
观察者模式(Observer Pattern)定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动的更新自己。
#pragma once
#include <iostream>
#include <list>
using namespace std;
class Observe
{
public:
Observe() {}
void update()
{
std::cout << "update" << std::endl;
}
};
class Subject
{
public:
Subject() {}
~Subject()
{
for (auto it : m_listObserve)
delete it;
}
void attach(Observe* obs)
{
m_listObserve.emplace_back(obs);
}
void detach(Observe* obs)
{
m_listObserve.remove(obs);
}
void notify()
{
for (auto it : m_listObserve)
{
it->update();
}
}
private:
std::list<Observe*> m_listObserve;
};
int main()
{
Subject* pSubject = new Subject();
pSubject->attach(new Observe());
pSubject->attach(new Observe());
pSubject->notify();
delete pSubject;
return 0;
}
装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
#pragma once
#include <iostream>
#include <list>
using namespace std;
class Cake
{
public:
virtual void show() = 0;
};
//奶油蛋糕
class CreamCake :public Cake
{
public:
virtual void show()
{
std::cout << "this is a CreamCake";
}
};
//水果蛋糕
class FruitCake :public Cake
{
public:
virtual void show()
{
std::cout << "this is a FruitCake";
}
};
//巧克力装饰
class ChocolateCake :public Cake
{
public:
ChocolateCake(Cake* cake)
{
m_pCake = cake;
}
virtual void show()
{
m_pCake->show();
std::cout << " add Chocolate on it";
}
private:
Cake* m_pCake = nullptr;
};
class CandyCake : public Cake
{
public:
CandyCake(Cake* cake)
{
m_pCake = cake;
}
virtual void show()
{
m_pCake->show();
std::cout << " add Candy on it";
}
private:
Cake* m_pCake = nullptr;
};
int main()
{
Cake* pCreamCake = new CreamCake(); //先制作一个奶油蛋糕
pCreamCake = new ChocolateCake(pCreamCake); //添加巧克力
pCreamCake->show();
std::cout << std::endl;
Cake* pFruitCake = new FruitCake(); //先制作一个水果蛋糕
pFruitCake = new ChocolateCake(pFruitCake); //添加巧克力
pFruitCake = new CandyCake(pFruitCake); //添加糖果
pFruitCake->show();
return 0;
}
输出结果:给奶油蛋糕添加了巧克力,给水果蛋糕添加了巧克力和糖果