מטריקות בתכנות

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש

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

מטריקות בתכנות פרוצדורלי[עריכת קוד מקור | עריכה]

סיבוכיות מעגלית (Cyclomatic complexity)[עריכת קוד מקור | עריכה]

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

באופן מתמטי, סיבוכיות מעגלית של תוכנית מוגדרת בעזרת גרף הזרימה של התוכנית שמוגדר להיות גרף מכוון שמכיל את הבלוקים הבסיסיים של התוכנית, כאשר ישנה קשת מקודקוד אחד לשני אם קיים תרחיש שעבורו לאחר ביצוע השורה המייצגת את הקודקוד הראשון נבצע את השורה המייצגת את הקודקוד השני. הסיבוכיות M מוגדרת להיות: M = E-N+2P כאשר,

E - מספר הקשתות בגרף. V - מספר הקדקודים (בלוקים) בגרף. P - מספר רכיבי הקשירות בגרף.

דוגמה[עריכת קוד מקור | עריכה]

עבור הקוד הנ"ל אנו יכולים לראות כי מספר הקשתות בגרף 11 מספר הקודקודים 10 וישנו רכיב קשירות בודד ולכן נקבל כי M=11-10+1*2 = 3

גרף סיבוכיות מעגלית עבור הקוד
for (int i=0 ; i< N ; i++)
 cout<< i <<endl;
for (int i=0; i<N ; i++)
 cout<<i*i<<endl;















מספר שורות קוד (LOC)[עריכת קוד מקור | עריכה]

מספר שורות קוד (LOC) היא מטריקה למדידת גודל של תכנה על ידי ספירת מספר שורות הקוד בקוד המקור של התוכנית. מטריקה זו יכולה לתת לנו הערכה טובה למאמץ הנדרש לפיתוח התכנה ולתחזוקתה.

במטרקיה זו, אנו מודדים את מספר השורות הפיזיות ולא הלוגיות.

יש חסרון בהסתכלות על מספר השורות הפיזיות ולא הלוגיות.

לדוגמה, נסתכל על קטע הקוד הבא בשפת C:

for (i = 0; i < 100; i++) printf("hello");

בקוד זה יש שורה פיזית אחת ושתי שורות לוגיות

לעומת זאת, מתכנת אחר יכול לרשום את אותו הקוד בצורה הזאת:

for (i = 0; i < 100; i++)
{
 printf("hello");
}

בקוד הנ"ל יש 4 שורות קוד פיזיות ושתי שורות לוגיות.

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

סיבוכיות מערכתית (System complexity)[עריכת קוד מקור | עריכה]

סיבוכיות מערכתית (SYSC) משלבת הערכה בין סיבוכיות הפרוצדורות לבין הקשר ביניהם, המדידה מתבצעת במונחים של הקריאות לפרוצדורות, הפרמטרים המועברים ושימוש במידע בתוכן. יתרון של שיטה זו הוא בעובדה שניתן לחשב את הסיבוכיות המערכתית של הפרוצדורות ללא המימוש של כל המערכת. חיסרון של שיטה זו שהיא לא נותנת מידע אמיתי לגבי מידת הקושי לבצע שינויים במערכת קיימת. סיבוכיות מערכתית מורכבת מ-2 חלקים עיקריים:

  • סיבוכיות מיבנית (SC) - אנו רוצים לראות כמה קריאות יש לפרוצדורות אחרות בתוך הפרוצדורה ולפי זה להעריך את מידת הסיבוכיות המבנית.
SC יהיה שווה למספר הקריאות לפרוצדורות אחרות בתוך הפרוצדורה בריבוע.
  • סיבוכיות המידע (DS)- אנו רוצים להתחשב במספר הקלטים/פלטים שיש לפרוצדורה.
DS מוגדר להיות היחס בין מספר הקלטים/פלטים של פרוצדורה, לבין מספר מספר הקריאות לפרוצדורות אחרות בתוך הפרוצדורה ועוד 1.

הסיבוכיות המערכתית (SYSC) של אוסף פרוצדורות מוגדר להיות סכום ה-DC וה-CS של כל הפרוצדורות

ככל שהסיבוכיות המערכתית גדולה יותר, ככה צפויות להיות יותר תקלות (באג) בקוד.

מטריקות בתכנות מונחה עצמים[עריכת קוד מקור | עריכה]

Coupling metrics[עריכת קוד מקור | עריכה]

קשרים בין מחלקות (CBO)[עריכת קוד מקור | עריכה]

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

דוגמה

קשרים בין שיטות (RFC)[עריכת קוד מקור | עריכה]

Response set For Class עבור מחלקה, מוגדר להיות מספר המתודות בקבוצת כל המתודות שיכולות לפעול כתוצאה ממסר שנשלח לאובייקט המחלקה.


דוגמה בשפת Java:

Class 2DPoint{
 private int x;
 private int y;
 public 2DPoint(int x,int y){
 this.x = x;
 this.y = y;
 }
 public distance(int x1,int y1){
 return Math.sqrt(Math.pow((x-x1),2) + Math.pow((y-y1),2));
 }
 public distanceFromOrigin(){
 return this.distance(0,0);
 }
}

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

Cohesion metrics[עריכת קוד מקור | עריכה]

מטריקה זו באה למדוד כמה שיטות של המחלקה קשורות אחת לשנייה, נראה 2 שיטות כאלו:

חוסר קשר בין שיטות (LCOM)[עריכת קוד מקור | עריכה]

אנו רוצים למדוד את חוסר הקשר בין השיטות על ידי התבוננות בכמה משתנים מהמחלקה כל שיטה משתמשת. נניח שיש לנו מ שיטות במחלקה ויש סה"כ k משתנים במחלקה אז עבור כל שיטה נחשב את ה-LCOM שלה כך:
נסתכל על כל זוגות המשתנים אצלנו, נגדיר את P להיות מספר הזוגות (Ii, Ij), שהשיטה m משתמשת גם ב-Ii וגם ב-Ij , ונגדיר את Q להיות את כל השאר הזוגות, אז (|LCOM(m) = max(0, |P|-|Q. לקבלת ה-LCOM עבור המחלקה נסכום את כל ה-LCOM עבור כל השיטות שלה.

קשר בין שיטות (TCC)[עריכת קוד מקור | עריכה]

מה שאנו רוצים לבדוק בשיטה זו זה כמה שיטות משתמשות באותן המשתנים (כלומר יש ביניהם קשר כלשהו).
נגדיר NP להיות המספר המקסימלי של קשרים בין שיטות (כלומר מספר הזוגות של השיטות במחלקה).
נגדיר NDC להיות מספר הקשרים הישירים כלומר בכמה זוגות של שיטות יש שימוש באותו משתנה.
ונקבל כי TCC=NDC/NP, כלומר היחס בין הקשרים הישירים לבין מספר הקשרים שאפשרי. כאשר ככל שה-TCC קטן יותר ככה המחלקה פחות מורכבת.
ככלל אנו מבדילים בין מחלקות עם TCC שקטן מ-0.5 לבין מחלקות עם TCC שגדול מ-0.5.

מטריקות הורשה (Inheritance related measures)[עריכת קוד מקור | עריכה]

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

עומק עץ ההורשה (DIT)[עריכת קוד מקור | עריכה]

נגדיר עבור כל מחלקה את עומק עץ ההורשה שלה, כאשר ככל שהעומק גדול יותר ככה הסיכוי לבאגים גדל, הסיבה היא שככל שאנו יורדים בעץ ההורשה אנו מקבלים עוד שיטות ומשתנים מה"הורים" שלנו ולכן "מסבכים" את המחלקה.
סטטיסטית קרוב ל-83% מהמחלקות הן בעומק 0 או 1 וכל השאר בעומקים הגדולים מ-1 כפי שרואים בתרשים.

עומק עץ ממוצע










מספר ילדים למחלקה (NOC)[עריכת קוד מקור | עריכה]

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

קישורים חיצוניים[עריכת קוד מקור | עריכה]