לדלג לתוכן

הזרקת תלויות מוסברת - Dependency Injection לבקאנד

יש דפוס מסוים שכמעט כל מפתח כותב בטעות בהתחלה, ואז מגלה שהוא הופך את הקוד לסיוט לבדיקה ולתחזוקה. זה קורה כשמחלקה או פונקציה בונה בעצמה, מבפנים, את כל מה שהיא צריכה כדי לעבוד. Dependency Injection, או בעברית הזרקת תלויות, הוא פתרון פשוט להפליא לבעיה הזו, והוא אחד מאותם רעיונות שברגע שהם "נדלקים" אצלכם, אתם מתחילים לראות אותם בכל מקום.

הבעיה - מחלקה שבונה את התלויות שלה בעצמה

תארו לעצמכם שירות שאחראי לשלוח מייל אישור הרשמה למשתמש חדש. הדרך הכי אינטואיטיבית לכתוב את זה היא שהמחלקה שאחראית על ההרשמה יוצרת בתוכה, ישירות, אובייקט של שולח מיילים אמיתי, ומשתמשת בו. זה עובד, אבל זה יוצר בעיה שקטה - המחלקה הזו עכשיו קשורה בחוזק לאותו שולח מיילים ספציפי, ואין שום דרך פשוטה להחליף אותו.

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

הפתרון - להזריק במקום ליצור

הפתרון הוא לשנות כיוון - במקום שהמחלקה תיצור את התלות שלה בעצמה מבפנים, מישהו מבחוץ מעביר לה אותה מוכנה, בדרך כלל דרך פרמטר בבנאי. המחלקה כבר לא אחראית לדעת איך בונים שולח מיילים, היא רק אחראית להשתמש במשהו שכבר עונה על ממשק מסוים של "שליחת מייל" - ולא משנה לה מי בדיוק בנה אותו ואיך.

דוגמה - לפני ואחרי

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

בגישה עם הזרקת תלויות, מחלקת שירות ההרשמה מקבלת בבנאי שלה פרמטר בשם "שולח מיילים", שומרת אותו כשדה פנימי, ובפעולת ההרשמה פשוט משתמשת באותו שדה כדי לשלוח את המייל, בלי לדעת ובלי להתעניין איך הוא נוצר. מי שבונה את מחלקת ההרשמה - בקוד האמיתי של האפליקציה, בהרצה רגילה - הוא זה שמעביר לה שולח מיילים אמיתי. מי שבונה אותה בבדיקה יכול להעביר לה במקום זאת גרסה מזויפת, שרק זוכרת אילו קריאות בוצעו אליה בלי לשלוח שום דבר באמת.

השינוי נראה קטן, כמעט טכני, אבל הוא הופך מחלקה נעולה עם תלות קשיחה למחלקה גמישה שאפשר להרכיב אותה עם כל תלות שמתאימה למצב.

למה זה עוזר בבדיקות ובגמישות

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

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

מיכל הזרקת תלויות - DI Container

בשפות ובפריימוורקים רבים קיימים כלים ייעודיים שנקראים "מיכלי הזרקת תלויות", שתפקידם לנהל אוטומטית את כל התהליך הזה - להחליט אילו תלויות להעביר לאיזו מחלקה, ולבנות את כל העץ הזה בשבילכם בלי שתצטרכו לחווט הכל ידנית. הכלים האלה נוחים מאוד בפרויקטים גדולים עם עשרות ומאות מחלקות תלויות זו בזו.

אבל חשוב להבין - הרעיון המרכזי של הזרקת תלויות הוא פשוט ושימושי גם בלי שום מיכל וגם בלי שום ספרייה ייעודית. אפשר להתחיל ליישם אותו בכל פרויקט, בכל שפה, פשוט על ידי החלטה מודעת להעביר תלויות דרך הבנאי במקום ליצור אותן מבפנים. הכלים הייעודיים באים אחר כך, כשהעץ נהיה גדול מספיק כדי שכדאי לנהל אותו אוטומטית.

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

לסיכום

הזרקת תלויות היא בעצם החלטה פשוטה - להעביר תלויות למחלקה מבחוץ במקום לתת לה ליצור אותן בעצמה מבפנים. ההחלטה הקטנה הזו היא ההבדל בין קוד נעול וקשה לבדיקה לבין קוד גמיש שאפשר להחליף בו חלקים ולבדוק אותו בקלות.

יש לכם דוגמה מהקוד שלכם שבה הזרקת תלויות פתרה כאב ראש? ספרו לנו על זה בדיסקורד.

הצטרפו לקהילה בדיסקורד