תבנית Singleton
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 54 מתוך 61.
לפעמים צריך מופע אחד בדיוק של אובייקט לאורך כל התוכנית: מנהל תצורה, מערכת רישום או חיבור למסד נתונים. תבנית Singleton מבטיחה שקיים רק מופע אחד ומספקת נקודת גישה גלובלית אליו.
ב־C, אנחנו מממשים זאת באמצעות משתנה static בתוך קובץ מקור. זכרו ש־static בהיקף הקובץ פירושו שהמשתנה פרטי לאותו קובץ ונשאר קיים לאורך כל חיי התוכנית. בשילוב עם פונקציית getter, הדבר יוצר את ה־Singleton שלנו:
// config.c
#include "config.h"
#include <stdlib.h>
struct Config {
int max_connections;
int timeout;
};
static Config* instance = NULL;
Config* get_config(void) {
if (instance == NULL) {
instance = malloc(sizeof(Config));
instance->max_connections = 100;
instance->timeout = 30;
}
return instance;
}הקסם מתרחש בתוך get_config(). הקריאה הראשונה יוצרת ומאתחלת את המופע. כל קריאה נוספת מחזירה את אותו מצביע.
מילת המפתח static מבטיחה ש-instance ישמור על ערכו בין קריאות לפונקציה ויישאר מוסתר מקבצים אחרים.
מהכותרת, המשתמשים רואים רק את פונקציית הקבלה. הם לא יכולים לגשת למשתנה הסטטי ישירות או לשנות אותו. לא משנה כמה פעמים או מאיפה קוראים ל־get_config(), תמיד מקבלים את אותו אובייקט.
אתגר
קלבואו נבנה מודול Settings שמנהל הגדרות כלליות של היישום באמצעות תבנית Singleton. לא משנה כמה פעמים הקוד שלך יבקש את ההגדרות, הוא תמיד אמור לקבל בדיוק את אותו מופע.
הקוד שלך יהיה מאורגן בשלושה קבצים:
settings.h: הצהר על טיפוס אטוםSettingsבאמצעות הצהרה מקדימה (גוף המבנה נשאר מוסתר). הצהר על פונקציהget_settingsשמחזירה מצביע למופע היחיד, וכן על פונקציות לקבלת ערכים ולעדכונם עבור שני ערכי תצורה:volume(מספר שלם) ו-brightness(מספר שלם). חשוב לכלול כאן הגנות הכללה.settings.c: כאן מתרחש הקסם. הגדר את מבנהSettingsבפועל, עם השדותvolumeו-brightness. צור משתנה מצביעstaticשיחזיק את המופע היחיד (ומאותחל ל-NULL). ממש אתget_settingsכך שהקריאה הראשונה תקצה ותאתחל את המופע לערכי ברירת המחדל (volume: 50, brightness: 75), ואילו קריאות נוספות פשוט יחזירו את המופע הקיים. ממש את פונקציות קבלת הערכים ועדכונם כדי לגשת לשדות המוסתרים ולשנות אותם.main.c: הדגם שתבנית Singleton פועלת כראוי. קרא שני מספרים שלמים שמייצגים ערכים חדשים של עוצמת הקול והבהירות. קרא ל-get_settingsפעמיים ושמור את התוצאות בשני משתני מצביע שונים. השתמש במצביע הראשון כדי לעדכן את עוצמת הקול והבהירות בערכי הקלט. לאחר מכן השתמש במצביע השני כדי לקבל ולהדפיס את שני הערכים. אם תבנית Singleton פועלת, השינויים שנעשו באמצעות מצביע אחד יהיו גלויים דרך המצביע האחר.
התוכנית שלך תקבל שני קלטים:
- הערך החדש של עוצמת הקול
- הערך החדש של הבהירות
הדפס את עוצמת הקול ואת הבהירות בשורות נפרדות, לאחר שינוי הערכים באמצעות מצביע אחד וקריאתם באמצעות מצביע אחר.
דוגמת פלט כאשר הקלטים הם 80 ו-100:
80
100דוגמת פלט כאשר הקלטים הם 25 ו-60:
25
60דוגמת פלט כאשר הקלטים הם 0 ו-50:
0
50התובנה המרכזית היא ששני המצביעים מצביעים לאותו אובייקט בזיכרון: זו מהות תבנית Singleton. המשתנה הסטטי בתוך קובץ המקור שלך מבטיח שקיים רק מופע אחד, והוא נשאר קיים במשך כל חיי התוכנית.
נסו בעצמכם
#include <stdio.h>
#include "settings.h"
int main() {
int new_volume, new_brightness;
scanf("%d", &new_volume);
scanf("%d", &new_brightness);
// TODO: קראו ל-get_settings פעמיים ושמרו את התוצאות בשני משתני מצביע שונים
// TODO: השתמשו במצביע הראשון כדי לעדכן את עוצמת הקול ואת הבהירות לפי ערכי הקלט
// TODO: השתמשו במצביע השני כדי לאחזר ולהדפיס את עוצמת הקול ואת הבהירות
// (זה מדגים ששני המצביעים מצביעים לאותו מופע יחיד)
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין