הנדסת תוכנה |
---|
ערך זה שייך לקטגוריית הנדסת תוכנה |
פעילויות ושלבים |
דרישות • ניתוח • אפיון • ארכיטקטורה • עיצוב • תכנות • ניפוי שגיאות • בדיקה • אימות • בנייה • פריסה • תפעול • תחזוקה |
מתודולוגיות |
זריזות • מפל המים • תכנת ותקן • Crystal Clear • Scrum • Unified Process • Extreme Programming • אינטגרציה רציפה • DevOps |
תחומים תומכים |
ניהול פרויקטים • ניהול תצורה • תיעוד • הבטחת איכות • Profiling |
כלים |
מהדר • מקשר • מפרש • IDE • ניהול גרסאות • אוטומציית בנייה |
תכנות לפי חוזה (באנגלית: Design by Contract, בקיצור: DbC) היא שיטת עיצוב תוכנה, המתבססת על הגדרת מפרטים פורמליים, מדויקים וניתנים לאימות עבור ממשקים של רכיבי תוכנה. בשיטת עבודה זו, רכיבי התוכנה הם טיפוסי נתונים אבסטרקטיים, הדורשים קיום של תנאים מוקדמים (preconditions), תנאים מאוחרים (postconditions), וקבועים (invariants). מפרטים אלו נקראים "חוזים", כמטפורה לתנאים ולמחויבויות הקיימים במסגרת חוזה עסקי.
על פי שיטה זו, רכיבי התוכנה משתפים פעולה זה עם זה על בסיס "מחויבויות" ו"רווחים" הדדיים. בדומה לעולם העסקי, מוגדרים "ספק" ו"לקוח" המסכימים ביניהם על "חוזה" המגדיר דברים כמו:
באופן דומה, בתכנות מונחה-עצמים, אם שגרה במחלקה מספקת פונקציונליות מסוימת, היא יכולה:
החוזה הוא פורמליזציה של מחויבויות ורווחים אלו. ניתן לסכם גישה זו על ידי "שלוש שאלות" שהמתכנת צריך לחזור ולשאול את עצמו לגבי החוזה:
שפות תכנות רבות מספקות תמיכה מובנית לבדיקת טענות נכונות (assertions), המאפשרות לבדוק את העמידה בתנאים של החוזה. עם זאת, גישת ה"תכנות לפי חוזה" רואה בחוזים חשיבות מכרעת לתקינות התוכנה, כך שהם אמורים להיות חלק כבר בתהליך התכנון. למעשה, התומכים בתכנות לפי חוזים, כותבים את ה-assertions לפני המימוש העיקרי של התוכנה. (ראו: פיתוח מונחה-בדיקות).
רעיון ה"חוזה" יורד עד לרמת המתודה/פרוצדורה. החוזה עבור מתודה מסוימת יתאר בדרך כלל את הפרטים הבאים:
בשימוש בירושה, המחלקה היורשת מורשית להרפות את התנאים המוקדמים (אבל לא להקשות אותם), והיא רשאית להקשיח את התנאים המאוחרים (אבל לא להחליש אותם).
כל היחסים בין מחלקות הם בין מחלקות "לקוח" לבין מחלקות "ספק". מחלקת לקוח מחויבת לבצע את הקריאות לשירותים של הספק כך שהמצב של הספק לא יופר על ידי קריאת הלקוח. עם זאת, הספק מחויב לספק "מצב החזרה" ונתונים שאינם מפרים את דרישות המצב של הלקוח. לדוגמה, חוצץ הנתונים (buffer) של הספק יכול לדרוש שהנתונים אכן ימצאו בחוצץ בזמן קריאה לשירות מחיקה של נתונים. בהמשך, הספק מבטיח ללקוח שכאשר שירות המחיקה מסיים את העבודה, הנתונים אכן ימחקו מהחוצץ. חוזים אחרים מגדירים את "קבועי המחלקה". קבוע המחלקה מבטיח (למחלקה המקומית) כי בסיום הריצה של כל אחד מהשירותים, המצב של המחלקה יישמר במסגרת טווח מוגדר מראש של מצבים.
כאשר משתמשים בחוזים, הספק לא אמור לנסות לוודא שתנאי החוזה מתממשים; הרעיון הכללי הוא שבמקרה של חריגה מתנאי החוזה, הקוד אמור "להכשל חזק", ווידוא החוזה אמור להיות רק "רשת הביטחון". ה"כישלון החזק" בשיטת התכנות לפי חוזים מקל על ניפוי שגיאות כאשר ההתנהגות הצפויה של כל שגרה מפורטת בצורה ברורה. זהו הבדל בולט לעומת שיטה דומה הנקראת defensive programming ("תכנות מתגונן"), בה הספק אחראי על ההחלטה מה לעשות כאשר אחד מהתנאים המוקדמים מופר. בדרך כלל, הספק זורק חריגה (exception) על מנת להודיע ללקוח שאחד מהתנאים המוקדמים אינו מתקיים. בשני המקרים - "תכנות לפי חוזה" ו"תכנות מתגונן" - הלקוח אמור להחליט כיצד הוא מגיב למצב כזה. תכנות לפי חוזה מקל על עבודת הספק.
תכנות לפי חוזה מסייע גם בשימוש חוזר (reuse) בקוד, מאחר שהחוזה עבור כל יחידת קוד מתועד במלואו. החוזים של מודול מסוים יכולים להחשב כסוג של דוקומנטציה של ההתנהגות עבור מודול זה.
תנאי החוזה לעולם לא אמורים להיות מופרים בזמן הריצה של תוכנה נקייה מבאגים. לפיכך, החוזים נבדקים בדרך כלל רק ב-debug mode, בזמן הפיתוח של התוכנה. מאוחר יותר, בשחרור התוכנה, מבטלים את בדיקות החוזה על מנת לשפר את הביצועים.
בשפות תכנות רבות, חוזים ממומשים עם בדיקות נכונות (asserts). כברירת מחדל, בדיקות אלה לא עוברות הידור ב-release mode ב-++C/C, ומבוטלות באופן דומה ב-C#/Java. זה מבטל את עלויות זמן הריצה של שימוש בחוזים בגרסת ה-release.
תכנות לפי חוזה אינו מחליף שיטות רגילות לבדיקות תוכנה כדוגמת בדיקות יחידה, בדיקות אינטגרציה ובדיקות מערכת. ליתר דיוק, השיטה משלימה לבדיקות תוכנה חיצוניות על ידי הוספת בדיקות-עצמיות פנימיות שניתן להפעיל הן עבור בדיקות נפרדות והן בתוכנה המוגמרת בזמן שלב הבדיקות. היתרון בבדיקות עצמיות פנימיות הוא בכך שהן יכולות לגלות שגיאות לפני שהן מופיעות בצורה של תוצאות שגויות הנראות ללקוח. זה מוביל לגילוי שגיאות מוקדם וספציפי יותר.