קריא, נכון או גם וגם?
בעולם אידאלי הגירסא הנכונה של קוד היא גם הקריאה ביותר. בחיים האמיתיים לא תמיד. נכתוב לדוגמא פונקציה ב JavaScript המקבלת משפט ורשימה של מילים ומחזירה משפט חדש שמורכב רק מהמילים שנמצאות ברשימה. דוגמת שימוש:
// prints: new world
console.log(wordsFromList('a brave new world', ['world', 'new']);
דרך קלה לפתור את זה היא להשתמש בפונקציה Array.includes
של השפה. הבעיה שברשימות גדולות סריקה של כל המערך מתחילתו עבור כל מילה אינה יעילה. לכן מקובל במצבים כאלה להמיר את הרשימה למבנה נתונים שמאפשר חיפוש מהיר. הפיתרון הקלאסי ב JavaScript הוא Object וכך נקבל:
function wordsFromList(sentence, words) {
const wordsObject = {};
words.forEach(word => { wordsObject[word] = true; });
return sentence.split(' ').filter(word => wordsObject[word]).join(' ');
}
וזה עובד בדוגמא שלנו. אבל ממש לא נכון במקרה הכללי. מוזמנים לקחת תרגיל ולמצוא כמה שיותר טעויות בקוד.
העניין שככל שנפתור יותר מהטעויות הקוד יהפוך לקצת יותר מוזר, עם טיפול בעוד מקרה קצה שיסיח את הדעת מהמנגנון האמיתי. הפיתרון? ארגון מחדש של הקוד:
function wordsFromList(sentence, words) {
const wordsList = new WordsList(words);
const breakableSentence = new Sentence(sentence);
return breakableSentence.filterWords(word => wordsList.includes(word)).toString();
}
כן הרחבנו את עולם המושגים של התוכנית. כן הוספנו עוד שתי מחלקות (שעוד צריך לכתוב את הקוד שלהן). אבל הכי חשוב הזזנו את כל הבאגים רחוק מתיאור המנגנון. עכשיו אתם יכולים ללכת ל WordsList ולהחליף שם את מבנה הנתונים ל Set; ואתם יכולים ללכת ל Sentence ולבנות שם מנגנון נורמלי ששובר משפט למילים ויודע גם לחבר אותן חזרה.
טיפול במקרי הקצה הכרחי אם רוצים לכתוב קוד נכון, אבל הוא לא חייב להופיע באמצע הפונקציה שמתארת מה אנחנו עושים.