facebook pixel מדריך: סגנון ה-API בכתיבת ספריות - www.4project.co.il
Main logo www.4project.co.il
כל הרכיבים לפרוייקט שלכם
עגלת קניות

העגלה ריקה

לקוחות נכבדים, אלה שעות הפעילות של המחסן במהלך פסח 2024:
ערב חג וחג ראשון (22-23/04) - המחסן סגור
חול המועד (24-25/04) - המחסן יפעל בין 8:00 עד 15:00
ערב חג וחג שני (28-29/04) - המחסן סגור
נחזור לפעילות רגילה ביום שלישי 30/04
חג שמח!

סגנון ה-API בכתיבת ספריות


2023-06-26 15:07:23
זהו מדריך בחירת API לספריות בסביבת הפיתוח Arduino. חלק מהדברים המוצגים כאן מנוגדים למה שנהוג בתכנות המקצועי. אנחנו מודעים לכך, אבל זה מה שגורם לכל כך הרבה מתחילים בתחום להתחיל לעבוד עם ה-Arduino בכזו פשטות, כך שתזכרו את העקרונות האלה כשאתם כותבים ספריה חדשה. אם יש לכם המלצות איך לגרום לספריות של Arduino להיות ברורים יותר לקהל היעד של המתחילים, אתם מוזמנים להשתתף בדיון בפורום. מדריך זה הוא לא סופי ונמצא בתהליך.

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

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

ארגנו את הפונקציות הפומביות (public) סביב הנתונים והפונקציונליות שהמשתמש מחפש. לעתים קרובות אוסף הפקודות עבור מודול אלקטרוני כלשהו הוא מסובך מדי עבור השימושים הנפוצים, או שהיה יכול להיות מאורגן סביב הפונקציונליות ברמה גבוהה יותר. תחשבו מה אדם ממוצע היה חושב שהדבר עושה ותנסו לארגן את פונקציות ה-API סביב זה. ספריה לרכיב BMP085 של Adafruit היא דוגמה טובה. פקודת ()readPressure עושה את כל הצעדים הנדרשים כדי להחזיר את הלחץ הסופי. הספריה עוטפת את  סדרת הפעולות שצריך לבצע בפקודה אחת שמחזירה את הערך שהמשתמש מחפש בפורמט שהוא מצפה לקבל. זה מחביא לא רק את הגישות לערוץ ה-I2C בשכבה הנמוכה, אלא גם חישובי טמפרטורה והלחץ בשכבה האמצעית, כאשר הפונקציות מהשכבה האמצעית עדיין זמינים למי שירצה להשתמש בהן.

השתמשו במילים יומיומיים ומלאים. אל תקצרו את שמות הפונקציות והמשתנים שלכם. השתמשו במושגים יומיומיים במקום מושגים טכניים מדי. בחרו במונחים המתאימים למה שמקובל בתחום הקשור למה שאתם עושים. אל תניחו ידע מיוחד. לדוגמה, זו הסיבה שבחרו בשם הפונקציה ()analogWrite במקום ()pwm. ראשי תיבות זה בסדר, אם השימוש בהם נפוץ או שהם מייצגים שם ראשי של משהו. לדוגמה, "HTML" הוא מאוד נפוץ ו-"SPI" הוא למעשה שם של הפרוטוקול (שימוש ב-serial-peripheral interface כנראה יהיה ארוך מדי). השם "Wire" הוא כנראה טעות מכיוון שהפרוטוקול שבשימוש בדרך כלל נקרא "TWI" או "I2C".

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

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

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

השתמשו בסגנון של ספריות הליבה המבוססות.
  • השתמשו ב-()read כדי לקלט ו-()write לפלט. לדוגמה ()digitalRead ו-()analogWrite.
  • השתמשו במחלקות Stream.h ו-Print.h בעבודה עם תקשורת נתונים. אם זה לא מתאים, לפחות תשתמשו במודל ה-API של המחלקות האלה. עוד פרטים בהמשך.
  • לתוכניות המשתמשות בתקשורת, השתמשו בספריות Client ו-Server כבסיס.
  • השתמשו ב-()begin כדי לאתחל אובייקט של הספריה, בדרך כלל לפי איזה שהם הגדרות. השתמשו ב-()end כדי לסיים אותו.

השתמשו באות ראשית לכל מילה בשמות, לא בקו תחתון. לדוגמה analogRead ולא analog_read. או myNewFunction ולא my_new_function. הסגנון אומץ ממערכת Processing.org כדי שיהיה קריא יותר.

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

נסו להימנע מפרמטרים בוליאניים (boolean). במקום זה תספקו שתי פונקציות שונות עם שמות שמתארים את ההבדלים ביניהן.

אל תניחו ידע והבנה במצביעים (pointers). עבור מתחילים בשפת C המחסום הגדול ביותר והמבלבל ביותר הם "*" ו-"&", כך שאם אפשר להימנע מהם ב-API, עשו זאת. דרך אחת להימנעות ממצביע היא הפניה למערך במקום ה-"*". לדוגמה, שורה זו:
קוד: בחר הכל
void printArray( char* array);


אפשר להחליף ב:
קוד: בחר הכל
void printArray(char[] array);


ישנם ספריות שאנחנו מעבירים אליהן מצביעים ל-struct, תנסו להימנע מגישה זו. לדוגמה, במקום:
קוד: בחר הכל
foo.readAccel(&x, &y, &z);


השתמשו במשהו כזה:
קוד: בחר הכל
xAxis = adxl.readX();

yAxis = adxl.readY();

zAxis = adxl.readZ();


כשאתם משתמשים בתקשורת טורית, אפשרו למשתמש לציין את האובייקט של מחלקת Stream במקום להשתמש ב-"Serial" בקוד שלכם. זה יגרום לספריה שלכם לתמוך בכל ה-Serial Ports בכרטיסי פיתוח Mega או Due ויאפשר להחליף את ערוץ התקשורת ל-SoftwareSerial. את האובייקט של מחלקת Stream אפשר להעביר לבונה (constructor) של הספריה או לפונקציה ()begin (כהפניה ולא כמצביע). ראו דוגמאות אלה לגישה זו:Firmata 2.3, XBee 0.4

כשכותבים ספריה שמטפלת בתקשורת נתונים, ירשו את המחלקה שלכם ממחלקת Stream, כך שאפשר יהיה להשתמש בספריה שלכם בכל ספריה אחרת שמקבלת אובייקט מסוג Stream. אם אפשר, שמרו את הנתונים הנכנסים בחוצץ (buffer), כך שפונקציה ()read תוכל לגשת לנתונים בחוצץ במלי שתצטרך לחכות להגעת נתונים חדשים. אם אפשרי, פונקציית ()write צריכה לכתוב את הנתונים לחוצץ השידור, אבל אם החוצץ מלא, היא צריכה לחכות כדי שיהיה מספיק מקום לשמור את כל המידע הנשלח. צריך לקרוא לפונקציית ()yield בזמן ההמתנה.

הנה כמה דוגמאות של ספריות מ-Adafruit שיכולות לשמש כדוגמה: BMP085, DHT. הספריות מחלקות את הפונקציונליות של המכשירים לרמות בצורה טובה.

ספריית RTClib עושה הפשטה טובה לספריית Wire (I2C).


ראו גם:

פירוט שפת תכנות לסביבת Arduino


עמוד זה הוא תרגום של Arduino Style Guide for Writing Libraries לפי רישיון Creative Commons Attribution-ShareAlike 3.0.