单例模式是最简单的设计模式之一,顾名思义,整个系统中每个结构体只有一个实例存在,不能再多,否则就不叫单例。单例模式只应在有真正的“单一实例”的需求时才可使用。
场景:timo和gg都是同一个公司的职员,今天需要去找老板签署文件。
例1:传统代码实现:
附例1代码:
//小问学编程
#include <stdio.h>
//定义boss的行为
typedef struct BOSS
{
void (*vfunc)();
}s_boss;
void sign(char * str)
{
printf("老板给%s签署文件\n",str);
}
s_boss* boss;
void main()
{
//timo找老板签文件
boss = (s_boss *)malloc(sizeof(s_boss));
boss->vfunc = sign;
boss->vfunc("timo");
//释放内存
free(boss);
//gg找老板签文件
boss = (s_boss *)malloc(sizeof(s_boss));
boss->vfunc = sign;
boss->vfunc("gg");
//释放内存
free(boss);
}
试想其他的员工也这样找老板签字,那频繁地创建及销毁BOSS这个结构体的话,势必会降低系统的运行效率。
解决方案:
使用单例模式,封装boss的创建过程,系统中只需要维护唯一BOSS结构体即可减少系统的性能开销。
例2:单例实现:
附例2代码:
//小问学编程
#include <stdio.h>
//定义boss的行为
typedef struct BOSS
{
void (*vfunc)();
}s_boss;
void sign(char * str)
{
printf("老板给%s签署文件\n",str);
}
//统一访问boss的接口
void* get_boss()
{
static s_boss * boss = NULL;
//如果系统已经存在对象,直接返回对象指针
if(NULL != boss)
return boss;
//第一次访问时创建对象
boss = (s_boss *)malloc(sizeof(s_boss));
//初始化对象行为
boss->vfunc = sign;
return (void*)boss;
}
int main()
{
//timo找老板签文件
s_boss * boss;
boss = get_boss();
boss->vfunc("timo");
//gg找老板签文件
boss = get_boss();
boss->vfunc("gg");
}
单例模式的主要优点在于提供了对唯一实例的受控访问并可以节约系统资源;其主要缺点在于因为缺少抽象层而难以扩展。
单例模式适用情况包括:
1、系统只需要一个实例对象;
2、客户调用对象的单个实例只允许使用一个公共访问点。