一、设计模式简介
1、什么是设计模式
针对反复出现的问题所总结归纳出的通用解决方设计模式是指在软件开发过程中案。这些方案是众多软件开发人员经过大量实践总结出来的,具有高效性、可维护性和可扩展性等优点。使用设计模式可以帮助开发者更高效地构建软件系统,提高代码的复用性、可维护性和可扩展性,同时也能降低系统的耦合度。
2、设计模式分类
大体上设计模式分为3中类型:创建型、结构型和代码型
23种设计模式
二、单例设计模式
其特点是只提供唯一一个类的设计模式,具有全局变量的特点,在任何位置都可以通过接口获取到唯一实例。他的优点显而易见:
他能够避免对象重复创建,节约空间并提升效率
避免由于操作不同实例导致的逻辑错误
单例模式有两种实现模式:饿汉式和懒汉式
饿汉:饿了肯定要饥不择⻝。所以在单例类定义的时候就进⾏实例化。
懒汉:在第⼀次⽤到类实例的时候才会去实例化。什么时候使⽤,什么时候创建单例
#include <iostream>
#include <string>
#include<memory>
using namespace std;
//单例的 饿汉模式的实现--特点:在定义类的时候就创建了一个对象
class Singleton
{
public:
//Singleton(const Singleton&temp )=delete;
static Singleton*get_instance()
{
return instance;
}
void test()
{
cout << "测试"<<this << endl;
}
private:
Singleton()=default;
//Singleton(const Singleton&temp )=default;
Singleton(const Singleton&temp )=default;
Singleton& operator=(const Singleton&temp)=default;
static Singleton*instance;
};
Singleton*Singleton::instance=new Singleton;
int main()
{
Singleton *obj1= Singleton::get_instance();
Singleton *obj2= Singleton::get_instance();
obj1->test();
obj2->test();
return 0;
}
//测试0x1fb01e91750
//测试0x1fb01e91750
#include <iostream>
#include <string>
#include<memory>
using namespace std;
//单例的 懒汉模式的实现--特点:第一次用类的实例才创建对象
//对于多线程环境下 饿汉模式它是线程安全的,对于懒汉模式在多线程下是不全的。
class Singleton
{
public:
//Singleton(const Singleton&temp )=delete;
static Singleton*get_instance()
{
if(instance==nullptr)
{instance=new Singleton;}
return instance;
}
void test()
{
cout << "测试"<<this << endl;
}
private:
Singleton()=default;
//Singleton(const Singleton&temp )=default;
Singleton(const Singleton&temp )=default;
Singleton& operator=(const Singleton&temp)=default;
static Singleton*instance;
};
Singleton*Singleton::instance=nullptr;
int main()
{
Singleton *obj1= Singleton::get_instance();
Singleton *obj2= Singleton::get_instance();
obj1->test();
obj2->test();
return 0;
}
//测试0x1fb01e91750
//测试0x1fb01e91750
#include <iostream>
#include <string>
#include<memory>
#include<mutex>
using namespace std;
//单例的 懒汉模式的实现--特点:第一次用类的实例才创建对象
//对于多线程环境下需要加锁实现实例的唯一性, 对于懒汉模式在多线程下是不安全的。
class Singleton
{
public:
static Singleton*get_instance()
{
if(instance==nullptr)
{
lock.lock();
if(instance==nullptr)
{instance=new Singleton;}
lock.unlock();
}
return instance;
}
void test()
{
cout << "测试"<<this << endl;
}
private:
Singleton()=default;
//Singleton(const Singleton&temp )=default;
Singleton(const Singleton&temp )=default;
Singleton& operator=(const Singleton&temp)=default;
static Singleton*instance;
static mutex lock;
};
Singleton*Singleton::instance=nullptr;
mutex Singleton::lock;//通过该类的默认构造函数来进行初始化,默认初始化为不上锁状态
int main()
{
Singleton *obj1= Singleton::get_instance();
Singleton *obj2= Singleton::get_instance();
obj1->test();
obj2->test();
return 0;
}
//测试0x1fb01e91750
//测试0x1fb01e91750
基础要点: 全局只有⼀个实例:static 特性,同时禁⽌⽤户⾃⼰声明并定义实例(把构造 函数设为 private) 线程安全 禁⽌赋值和拷⻉ ⽤户通过接⼝获取实例:使⽤ static 类成员函数
关于如何选择懒汉和饿汉模式:
懒汉:在访问量较⼩时,采⽤懒汉实现。这是以时间换空间。
饿汉:由于要进⾏线程同步,所以在访问量⽐较⼤,或者可能访问的线程⽐较 多时,采⽤饿汉实现,可以实现更好的性能。这是以空间换时间。
加了锁,使⽤互斥量来达到线程安全。这⾥使⽤了两个 if 判断语句的技术称为 双检锁;好处是,只有判断指针为空的时候才加锁,避免每次调⽤ getInstance 的⽅法都加锁,锁的开销毕竟还是有点⼤的。