בכל זאת, אנסה לכתוב פוסט קצר על תבנית עיצוב בשם Null Object.יש לנו מסורת ב SAP, להעביר פעם בשנה קורס “תבניות עיצוב” (Design Patterns) לעובדים החדשים. חלקם מכירים את הנושא – אבל תמיד יש מה לשפר. אני כותב פוסט זה תוך כדי הכנה של החלק שלי בקורס.
האמת? יש לי הסתייגות פנימית קלה מנושא תבניות העיצוב: תבניות עיצוב הוא תחום שעלול לגרום ליותר נזק מתועלת – כאשר מנסים “לדחוף כמה שיותר תבניות עיצוב במטר מרובע”, וזה יכול לקרות הרבה.
מצד שני, כשמתבגרים ונרגעים ניתן להשתמש בהן בצורה מאוזנת ומועילה. חוץ מזה: זה נושא שאנשים רוצים לדעת היטב – ומי אני שאמנע מהם? האם אני הייתי מוכן לוותר על להכיר את הנושא? בטח שלא!
בקורס, אנו מנסים להדגיש את הנקודות החשובות הבאות:
- תבניות עיצוב כשפה רק עבור התקשורת הפשוטה, כדאי ללמוד תבניות עיצוב: “ה class הזה הוא בעצם כמו Strategy” יכול להגיד המון למי שמכיר את ה Pattern או לגרור דיון של כמה דקות – למי שלא.
- תבניות עיצוב כתיקון למצב בעייתי, או מה שנקרא Refactoring To Patterns: כדאי ומומלץ להימנע משימוש בתבניות עצוב במחשבה על “מצב עתידי”, קרי “יהיה יותר קל לטפל גם במספר רב של אובייקטים אם נשתמש כאן ב Composite“. חכו שיהיה מצב בו יש מספר רב של אובייקטים – ורק אז עשו Refactoring ל Composite.
ההמלצה היא לזהות צורך מיידי ש Pattern יכול לפתור, או לסירוגין smell בקוד שנובע מאי-שימוש ב Pattern ורק אז לעשות refactoring ולהכניס את ה Pattern.

קצת על null בג’אווהסקריפט
ג’אווהסקריפט הופכת לשפה משמעותית עבורנו – ולכן הדוגמאות שאספק יהיו בעיקר מעולם זה. לא מעניין אתכם javaScript או ה nulls שלה – דלגו ל section הבא.
למה “nulls” ולא “null“? כי יש כמה כאלו בג’אווהסקריפט. תלוי את מי שואלים, יש שניים או שלושה, אני אציג את נקודת המבט המחמירה:
- יש ערך “null“, שמשמעותו היא “נקבע למשתנה זה ערך ריק / חסר משמעות”. בניגוד לג’אווה זהו איננו ערך ברירת המחדל למשתנים.
- יש ערך “undefined” ששמו דיי מבלבל: נשמע שהוא מתאר משתנים שלא הוגדרו – אך בעצם הוא נקבע כערך ברירת מחדל למשתנים שהוגדרו אך לא נקבע להם ערך. שם מוצלח יותר היה יכול להיות unassigned.
- יש מצב בו לא הוגדר משתנה. אפשר לקרוא לו “בום!“: ניסיתם לגשת למשתנה, אפילו בזהירות? – ייזרק error. שם שהייתי מעדיף לכזה משתנה הוא undefined, אבל השם כבר תפוס. זה לא בדיוק null value, אבל הוא דורש התגוננות דומה (ונוספת).
אבל… מה קורה עם משתנה z שלא הגדרתי (כלומר הוא: truly undefined)?
הערה: גישה למשתנה גלובאלי בצורה .window היא דווקא בטוחה בפני ReferenceError. תודה לקורא שתיקן אותי.
- אולי אלו 2: null ו undefined
- אולי אלו 2: null/undefined ו truly undefined
- אולי אלו 3.
תלוי את מי שואלים….
מה הבעיה עם null?
טוני אוהר’ה, מי שהמציא את הקונספט בשפת ALGOL איפשהו בשנות השישים, אומר שזו פשוט הייתה עצלנות. “לא היה לי זמן למצוא פתרון יותר אלגנטי באותה התקופה”. הוא קורא להחלטה ליצור את null טעות, ולא סתם טעות: “טעות מיליארד הדולר שלי” (טריליון דולר – בתרגום למונחים ראליים של היום). איזה נזק לתעשייה כולה! ומאז ששפת C החליטה לאמץ את הרעיון – אבדה הדרך חזרה…

מה עושים?
עדכון יוני 2014:
אפל הודיעה על שפת Swift, שתחליף עם הזמן את Objective-C לפיתוח OS X/iOS ומה שאומר שצפוי לה שימוש נרחב. מה הקשר? ב Swift משתנים לא יכולים להיות nil אלא אם הוגדרו כ Option Type (מה שנקרא גם “Maybe”) – שבתחביר השפה זהו סימן שאלה בסוף – למשל ?Int. פתרון מאוד אלגנטי לטעמי לעניין ה null!
התחביר דוגמה מאוד ל nullable types ב #C – תחביר המאפשר nulls ב primitives. כלומר – עשו שם רק את החצי הקל של העבודה…
סיכום
- התרגלנו (בעצם: נולדנו) לעולם בו פונקציות עלולות להחזיר null בכל רגע, וללא התראה.
- null יכול להפתיע בכל מקום בקוד – מה שהופך אותו לבעיית תחזוקה קשה.
- NullObject יכול לעזור.
- לצמצם הפתעות.
- להוסיף סמנטיקה עשירה יותר למצב ה null.
- NullObject הוא לא מושלם: הוא דורש מעט יותר עבודה. מומלץ לשימוש באופן מקיף במערכת שמתקרבת לשלב התחזוקה (לא MVP).
תודה רבה !! מענין מאד ומעורר מחשבה.רק הערה קטנה בנוגע להערתך על javascript:\”יש לעשות בדיקה מקיפה זו כל פעם שניגשים (פעם ראשונה?!) למשתנה במרחב הגלובלי, קרי .window.\”לדעתי אם ניגשים ל- .window אין צורך בבדיקה הארוכה אך אם רוצים לגשת ישירות ל- ולא באמצעות ה-window יש להוסיף את הבדיקה הארוכה.לדוגמא – window.xxxxxxx לא יזרוק שגיאה אך – xxxxxxx יפול.תכל'ס זה לא כ\”כ משנה לרעיון העיקרי של הפוסט – סתם הערה שולית… :)שוב תודה, היה מענין!
אתה בהחלט צודק. אתקן.תודה על ההערה!ליאור
הי ליאור.שפת Ceylon של רד הט מיישמת nullable ref types . כמו כן, אף דיון ב nullable לא שלם בלי maybe monad, ע\”ג למ(ב)דות. ממליץ בחום להרחיב את הפוסטיואב
היי אנונימי,אני באמת לא מכיר.אם תשלח לי תקציר בנושא – אוכל לערוך אותו ולהוסיף אותו לפוסט.תודה,ליאור
סליחה – יואב.
בג'אווה יש מימוש חלקי לגישה הזאת.אני מקפיד להחזיר Collections.emptyList במקום null