כפל קוד ואבסטרקציה לא נכונה

27/06/2026

במאמר בנושא אבסטרקציות בתקופה שמפתחים עוד כתבו קוד סנדי מץ מתארת את התרחיש הנפוץ הבא:

  1. מפתח A רואה את אותו קוד מופיע בשני מקומות. מוציא לפונקציה משותפת ושמח על החסכון בקוד.

  2. הזמן עובר ונכנסת דרישה חדשה למערכת.

  3. מפתח B מזהה שהקוד כמעט מתאים לדרישה החדשה אז הוא רק מוסיף פרמטר לפונקציה המשותפת ועוד if קטן והכל מסתדר.

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

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

אגב התרחיש המקורי ממנו מפתח A ניסה להתגונן היה:

  1. הזמן עובר ונכנסת דרישה חדשה למערכת.

  2. מפתח B מתקן את הקוד במקום אחד ושוכח שהקוד משוכפל ומופיע במקום נוסף במערכת.

  3. משתמשים כועסים כי עכשיו כפתור אחד מתנהג נכון ושני עדיין שבור.

עשר שנים אחרי המאמר של סנדי מץ ואנחנו צריכים להוסיף שיקול חדש למערכת. איזה מהתרחישים יותר מטריד אותנו כש AI כותב את הקוד. הנה מה שאנחנו יודעים:

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

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

ואת כל זה צריך להכפיל פי 10 כי סוכני קידוד כותבים הרבה יותר קוד הרבה יותר מהר מבני אדם.

אז האם כפל קוד עדיין יותר זול? טוב בשביל לענות צריך קודם להבין איך בכלל אנחנו מתמודדים עם שני המצבים בעולם של סוכני קידוד:

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

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

לדוגמה ב langlets יש לי שני נגני וידאו ומספר layouts לכל נגן. חלק מהקוד משותף וחלק משוכפל בין הנגנים ובאמת מדי פעם כשביקשתי לעדכן פיצ'ר בנגן הוידאו ה AI מימש את השינוי רק באחד מהם. הפתרון היה להוסיף קובץ טקסט שמסביר על ארכיטקטורת הוידאו במערכת, אפשר לראות אותו כאן:

https://github.com/ynonp/langlets-rails/blob/main/docs/video-player.md

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

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