Menu
Coddy logo textTech

תבנית 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(), תמיד מקבלים את אותו אובייקט.

challenge icon

אתגר

קל

בואו נבנה מודול 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 פועלת, השינויים שנעשו באמצעות מצביע אחד יהיו גלויים דרך המצביע האחר.

התוכנית שלך תקבל שני קלטים:

  1. הערך החדש של עוצמת הקול
  2. הערך החדש של הבהירות

הדפס את עוצמת הקול ואת הבהירות בשורות נפרדות, לאחר שינוי הערכים באמצעות מצביע אחד וקריאתם באמצעות מצביע אחר.

דוגמת פלט כאשר הקלטים הם 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;
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C אונליין