תקציר: בפוסט זה תקבלו הצצה לאופן שבו Doxygen עוזר ליצור תיעוד יוצא דופן וכיצד הוא מאפשר לכם לכתוב קוד C/C++‎ בצורה מקצועית יותר.

Doxygen הוא כלי קוד פתוח המשמש ליצירת תיעוד עבור בסיס קוד של תוכנה. Doxygen תומך בשפות שונות, כולל C ו-C++‎. הוא יוצר את תיעוד התוכנה בפורמט HTML, pdf או Latex מתוך הקוד וההערות המעוצבות בתחביר התגיות (markup) של Doxygen.

באמצעות Doxygen, מפתח יכול לקבל הבנה מעמיקה יותר של הקוד שלו. Doxygen מאפשר לכם לנווט בקלות לאורך הקוד באמצעות קישורים מצולבים שנוצרים אוטומטית. בנוסף, פונקציות, namespaces, מבנים (structures), טיפוסי enum ודוגמאות קוד מסודרים בצורה מאורגנת בתיעוד.

למה כדאי לכם להשתמש ב-Doxygen עבור קוד C++‎?

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

דיאגרמות היררכיית מחלקות כאלה מאפשרות לכם לראות ליקויים בקוד שלכם ולהימנע מקוד “ספגטי”.

עיצוב תיעוד ה-Doxygen שלכם

Doxygen אכן נראה מעט מסובך בהתחלה, במיוחד אם תנסו להשתמש בו ולהגדיר אותו בעצמכם. עם זאת, אם אינכם רוצים לעשות עבודה מאומצת תוכלו פשוט להשתמש בכלי מקוון חינמי בשם CodeDocs שמגדיר עבורכם את הכול, ומאפשר לכם להתמקד בתוצאה הסופית – התיעוד (אזהרה: תצורת ה-Doxygen שמוגדרת על ידי CodeDocs אינה אידיאלית לדעתי עבור שפת C/C++‎, ולא תקבלו שום תמונות גרף. לשם כך, תצטרכו להגדיר כלי נוסף שעובד עם Doxygen בשם Dot, אבל זה אינו חלק מהיקף הפוסט הזה). על ידי עיון בתיעוד, מפתחים יכולים לשפר את הקוד שלהם באמצעות בחינת דיאגרמות היררכיית המחלקות. אינכם צריכים לעשות שום דבר מיוחד בקוד שלכם כדי ליצור את התיעוד הראשון שלכם. עם זאת, אם תרצו לעצב את התיעוד שנוצר, עליכם ללמוד כמה סגנונות הערות ספציפיים.

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

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

יצירת תרשימי זרימה ומכונות מצבים עם Doxygen

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

אז הדרך שבה תרשימי זרימה נוצרים מהקוד שלכם היא על ידי הוספת הערת בלוק המכילה סקריפט DOT. DOT הוא כלי צד שלישי ש-Doxygen משתמש בו ליצירת גרפים בתיעוד. אל דאגה; לא אשעמם אתכם בהסברים על איך לכתוב סקריפטים של DOT. למרבה המזל, שפת הסקריפט יחסית אינטואיטיבית ליצירת תרשימי זרימה, כפי שהראיתי למעלה. ותוכלו בקלות לשחק עם הסקריפט ולראות את הגרף משתנה בקישור המצוין הזה: https://edotor.net/

ואם אתם עדיין רוצים להעמיק בכל הניואנסים של DOT, תוכלו לגשת לתיעוד שלהם כאן: https://graphviz.org/documentation/

אתם אולי תוהים כיצד זה משתלב עם Doxygen? נניח שיש לכם פונקציה StateMachine(), שמנהלת מכונת מצבים בקוד שלכם. תוכלו להוסיף הערת בלוק מעל הפונקציה המתארת את מכונת המצבים הזו בשפת DOT. ואם תרצו ש-Doxygen “יזהה” את סקריפט ה-DOT שלכם, עליכם למקם אותו בין \dot ל-\enddot. הנה דוגמה לסקריפט שיצר את מכונת המצבים שלמעלה:

/*!

    State Machine dot graph:
    \dot
    digraph finite_state_machine {
        rankdir=LR;
        size="8,5"
  
        node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
        node [shape = circle];

        LR_0 -> LR_2 [ label = "SS(B)" ];
        LR_0 -> LR_1 [ label = "SS(S)" ];
        LR_1 -> LR_3 [ label = "S($end)" ];
        LR_2 -> LR_6 [ label = "SS(b)" ];
        LR_2 -> LR_5 [ label = "SS(a)" ];
        LR_2 -> LR_4 [ label = "S(A)" ];
        LR_5 -> LR_7 [ label = "S(b)" ];
        LR_5 -> LR_5 [ label = "S(a)" ];
        LR_6 -> LR_6 [ label = "S(b)" ];
        LR_6 -> LR_5 [ label = "S(a)" ];
        LR_7 -> LR_8 [ label = "S(b)" ];
        LR_7 -> LR_5 [ label = "S(a)" ];
        LR_8 -> LR_6 [ label = "S(b)" ];
        LR_8 -> LR_5 [ label = "S(a)" ];
    }
    \enddot
*/

void StateMachine()
{
    //Write some code here…
}

הגרף יופיע בפלט התיעוד שנוצר על ידי Doxygen בתוך התיאור של הפונקציה StateMachine().

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

כיצד זה משפר את איכות הקוד שלכם?

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

סיכום מסכם

מאמר זה מסביר כיצד Doxygen יכול לחלץ כמות גדולה של נתונים בעלי ערך מקוד C/C++‎ ולארגן אותם בצורה ידידותית למשתמש. כשמשתמשים בו נכון, Doxygen הוא כלי מצוין לתחזוקה וניהול של תיעוד הקוד שלכם.