模式动机
单例模式是最简单的设计模式之一,顾名思义,整个系统中每个结构体只有一个实例存在,不能再多,否则就不叫单例。单例模式只应在有真正的“单一实例”的需求时才可使用。
场景:timo和gg都是同一个公司的职员,今天需要去找老板签署文件。
传统代码实现:
#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); }
代码可以直接复制粘贴在菜鸟 C 在线工具运行(https://c.runoob.com/compile/11)中查看运行结果。结果如下:
老板给timo签署文件
老板给gg签署文件
试想其他的员工也这样找老板签字,那频繁地创建及销毁BOSS这个结构体的话,势必会降低系统的运行效率。
解决方案
使用单例模式,封装boss的创建过程,系统中只需要维护的唯一BOSS结构体即可,减少系统的性能开销。
#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;
}
void main()
{
//timo找老板签文件
s_boss * boss;
boss = get_boss();
boss->vfunc("timo");
//gg找老板签文件
boss = get_boss();
boss->vfunc("gg");
}
代码可以直接复制粘贴在菜鸟 C 在线工具运行(https://c.runoob.com/compile/11)中查看运行结果。结果如下:
老板给timo签署文件
老板给gg签署文件
单例模式的主要优点在于提供了对唯一实例的受控访问并可以节约系统资源;其主要缺点在于因为缺少抽象层而难以扩展
单例模式适用情况包括:
1、系统只需要一个实例对象;
2、客户调用对象的单个实例只允许使用一个公共访问点。