טבלת Singleton
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 63 מתוך 70.
לפעמים צריך מופע אחד בדיוק של משהו בכל התוכנית: מנהל תצורה, מערכת רישום או הגדרות משחק. יצירת עותקים מרובים עלולה לגרום לבעיות: לאיזה מהם יש את הנתונים הנכונים? תבנית Singleton מבטיחה שקיים רק מופע אחד.
ב-Lua, מימוש Singleton פשוט להפליא בזכות אופן הפעולה של מודולים. כשאתה מפעיל require על מודול, Lua שומרת במטמון את התוצאה. קריאות עוקבות ל-require מחזירות את הטבלה השמורה במטמון, ולא טבלה חדשה.
-- GameConfig.lua
local GameConfig = {
volume = 80,
difficulty = "normal"
}
function GameConfig:setVolume(v)
self.volume = v
end
return GameConfig
כעת, בכל מקום בתוכנית שלך:
local config1 = require("GameConfig")
local config2 = require("GameConfig")
config1:setVolume(50)
print(config2.volume) -- 50 (אותה טבלה!)
גם config1 וגם config2 מפנים לאותה הטבלה בדיוק. שינויים שנעשים דרך משתנה אחד גלויים דרך המשתנה האחר. הדבר קורה באופן אוטומטי, משום ש-require של Lua שומר את הערך המוחזר ב-package.loaded ומשתמש בו שוב.
בשונה מתבנית Factory שיוצרת אובייקטים חדשים, Singleton מבטיח מצב משותף בכל היישום שלך. הדבר אידיאלי להגדרות גלובליות שחלקים שונים בקוד שלך צריכים לגשת אליהן ולשנות אותן באופן עקבי.
אתגר
קלבואו נבנה מנהל הגדרות למשחק באמצעות תבנית Singleton! תיצרו מודול הגדרות שמבטיח שכל חלק בתוכנית שלכם ניגש לאותן הגדרות בדיוק, בלי קשר למספר הפעמים שבהן הוא נדרש.
תארגנו את הקוד שלכם בשני קבצים:
GameSettings.lua: צרו מודול Singleton ששומר את הגדרות המשחק. טבלת ההגדרות שלכם צריכה לכלול אתmusicVolume(מתחיל ב־70), אתsfxVolume(מתחיל ב־100) ואתdifficulty(מתחיל ב־"normal"). הוסיפו שלוש מתודות::setMusicVolume(value),:setSfxVolume(value)ו־:setDifficulty(level)כדי לשנות את ההגדרות האלה. זכרו להחזיר את הטבלה בסוף המודול!main.lua: הדגימו ש־Singleton פועל באמצעות דרישה של מודול GameSettings פעמיים לתוך משתנים שונים. השתמשו במשתנה הראשון כדי לשנות את עוצמת המוזיקה ואת רמת הקושי. לאחר מכן השתמשו במשתנה השני כדי להדפיס את כל שלוש ההגדרות. אם Singleton פועל כראוי, שני המשתנים מפנים לאותה טבלה, ולכן שינויים שנעשים באמצעות אחד מהם גלויים גם באמצעות האחר.
תקבלו שתי קלטים:
- עוצמת מוזיקה חדשה (מספר)
- רמת קושי חדשה (מחרוזת כמו
"easy"או"hard")
לאחר שינוי ההגדרות באמצעות המשתנה הראשון, הדפיסו את שלוש ההגדרות באמצעות המשתנה השני, כל אחת בשורה נפרדת ובסדר הזה: עוצמת המוזיקה, עוצמת אפקטי הקול ואז רמת הקושי.
לדוגמה, אם הקלטים הם 50 ו־hard, הפלט צריך להיות:
50
100
hardאם הקלטים הם 25 ו־easy, הפלט צריך להיות:
25
100
easyשימו לב שעוצמת אפקטי הקול נשארת בערך ברירת המחדל שלה, 100, מכיוון שלא שינינו אותה, אבל עוצמת המוזיקה ורמת הקושי משקפות את השינויים שנעשו באמצעות המשתנה הראשון. כך מוכח ששני המשתנים מצביעים לאותו מופע Singleton!
נסו בעצמכם
-- main.lua - הדגמת תבנית Singleton
-- קריאת הקלט
local newMusicVolume = tonumber(io.read())
local newDifficulty = io.read()
-- TODO: טענו את המודול GameSettings למשתנה (למשל, settings1)
-- TODO: טענו את המודול GameSettings שוב למשתנה אחר (למשל, settings2)
-- (אם Singleton פועל כראוי, שני המשתנים מפנים לאותה טבלה!)
-- TODO: השתמשו במשתנה הראשון כדי:
-- - להגדיר את עוצמת המוזיקה לערך newMusicVolume
-- - להגדיר את רמת הקושי לערך newDifficulty
-- TODO: השתמשו במשתנה השני כדי להדפיס את ההגדרות
-- הדפיסו כל אחד בשורה נפרדת: musicVolume, sfxVolume, difficulty
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4פרויקט: בנק דיגיטלי
הגדרת הפרויקטפעולת הפקדה7פולימורפיזם ודריסת מתודות
דריסת מתודותקריאה למתודות של מחלקת האבטיפוסיות ברווזממשק משותףבדיקת טיפוססיכום – תפקידי עובדים2תבנית אב־טיפוס למחלקה
מושג אב־הטיפוסקישור באמצעות __indexהבנאי :new()אתחול מאפייניםמופעים עצמאייםסיכום – מפעל מכוניות5העמסת אופרטורים בתכנות מונחה עצמים
חיבור אובייקטיםחיסור אובייקטיםשרשור אובייקטיםהשוואת אובייקטים (<, >)חזרה – חישובים עם ארנק8כימוס
כללי מתן שמותClosures לשמירה על פרטיותגישה באמצעות Closuresטבלאות לקריאה בלבדלוגיקת אימותסיכום – כספת מאובטחת11תבניות עיצוב (בקצרה)
פונקציות Factoryטבלת Singletonתבנית IteratorObserver (מאזין)סיכום – מפעל Logger3מצב והתנהגות של אובייקטים
משתני מופעמתודות Getterמתודות Setterמאפיינים מחושביםעיצוב מחרוזותבדיקות שוויוןסיכום – ציון תלמיד6יסודות הירושה
הכנת מבנה הירושהירושת מתודותהרחבת הבנאיהוספת מתודות למחלקת הבתמשותף לעומת ייחודיסיכום – היררכיית צורותתרגלו בעצמכם: קומפיילר Lua אונליין