class Singleton
{
public:
static Singleton *GetInstance()
{
if (_instance == nullptr){
_instance = new Singleton();
atexit(Destructor); // atexit 是线程安全的
}
return _instance;
}
private:
static void Destructor()
{
if (nullptr != _instance){
delete _instance;
_instance = nullptr;
}
}
Singleton(){}; //构造
~Singleton(){};
Singleton(const Singleton &) = delete; //拷⻉构造
Singleton &operator=(const Singleton &) = delete; //拷贝赋值构造
Singleton(Singleton &&) = delete; //移动构造
Singleton &operator=(Singleton &&) = delete; //移动拷贝构造
static Singleton *_instance;
};
Singleton *Singleton::_instance = nullptr; //静态成员需要初始化
#include
Singleton *Singleton::_instance = nullptr; //静态成员需要初始化
std::mutex Singleton::_mutex; //互斥锁初始化
class Singleton
{
public:
static Singleton *GetInstance()
{
// std::lock_guard lock(_mutex); // 3.1 切换线程
if (_instance == nullptr)
{
std::lock_guard<std::mutex> lock(_mutex); // 3.2
if (_instance == nullptr)
{
_instance = new Singleton();
// 1. 分配内存 2. 调用构造函数 3. 返回指针
// 问题:多线程环境下,会出现CPU指令重排,比如:132 这样如果在没调用构造函数,就返回了指针,操作该指针会报错
atexit(Destructor);
}
}
return _instance;
}
private:
static void Destructor()
{
if (nullptr != _instance){
delete _instance;
_instance = nullptr;
}
}
Singleton(){}; //构造
~Singleton(){};
Singleton(const Singleton &) = delete; //拷⻉构造
Singleton &operator=(const Singleton &) = delete; //拷贝赋值构造
Singleton(Singleton &&) = delete; //移动构造
Singleton &operator=(Singleton &&) = delete; //移动拷贝构造
static Singleton *_instance;
static std::mutex _mutex;
};
分为:原子变量和内存栅栏。其中,原子变量负责解决原子行和可见性,内存栅栏负责解决执行序问题。
load 就是可以看见其他线程最新操作的数据。
store 就是让别的线程可以看到自己线程的修改。
static std::atomic<Singleton *> _instance; //原子变量需要添加头文件 #include
Singleton *tmp = _instance.load(std::memory_order_relaxed); //
_instance.store(tmp, std::memory_order_relaxed); //
memory_order_acquire 和 memory_order_release之间的代码,不会被优化到他们之外的部分。
memory_order_relaxed 优点:内存模型使用relaxed进行优化,速度快
#include
#include
class Singleton
{
public:
static Singleton *GetInstance()
{
Singleton *tmp = _instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire); //获取内存屏障,也就是开启内存屏障
if (tmp == nullptr)
{
std::lock_guard<std::mutex> lock(_mutex);
tmp =_instance.load(std::memory_order_relaxed); // 内存模型使用relaxed进行优化,速度快
if (tmp == nullptr){
tmp = new Singleton; // 在内存屏障的区域内,乱序没有关系,不会跑出内存屏障的范围
std::atomic_thread_fence(std::memory_order_release); //释放内存屏障
_instance.store(tmp, std::memory_order_relaxed);
atexit(Destructor);
}
}
return tmp;
}
private:
static void Destructor(){
Singleton *tmp = _instance.load(std::memory_order_relaxed);
if (nullptr != tmp){
delete tmp;
}
}
Singleton(){}; //构造
~Singleton(){};
Singleton(const Singleton &) = delete; //拷⻉构造
Singleton &operator=(const Singleton &) = delete; /拷贝赋值构造
Singleton(Singleton &&) = delete; //移动构造
Singleton &operator=(Singleton &&) = delete; //移动拷贝构造
static std::atomic<Singleton *> _instance;
static std::mutex _mutex;
};
std::atomic<Singleton *> Singleton::_instance; //静态成员需要初始化
std::mutex Singleton::_mutex; //互斥锁初始化
class Singleton
{
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){}; //构造
~Singleton(){};
Singleton(const Singleton &) = delete; //拷⻉构造
Singleton &operator=(const Singleton &) = delete; //拷贝赋值构造
Singleton(Singleton &&) = delete; //移动构造
Singleton &operator=(Singleton &&) = delete; //移动拷贝构造
};
为了让基类的Singleton访问到子类DesignPattern的私有构造函数,所以,需要在子类中声明基类为友元类。友元函数可以访问该类的私有成员和属性。
template <typename T>
class Singleton
{
public:
static T &GetInstance(){
static T instance; // 这⾥要初始化DesignPattern,需要调⽤DesignPattern 构造函数,同时会调⽤⽗类的构造函数。
return instance;
}
protected:
virtual ~Singleton() {}
Singleton() {} // protected修饰构造函数,才能让别⼈继承
private:
Singleton(const Singleton &) = delete; //拷⻉构造
Singleton &operator=(const Singleton &) = delete; //拷贝赋值构造
Singleton(Singleton &&) = delete; //移动构造
Singleton &operator=(Singleton &&) = delete; //移动拷贝构造
};
// 子类DesignPattern 继承父类 Singleton
class DesignPattern : public Singleton<DesignPattern>
{
friend class Singleton<DesignPattern>; //friend 能让Singleton 访问到 DesignPattern构造函数
private :
DesignPattern() {}
~DesignPattern() {}
};
实现代码举例:
#include
// 实现导出数据的接口, 导出数据的格式包含 xml,json 后面可能扩展excel格式csv
class IExport {
public:
virtual bool Export(const std::string &data) = 0; // 纯虚函数,多态
virtual ~IExport(){} // 虚析构函数
};
class ExportXml : public IExport {
public:
// 需要实现父类的纯虚函数
virtual bool Export(const std::string &data) {
return true;
}
};
class ExportJson : public IExport {
public:
// 需要实现父类的纯虚函数
virtual bool Export(const std::string &data) {
return true;
}
};
// 扩展csv格式
/*
class ExportCSV : public IExport {
public:
virtual bool Export(const std::string &data) {
return true;
}
};
*/
// 工厂对外提供导出接口
class IExportFactory {
public:
IExportFactory() {
_export = nullptr;
}
virtual ~IExportFactory() {
if (_export) {
delete _export;
_export = nullptr;
}
}
bool Export(const std::string &data) {
if (_export == nullptr) {
_export = NewExport();
}
return _export->Export(data);
}
protected:
virtual IExport * NewExport(/* ... */) = 0;
private:
IExport* _export; //基类指针
};
class ExportXmlFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/* ... */) {
// 可能有其它操作,或者许多参数
IExport * temp = new ExportXml();
// 可能之后有什么操作
return temp;
}
};
class ExportJsonFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/* ... */) {
// 可能有其它操作,或者许多参数
IExport * temp = new ExportJson;
// 可能之后有什么操作
return temp;
}
};
// 扩展csv格式
/*
class ExportCSVFactory : public IExportFactory {
protected:
virtual IExport * NewExport(/* ... */) {
// 可能有其它操作,或者许多参数
IExport * temp = new ExportCSV;
// 可能之后有什么操作
return temp;
}
};
*/
int main () {
IExportFactory *factory = new ExportCSVFactory();
factory->Export("hello world");
return 0;
}
代码实现举例
#include
// 实现导出数据的接口, 导出数据的格式包含 xml,json,文本格式txt 后面可能扩展excel格式csv
class IExport {
public:
virtual bool Export(const std::string &data) = 0;
virtual ~IExport(){}
};
class ExportXml : public IExport {
public:
virtual bool Export(const std::string &data) {
return true;
}
};
class IImport {
public:
virtual bool Import(const std::string &data) = 0;
virtual ~IImport(){}
};
class ImportXml : public IImport {
public:
virtual bool Import(const std::string &data) {
return true;
}
};
class IDataApiFactory {
public:
IDataApiFactory() {
_export = nullptr;
_import = nullptr;
}
virtual ~IDataApiFactory() {
if (_export) {
delete _export;
_export = nullptr;
}
if (_import) {
delete _import;
_import = nullptr;
}
}
bool Export(const std::string &data) {
if (_export == nullptr) {
_export = NewExport();
}
return _export->Export(data);
}
bool Import(const std::string &data) {
if (_import == nullptr) {
_import = NewImport();
}
return _import->Import(data);
}
protected:
virtual IExport * NewExport(/* ... */) = 0;
virtual IImport * NewImport(/* ... */) = 0;
private:
IExport *_export;
IImport *_import;
};
class XmlApiFactory : public IDataApiFactory {
protected:
virtual IExport * NewExport(/* ... */) {
// 可能有其它操作,或者许多参数
IExport * temp = new ExportXml;
// 可能之后有什么操作
return temp;
}
virtual IImport * NewImport(/* ... */) {
// 可能有其它操作,或者许多参数
IImport * temp = new ImportXml;
// 可能之后有什么操作
return temp;
}
};
// 相关性 依赖性 工作当中
int main () {
IDataApiFactory *factory = new CSVApiFactory();
factory->Import("hello world");
factory->Export("hello world");
return 0;
}
接收者形成一个链条,发送者发送的请求,从第一个开始,往后顺延,直到被处理为止,处理完后面就不会再处理了。简单理解:一个一个传递,有打断功能。
场景:请假流程,1天内需要直系领导审批;3天内需要经理审批,3天以上需要董事长审批。
核心点:我能处理我处理,处理不了往下传。
代码实现举例:
#include
class Context {
public:
std::string name;
int day;
};
// 稳定点 抽象 变化点 扩展 (多态)
// 从单个处理节点出发,我能处理,我处理,我不能处理交给下一个人处理
// 链表关系如何抽象
class IHandler {
public:
virtual ~IHandler() : next(nullptr) {}
void SetNextHandler(IHandler *next) { // 链表关系
next = next;
}
bool Handle(const Context &ctx) {
if (CanHandle(ctx)) {
return HandleRequest(ctx);
} else if (GetNextHandler()) {
return GetNextHandler()->Handle(ctx);
} else {
// err
}
return false;
}
// 通过函数来抽象 处理节点的个数 处理节点顺序
static bool handler_leavereq(Context &ctx) {
IHandler * h0 = new HandleByBeauty();
IHandler * h1 = new HandleByMainProgram();
IHandler * h2 = new HandleByProjMgr();
IHandler * h3 = new HandleByBoss();
h0->SetNextHandler(h1);
h1->SetNextHandler(h2);
h2->SetNextHandler(h3);
return h0->Handle(ctx);
}
protected:
virtual bool HandleRequest(const Context &ctx) {return true};
virtual bool CanHandle(const Context &ctx) {return true};
IHandler * GetNextHandler() {
return next;
}
private:
IHandler *next; // 组合基类指针
};
// 能不能处理,以及怎么处理
class HandleByMainLeader : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
if (ctx.day <= 10)
return true;
return false;
}
};
class HandleByMgr : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
if (ctx.day <= 20)
return true;
return false;
}
};
class HandleByBoss : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
if (ctx.day < 30)
return true;
return false;
}
};
class HandleByBeauty : public IHandler {
protected:
virtual bool HandleRequest(const Context &ctx){
//
return true;
}
virtual bool CanHandle(const Context &ctx) {
//
if (ctx.day <= 3)
return true;
return false;
}
};
int main() {
// nginx http 处理 就是责任连模式
// 设置下一指针
Context ctx;
if (IHander::handler_leavereq(ctx)) {
cout << "请假成功";
} else {
cout << "请假失败";
}
return 0;
}
动态地给一个对象增加一些额外的职责。比生产子类更加灵活。
不影响其他对象的情况下,以动态、透明的方式给对象添加职责;每个职责都是完全独立的功能,彼此之间没有依赖
#include
// 普通员工有销售奖金,累计奖金,部门经理除此之外还有团队奖金;后面可能会添加环比增长奖金,同时可能产生不同的奖金组合;
// 销售奖金 = 当月销售额 * 4%
// 累计奖金 = 总的回款额 * 0.2%
// 部门奖金 = 团队销售额 * 1%
// 环比奖金 = (当月销售额-上月销售额) * 1%
// 销售后面的参数可能会调整
using namespace std;
class Context {
public:
bool isMgr;
// User user;
// double groupsale;
};
class CalcBonus {
public:
CalcBonus(CalcBonus * c = nullptr) : cc(c) {}
virtual double Calc(Context &ctx) {
return 0.0; // 基本工资
}
virtual ~CalcBonus() {}
protected:
CalcBonus* cc;
};
class CalcMonthBonus : public CalcBonus {
public:
CalcMonthBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double mbonus /*= 计算流程忽略*/;
return mbonus + cc->Calc(ctx);
}
};
class CalcSumBonus : public CalcBonus {
public:
CalcSumBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double sbonus /*= 计算流程忽略*/;
return sbonus + cc->Calc(ctx);
}
};
class CalcGroupBonus : public CalcBonus {
public:
CalcGroupBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double gbnonus /*= 计算流程忽略*/;
return gbnonus + cc->Calc(ctx);
}
};
class CalcCycleBonus : public CalcBonus {
public:
CalcCycleBonus(CalcBonus * c) : CalcBonus(c) {}
virtual double Calc(Context &ctx) {
double gbnonus /*= 计算流程忽略*/;
return gbnonus + cc->Calc(ctx);
}
};
int main() {
// 1. 普通员工
Context ctx1;
CalcBonus *base = new CalcBonus();
CalcBonus *cb1 = new CalcMonthBonus(base);
CalcBonus *cb2 = new CalcSumBonus(cb1);
cb2->Calc(ctx1);
// 2. 部门经理
Context ctx2;
CalcBonus *cb3 = new CalcGroupBonus(cb1);
cb3->Calc(ctx2);
}
将对象组合成树型结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
class IComponent
{
public:
IComponent(/* args */);
~IComponent();
virtual void Execute() = 0;
virtual void AddChild(IComponent *ele) {}
virtual void RemoveChild(IComponent *ele) {}
};
class Leaf : public IComponent
{
public:
virtual void Execute() {
cout << "leaf exxcute" << endl;
}
};
class Composite : public IComponent
{
private:
std::list<IComponent*> _list;
public:
virtual void AddChild(IComponent *ele) {
// ...
}
virtual void RemoveChild(IComponent *ele) {
// ...
}
virtual void Execute() {
for (auto iter = _list.begin(); iter != _list.end(); iter++) {
iter->Execute();
}
}
};
文章参考与<零声教育>的C/C++linux服务期高级架构。