DanLevy.net

היזהרו מאנשים חד-תכליתיים

טהור עד כאב

הSingle Responsibility Principle הוא אחד מהרעיונות האלה שנשמע כל כך הגיוני שהוא יכול לחמוק מהשיפוט שלך.

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

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

הבעיה היא לא SRP. הבעיה היא להתייחס ל”קטן” כתחליף ל”קוהרנטי”.

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

אלימות בארכיטקטורת תוכנה
רכיבים, רכיבים בכל מקום

I. הרעיון השימושי שמתחת

הוספת תיבת סימון בודדת לטופס אמורה באופן אידיאלי להשפיע רק על קובץ אחד. לא 8 קבצים ב-5 תיקיות… אני מסתכל עליכם, React/Redux.

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

אפילו הדוגמאות הקלאסיות של יוניקס הן יותר פרקטיות ממה שהסיסמה מרמזת. ls מפרט קבצים, כן, אבל הוא גם מתאם קריאות כמו opendir, readdir, closedir, ו-stat. היחידה השימושית היא לא הפעולה הקטנה ביותר האפשרית. היחידה השימושית היא הדבר הקוהרנטי הקטן ביותר שפותר את המשימה.

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

ההבחנה הזו חשובה. “אחריות אחת” אינה זהה ל”שורת התנהגות אחת”.

II. אבסטרקציית יתר: כשפשטות הופכת לכאוס

הארכיטקט שלנו מתעקש שכל פונקציה ארוכה מ-5 שורות היא ‘ריח קוד’. בסיס הקוד שלנו כעת מריח קלות של ייאוש חסר מושג.

קל לזהות את מצב הכשל אחרי שהוא כבר הרס לך את השבוע.

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

אין מנוס מדפוס העבודה האינסופי הזה
קומפוננטות, קומפוננטות בכל מקום

מה קנתה כל הטוהר הזה?

בהיתי בתהום של בסיסי קוד שבהם תכונה פשוטה בת 100 שורות נותחה על פני 15+ קבצים, כל אחד מלאך קטן “טהור” המכיל אולי פונקציה אחת או שתיים. רדיוס הפיצוץ הקוגניטיבי של ניסיון להחזיק את הבלאגן הזה בראש ביטל לחלוטין כל ניצחון תיאורטי מההפרדה. זה לא היה פשוט יותר; זה היה פשוט מפוזר.

III. המחיר של השלמות: השפעה על מפתחים

אנחנו מבזבזים יותר זמן בוויכוחים על מבנה קבצים ומוסכמות שמות מאשר במשלוח תכונות. זה אג’ילי?

כל כך מבולגן שזה גובל באמנות
כל כך מבולגן שזה גובל באמנות

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

ניקוז הפרודוקטיביות: תשכחו מחוב טכני; זה חוב ארגוני שנצבר דרך קינון תיקיות כפייתי-אובססיבי. כל שינוי קטן הופך לחפירה ארכיאולוגית דרך שכבות של הפשטה. הזמן נעלם לתוך החור השחור של cd .. ו-grep.

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

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

IV. אימוץ הפרגמטיות: אלטרנטיבה מעשית

הצעתי לשים שתי פונקציות קשורות באותו קובץ. החדר הגיב כאילו הצעתי למחוק את ה-staging. — קורא מחלים מפוריות

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

הנה איך זה נראה בפועל:

המטרה אינה שלמות תאורטית הראויה לתזה דוקטורט; היא יצירת קוד שעמיתיך (והעצמי העתידי שלך) יוכלו לנווט בו, להבין ולשנות מבלי לרצות להצית את הבניין.

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

הישארו ממוקדים ללא הרף בשאלות המעשיות:

V. מסקנה: טיפוח קוד קוהרנטי ובר-תחזוקה

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

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

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

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

¹ האירוניה היא שהשגת מטרה אחת אמיתית ברמות הנמוכות ביותר דורשת מורכבות עצומה החבויה ממש מתחת לפני השטח.

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