模式動機
單例模式是最簡單的設計模式之一,顧名思義,整個系統中每個結構體只有一個實例存在,不能再多,否則就不叫單例。單例模式只應在有真正的“單一實例”的需求時纔可使用。
場景: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、客戶調用對象的單個實例只允許使用一個公共訪問點。