תהיו נחמדים למשתמש הקצה. תניחו שאתם כותבים 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.