״פרדיגמה״ היא מערכת הנחות, רעיונות, ערכים וטכניקות. היא רחבה יותר מ״שיטה״, ״מודל״, או ״טכניקה״ - ויש בה אלמנט עמוק של תפיסת-עולם וסט-אמונות, המרכזים את הרעיונות והשיטות שהיא כוללת.
בתכנות ישנן כמה פרדיגמות תכנות מקובלות. הפרדיגמות המשפיעות ביותר כיום הן פרדיגמת ה-Objection-Orientation (בקיצור: OO) ו-Functional Programming (תכנות פונקציונלי) - אך גם יש אחרות מוכרות יותר ופחות.
עבור הרוב המוחץ של אנשי-התוכנה, התשובה היא זו:
"אנו עובדים על בסיס פרדיגמת OO, המבוססת על תכנות פרוצדורלי ותכנות מובנה, אך משתמשים גם באלמנטים של תכנות פונקציונלי, ואולי עוד כמה פרדיגמות נוספות".
למרות שפרדיגמות הן "סט אמונות" - הן לא אקסקלוסיביות, ואנו בעצם מערבבים פרדיגמות ומשתמשים בכמה במקביל (גם אם לא תמיד מודעים לכך). בד"כ אין דייקנות באימוץ של פרדיגמות, וזה בסדר גמור - כי לכל פרדיגמה יש פרשנויות שונות.
איזו פרדיגמה היא הטובה ביותר?
אולי OO? - שהיא (עדיין) הדומיננטית, והמשפיעה ביותר ב-20-30 שנה האחרונות?
ואלי תכנות פונקציונלי שמרגיש חדש יותר (הוא בעצם קדם ל OO) - וזוכה להרבה מומנטום מחודש בעשור האחרון?
אם אנחנו הולכים לכתוב קוד קצר בן כמה עשרות שורות קוד - שימוש ב-OO, או תכנות פונקציונלי, או Reactive Programming - יהוו סיבוך ובזבוז זמן!
קוד קצר מאוד כנראה לא ירוויח דבר מהשימוש בפרדיגמות הללו. אם אנו כותבים תוכנות קצרצרות בכלים הללו - ההצדקה היחידה לכך היא ההרגל.
לשימוש בפרדיגמות מתקדמות - יש מחירים:
• עוד שורות קוד שנכתבות על מנת לשמר את הפרדיגמה - ואינן מוסיפות יכולות נוספות למערכת.
• כללים וחוקים מגבילים שאנו מטילים על עצמנו - שמדי פעם יגרמו לשינוי פשוט להיות מורכב ו/או ארוך יותר.
• עקומת למידה שאין לזלזל בה. התאוריה לרוב לא מסובכת, אבל תהליך התמקצעות בפרדיגמת תכנות מורכבת - עשוי לארוך שנים.
הסיבה היחידה שפרדיגמות תכנות מתקדמות קיימות - היא לאפשר לבנות מערכות תוכנה גדולות ומורכבות שיוכלו להתקיים לאורך זמן (= כמות שינויים).
בעצם, משם הכל התחיל *: מפרדיגמות מאוד פשוטות, עבור תוכנות פשוטות, שרצו על חומרה - שלא יכלה לתמוך בתוכנות מורכבות יותר:
אם אפשר לעבוד בצורה דקלרטיבית - לרוב עדיף. זה פשוט יותר: יש פחות מקום לטעויות אנוש, ולרוב הקוד יהיה קצר יותר. החיסרון: האלגוריתם הוא לא בשליטתנו - אלא בשליטת סביבת-הריצה.
הסיבה לשימוש בפרדיגמה אימפרטיבית - הוא שאין פרדיגמה דקלרטיבית שתספק את הצרכים שלנו, וזה המצב ברוב הפעמים. המערכות הן שונות ומורכבות, מכדי שמישהו יוכל להגדיר אלגוריתם כללי שיספק אותן. הדברים הללו עובדים ב-SQL או HTML - אבל לא במערכות ווב מורכבות, שהדרישות מהן משתנות על בסיס שבועי.
הערה: בפוסט אגע בכמה פרדיגמות, שלכל אחת ניתן להקדיש פוסט או שניים. הכוונה היא להתמקד בכל פרדיגמה בצדדים הבודדים משמעותיים ביותר שלה, ובמיוחד מנקודת מבט של שנת 2019.
למשל: בתיאורים המקודמים של Alan Key ל Object-Oriented - ישנו דגש גדול על העיקרון ש"אובייקטים מתקשרים ע"י שליחת וקבלת הודעות". אפשר להסביר למה ההדגשות הללו היו חשובות בזמנו, ומה משמעותן, אבל היום ההגדרות הללו נכנסות תחת הגדרת ההכמסה (Encapsulation). כלומר: אובייקט שולח הודעות - כי הוא לא יכול לגשת לנתונים הפנימיים של האובייקט האחר בעצמו. בכלל, המונח "שליחת הודעות" מתקשר היום חזק יותר לפרדיגמה של Event-Driven - וזה כבר נושא אחר.
הדברים מסתבכים
ממש כמו חברה אנושית, בה במבנה מאוד קטן (למשל: משפחה) לא זקוק לפרדיגמת ניהול מורכבת - כך גם התוכנות שנכתבו בשנות ה-50, לא היו זקוקות להן. המגבלה הייתה בחומרה: כמות זיכרון ומהירות המעבד לא יכלו לתמוך בתוכנות ארוכות ומורכבות.
עם הזמן, החומרה התחזקה, וניתן היה לכתוב תוכנות ארוכות יותר ומורכבות יותר.
בהקבלה לחברות האנושיות: עכשיו בני-האדם התאגדו בקבוצה של 100 איש, וכבר קשה לנהל "משפחה" של 100 איש. על הקבוצה למצוא כללים מורכבים יותר - בכדי להתנהל בצורה יציבה לאורך זמן.
בשלב מסוים, בסוף שנות השישים, נדמה היה שעולם התוכנה נתקע - ואולי לא יהיה ניתן לפתח תוכנות גדולות ומורכבות בזמן הקרוב. התוכנות הגדולות שניסו לכתוב, הסתבכו בצורה כ"כ קשה ולא צפויה (באגים, שינויים קשים לביצוע, הסתבכות לא צפויה של פרויקטים שמתארכים עוד ועוד) - כשעלה החשש שתחום התוכנה עשוי עשוי להיעצר. קראו לזה אז "The Software Crisis" - ואנו חווים וריאציות של האתגרים הללו עד היום.
בניגוד לאז, האמונה השתנתה: הקונצנזוס (מגובה בהוכחות בשטח) הוא שנהיה מסוגלים לכתוב תוכנות גדולות ומורכבות יותר ויותר - רק צריך למצוא את השיטות הטובות לכך.
בהקבלה, בני האדם היו צריכים להמציא את ה"כפר" או "השבט" בכדי לבנות מבנה חברתי גדול ומורכב יותר שיוכל להחזיק לאורך זמן. בשלב מסוים, גם המבנה הזה לא מספיק, והיה צורך ב-"עיר" ואז "מדינה". כל אחד מהמבנים הללו הוא מורכב יותר, ובא גם עם תקורה גדולה יותר - אבל הוא נדרש בכדי להחזיק מבנה גדול ויציב.
היתרון במבנה גדול - הוא אדיר: שום התקדמות אנושית מהפכנית (מדע, רפואה, חברה) לא היה מתרחשת - ללא ריכוז מאמץ של אנשים רבים - ביחד. שום תוכנה מורכבת לא הייתה יכולה להיכתב ולהחזיק לאורך זמן - ללא שימוש בפרדיגמות המורכבות יותר.
פתחו את הטלפון שלכם והסתכלו באפליקציות "הקטנות" שאתם משמשים בהן:
גוגל, YouTube, פייסבוק, ספוטיפי, או אפילו אפליקציה למציאות מונית. כל אחת ממלאה פונקציה קטנה - אבל מאחורי הקלעים רצה מערכת גדולה וסבוכה, שלא היו רבות כמותה בעולם עשור או שניים קודם לכן.
בטווח הקצר - נראה שאימוץ פרדיגמה מורכבת יותר הוא טרחנות, חוסר-יעילות ובזבוז זמן, אבל מחזור אחר מחזור - עולם התוכנה נאלץ לאמץ את הפרדיגמות המורכבות יותר הללו.
אני מדגיש את העניין הזה, כי קיים דיון תמידי - עד כמה הפרקטיקות הללו אכן נדרשות.
בראיה מקומית - העובדות תומכות בכך שאם נסיר מעצמנו את ההגבלות של הפרדיגמה המורכבת (OO, Function, או מה שלא יהיה) - נוכל עכשיו לסיים את הפיצ'ר מהר יותר. לא חבל על כל בזבוז הזמן?
בפרספקטיבה מערכתית, והיסטורית - פרדיגמות מורכבות יותר מנצחות לאורך זמן שוב ושוב פרדיגמות פשוטות "ומהירות" יותר.
אני זוכר בתחילת הקריירה שלי, לפני +15 שנים - ויכוחים על "הוצאה" של פונקציות:
"אם קוראים לפונקציה רק פעם אחת - אז לא נכון להוציא את הקוד לפונקציה - " הייתה טענה שנשמעה מדי-פעם. "חבל על הקוד הנוסף (הגדרת הפונקציה והקריאה לה), ועל זמן הריצה המבוזבז".
חשבו על זה לרגע: יש היגיון בטיעון. ההיגיון חזק בראיה מקומית, ואכן נחלש ככל שחושבים על מערכת גדולה, עליה עובדים מאות מהנדסים.
הדיון הספציפי זה נעלם עם השנים: כיום, אם הקוד יהיה אפילו טיפה קריא יותר כאשר מוציאים כמה שורות לפונקציה - אנו לא חושבים פעמים ומבצעים פעולת "extract function". הנה - יש לזה אפילו שם, וקיצור-מקשים ב-IDE.
הדינמיקה של דיונים בנכונות הפרדיגמות מעולם לא פסק, הוא רק החליף נושאי-דיון:
• האם חייבים הכמסה? לא נתקלתי שמערערים על חשיבות של ההכמסה, אלא האם לא ניתן פה ופה - לוותר.
• האם כתיבת בדיקות אוטומטיות / בדיקות יחידה - שווה את המאמץ?
• האם נכון בכלל לחלק את המערכת למודולים? או אולי: למה לא ללכת כמה צעדים קדימה - ולפרק את המערכת להמון פונקציות בודדות?
• (הרעיון הזה סותר כ"כ הרבה פרדיגמות שהוכיחו את עצמן לאורך שנים, אך הבאזז דילג מעל כולן בקלילות מפתיעה).
• למה לשאת את האילוצים של Strong Typing? "זה מאט את הכתיבה, ומעצבן"
ועוד...
הדיונים על נכונות השימוש בפרדיגמה הם כמובן חשובים: לא כל פרדיגמה מורכבת יותר - היא אכן טובה יותר. לאימוץ פרדיגמות יש מחיר ניכר, ולא כל פרדיגמה ש"תפסה" בארגון X - תצליח בהכרח גם בארגון Y. למשל: ב-C עדיין משתמשים במשפטי goto - בעיקר בשם היעילות הגבוהה (קרבה למעבד).
בקרנל של לינוקס למשל, יש כ 13K משפטי goto (בדקתי הרגע).
יש גם פרספקטיבה של זמן: פרדיגמות שונות שנראו מבטיחות בתחילה (למשל: שימוש עמוק ב-XML) - לא עמדו במבחן הזמן.
אנחנו צריכים לבחון כל פרקטיקה, ולראות אם היא מטיבה עם המערכת שלנו -- בפועל. מצד שני - צריך גם לפרגן ולתת משקל מספיק לניסיון שנצבר.
בתור ארכיטקט, אני באופן טבעי מגיע להרבה דיונים כאלו, ויש פה איזה פרדוקס שפועל כנגד אימוץ הפרדיגמות: קל להדגים בצורה מוחשית כיצד אי-ציות להגבלה יתרום בטווח המאוד הקצר - לשחרור הפיצ'ר הבא.
קשה הרבה יותר להדגים, כיצד קיצורי הדרך מצטברים - לכדי אזור שלא ניתן לתחזק (כלומר: להמשיך לבצע בו שינויים - בזמנים סבירים). תמיד אפשר לטעון שהמתכנת הספציפי בנקודה הזו עשה עבודה גרועה, שזה מזל רע משמיים, או שזה מקרה חד-פעמי ולא מייצג.
לעתים, מפתחים מחליפים אחריות על מודול שכתבו (או למשל: עוזבים את החברה) - לפני שהם מספיקים "להרגיש" את תוצאות ארוכות הטווח של הקיצורים שעשו - וכך הם עלולים לא-ללמוד את קשר הסיבה - ותוצאה.
בתור מי שמנסה לדייק ולהיצמד לעובדות - יש קושי בקידום פרדיגמות תכנות. אני מניח שגישה דתית-משיחית יכולה לעזור כאן בהרבה 😅.
ההחלטות על אימוץ פרדיגמות ושיטות, הוא הרבה פעמים מערכתי: רק כשמסתכלים על כלל המערכת, ומספר מקרים בעייתיים שהצטבר - מגיעים להחלטה לאמץ באופן גורף כלל או פרקטיקה במערכת.
הורשה מרובה, למשל - היא לא בהכרח דבר רע, וב-90% מהפעמים - אפשר להשתמש בה בצורה נשלטת. אני זוכר שבעבודה עם ++C, היו שטענו שכל הפחד מהורשה-מרובה - הוא מוגזם.
10% מהפעמים שבהם היא יצאה משליטה - היו מספיק קשות, עד כדי כך שהתעשייה (!) באופן גורף החליטה לזנוח את האפשרות הזו.
אם כלי כלשהו כושל ויוצר בעיה מהותית, נאמר, ב-10% מהשימושים - זה עשויה להיות סיבה מספיקה בכדי להחליט ולהכחיד אותו מהמערכת. השיקול הכללי - גובר על השיקול המקומי.
גם היום, עדיין יש בשפות, וב-Frameworks יכולות בעייתיות: שמדי פעם מקצרות את הקוד - אבל בפעמים אחרות הן זרז לבעיה. מדוע חשיש יצא מחוץ לחוק ואלכוהול לא? - קשה לומר.
חשוב לזהות אלמנטים במערכת שגורמים לבעיות רבות מדי - ולחסום אותם. אני בטוח שיהיו מתנגדים, אבל זכרו שמערכות לא הופכות עם הזמן לפשוטות יותר, או קלות יותר לתחזוקה. הסתמכות על משמעת ודיוק של כל וכל מהנדס במערכת - היא מתכון לכישלון.
על זה נאמר: "It must be simple - or it simply won't be"
במאמר הבא, נבחן את חשיבות הפדיגמות המוקדמות עבורנו.
---
* דילגתי עם קוד מכונה, אסמבלי, ועל הדיון של המכונה של טיורינג לזו של פון-ניומן. זו היסטוריה low level מדי, ולא מעניינת לדיון.
״פרדיגמה״ היא מערכת הנחות, רעיונות, ערכים וטכניקות. היא רחבה יותר מ״שיטה״, ״מודל״, או ״טכניקה״ - ויש בה אלמנט עמוק של תפיסת-עולם וסט-אמונות, המרכזים את הרעיונות והשיטות שהיא כוללת.
בתכנות ישנן כמה פרדיגמות תכנות מקובלות. הפרדיגמות המשפיעות ביותר כיום הן פרדיגמת ה-Objection-Orientation (בקיצור: OO) ו-Functional Programming (תכנות פונקציונלי) - אך גם יש אחרות מוכרות יותר ופחות.
עבור הרוב המוחץ של אנשי-התוכנה, התשובה היא זו:
"אנו עובדים על בסיס פרדיגמת OO, המבוססת על תכנות פרוצדורלי ותכנות מובנה, אך משתמשים גם באלמנטים של תכנות פונקציונלי, ואולי עוד כמה פרדיגמות נוספות".
למרות שפרדיגמות הן "סט אמונות" - הן לא אקסקלוסיביות, ואנו בעצם מערבבים פרדיגמות ומשתמשים בכמה במקביל (גם אם לא תמיד מודעים לכך). בד"כ אין דייקנות באימוץ של פרדיגמות, וזה בסדר גמור - כי לכל פרדיגמה יש פרשנויות שונות.
איזו פרדיגמה היא הטובה ביותר?
אולי OO? - שהיא (עדיין) הדומיננטית, והמשפיעה ביותר ב-20-30 שנה האחרונות?
ואלי תכנות פונקציונלי שמרגיש חדש יותר (הוא בעצם קדם ל OO) - וזוכה להרבה מומנטום מחודש בעשור האחרון?
אם אנחנו הולכים לכתוב קוד קצר בן כמה עשרות שורות קוד - שימוש ב-OO, או תכנות פונקציונלי, או Reactive Programming - יהוו סיבוך ובזבוז זמן!
קוד קצר מאוד כנראה לא ירוויח דבר מהשימוש בפרדיגמות הללו. אם אנו כותבים תוכנות קצרצרות בכלים הללו - ההצדקה היחידה לכך היא ההרגל.
לשימוש בפרדיגמות מתקדמות - יש מחירים:
• עוד שורות קוד שנכתבות על מנת לשמר את הפרדיגמה - ואינן מוסיפות יכולות נוספות למערכת.
• כללים וחוקים מגבילים שאנו מטילים על עצמנו - שמדי פעם יגרמו לשינוי פשוט להיות מורכב ו/או ארוך יותר.
• עקומת למידה שאין לזלזל בה. התאוריה לרוב לא מסובכת, אבל תהליך התמקצעות בפרדיגמת תכנות מורכבת - עשוי לארוך שנים.
הסיבה היחידה שפרדיגמות תכנות מתקדמות קיימות - היא לאפשר לבנות מערכות תוכנה גדולות ומורכבות שיוכלו להתקיים לאורך זמן (= כמות שינויים).
בעצם, משם הכל התחיל *: מפרדיגמות מאוד פשוטות, עבור תוכנות פשוטות, שרצו על חומרה - שלא יכלה לתמוך בתוכנות מורכבות יותר:
אם אפשר לעבוד בצורה דקלרטיבית - לרוב עדיף. זה פשוט יותר: יש פחות מקום לטעויות אנוש, ולרוב הקוד יהיה קצר יותר. החיסרון: האלגוריתם הוא לא בשליטתנו - אלא בשליטת סביבת-הריצה.
הסיבה לשימוש בפרדיגמה אימפרטיבית - הוא שאין פרדיגמה דקלרטיבית שתספק את הצרכים שלנו, וזה המצב ברוב הפעמים. המערכות הן שונות ומורכבות, מכדי שמישהו יוכל להגדיר אלגוריתם כללי שיספק אותן. הדברים הללו עובדים ב-SQL או HTML - אבל לא במערכות ווב מורכבות, שהדרישות מהן משתנות על בסיס שבועי.
הערה: בפוסט אגע בכמה פרדיגמות, שלכל אחת ניתן להקדיש פוסט או שניים. הכוונה היא להתמקד בכל פרדיגמה בצדדים הבודדים משמעותיים ביותר שלה, ובמיוחד מנקודת מבט של שנת 2019.
למשל: בתיאורים המקודמים של Alan Key ל Object-Oriented - ישנו דגש גדול על העיקרון ש"אובייקטים מתקשרים ע"י שליחת וקבלת הודעות". אפשר להסביר למה ההדגשות הללו היו חשובות בזמנו, ומה משמעותן, אבל היום ההגדרות הללו נכנסות תחת הגדרת ההכמסה (Encapsulation). כלומר: אובייקט שולח הודעות - כי הוא לא יכול לגשת לנתונים הפנימיים של האובייקט האחר בעצמו. בכלל, המונח "שליחת הודעות" מתקשר היום חזק יותר לפרדיגמה של Event-Driven - וזה כבר נושא אחר.
הדברים מסתבכים
ממש כמו חברה אנושית, בה במבנה מאוד קטן (למשל: משפחה) לא זקוק לפרדיגמת ניהול מורכבת - כך גם התוכנות שנכתבו בשנות ה-50, לא היו זקוקות להן. המגבלה הייתה בחומרה: כמות זיכרון ומהירות המעבד לא יכלו לתמוך בתוכנות ארוכות ומורכבות.
עם הזמן, החומרה התחזקה, וניתן היה לכתוב תוכנות ארוכות יותר ומורכבות יותר.
בהקבלה לחברות האנושיות: עכשיו בני-האדם התאגדו בקבוצה של 100 איש, וכבר קשה לנהל "משפחה" של 100 איש. על הקבוצה למצוא כללים מורכבים יותר - בכדי להתנהל בצורה יציבה לאורך זמן.
בשלב מסוים, בסוף שנות השישים, נדמה היה שעולם התוכנה נתקע - ואולי לא יהיה ניתן לפתח תוכנות גדולות ומורכבות בזמן הקרוב. התוכנות הגדולות שניסו לכתוב, הסתבכו בצורה כ"כ קשה ולא צפויה (באגים, שינויים קשים לביצוע, הסתבכות לא צפויה של פרויקטים שמתארכים עוד ועוד) - כשעלה החשש שתחום התוכנה עשוי עשוי להיעצר. קראו לזה אז "The Software Crisis" - ואנו חווים וריאציות של האתגרים הללו עד היום.
בניגוד לאז, האמונה השתנתה: הקונצנזוס (מגובה בהוכחות בשטח) הוא שנהיה מסוגלים לכתוב תוכנות גדולות ומורכבות יותר ויותר - רק צריך למצוא את השיטות הטובות לכך.
בהקבלה, בני האדם היו צריכים להמציא את ה"כפר" או "השבט" בכדי לבנות מבנה חברתי גדול ומורכב יותר שיוכל להחזיק לאורך זמן. בשלב מסוים, גם המבנה הזה לא מספיק, והיה צורך ב-"עיר" ואז "מדינה". כל אחד מהמבנים הללו הוא מורכב יותר, ובא גם עם תקורה גדולה יותר - אבל הוא נדרש בכדי להחזיק מבנה גדול ויציב.
היתרון במבנה גדול - הוא אדיר: שום התקדמות אנושית מהפכנית (מדע, רפואה, חברה) לא היה מתרחשת - ללא ריכוז מאמץ של אנשים רבים - ביחד. שום תוכנה מורכבת לא הייתה יכולה להיכתב ולהחזיק לאורך זמן - ללא שימוש בפרדיגמות המורכבות יותר.
פתחו את הטלפון שלכם והסתכלו באפליקציות "הקטנות" שאתם משמשים בהן:
גוגל, YouTube, פייסבוק, ספוטיפי, או אפילו אפליקציה למציאות מונית. כל אחת ממלאה פונקציה קטנה - אבל מאחורי הקלעים רצה מערכת גדולה וסבוכה, שלא היו רבות כמותה בעולם עשור או שניים קודם לכן.
בטווח הקצר - נראה שאימוץ פרדיגמה מורכבת יותר הוא טרחנות, חוסר-יעילות ובזבוז זמן, אבל מחזור אחר מחזור - עולם התוכנה נאלץ לאמץ את הפרדיגמות המורכבות יותר הללו.
אני מדגיש את העניין הזה, כי קיים דיון תמידי - עד כמה הפרקטיקות הללו אכן נדרשות.
בראיה מקומית - העובדות תומכות בכך שאם נסיר מעצמנו את ההגבלות של הפרדיגמה המורכבת (OO, Function, או מה שלא יהיה) - נוכל עכשיו לסיים את הפיצ'ר מהר יותר. לא חבל על כל בזבוז הזמן?
בפרספקטיבה מערכתית, והיסטורית - פרדיגמות מורכבות יותר מנצחות לאורך זמן שוב ושוב פרדיגמות פשוטות "ומהירות" יותר.
אני זוכר בתחילת הקריירה שלי, לפני +15 שנים - ויכוחים על "הוצאה" של פונקציות:
"אם קוראים לפונקציה רק פעם אחת - אז לא נכון להוציא את הקוד לפונקציה - " הייתה טענה שנשמעה מדי-פעם. "חבל על הקוד הנוסף (הגדרת הפונקציה והקריאה לה), ועל זמן הריצה המבוזבז".
חשבו על זה לרגע: יש היגיון בטיעון. ההיגיון חזק בראיה מקומית, ואכן נחלש ככל שחושבים על מערכת גדולה, עליה עובדים מאות מהנדסים.
הדיון הספציפי זה נעלם עם השנים: כיום, אם הקוד יהיה אפילו טיפה קריא יותר כאשר מוציאים כמה שורות לפונקציה - אנו לא חושבים פעמים ומבצעים פעולת "extract function". הנה - יש לזה אפילו שם, וקיצור-מקשים ב-IDE.
הדינמיקה של דיונים בנכונות הפרדיגמות מעולם לא פסק, הוא רק החליף נושאי-דיון:
• האם חייבים הכמסה? לא נתקלתי שמערערים על חשיבות של ההכמסה, אלא האם לא ניתן פה ופה - לוותר.
• האם כתיבת בדיקות אוטומטיות / בדיקות יחידה - שווה את המאמץ?
• האם נכון בכלל לחלק את המערכת למודולים? או אולי: למה לא ללכת כמה צעדים קדימה - ולפרק את המערכת להמון פונקציות בודדות?
• (הרעיון הזה סותר כ"כ הרבה פרדיגמות שהוכיחו את עצמן לאורך שנים, אך הבאזז דילג מעל כולן בקלילות מפתיעה).
• למה לשאת את האילוצים של Strong Typing? "זה מאט את הכתיבה, ומעצבן"
ועוד...
הדיונים על נכונות השימוש בפרדיגמה הם כמובן חשובים: לא כל פרדיגמה מורכבת יותר - היא אכן טובה יותר. לאימוץ פרדיגמות יש מחיר ניכר, ולא כל פרדיגמה ש"תפסה" בארגון X - תצליח בהכרח גם בארגון Y. למשל: ב-C עדיין משתמשים במשפטי goto - בעיקר בשם היעילות הגבוהה (קרבה למעבד).
בקרנל של לינוקס למשל, יש כ 13K משפטי goto (בדקתי הרגע).
יש גם פרספקטיבה של זמן: פרדיגמות שונות שנראו מבטיחות בתחילה (למשל: שימוש עמוק ב-XML) - לא עמדו במבחן הזמן.
אנחנו צריכים לבחון כל פרקטיקה, ולראות אם היא מטיבה עם המערכת שלנו -- בפועל. מצד שני - צריך גם לפרגן ולתת משקל מספיק לניסיון שנצבר.
בתור ארכיטקט, אני באופן טבעי מגיע להרבה דיונים כאלו, ויש פה איזה פרדוקס שפועל כנגד אימוץ הפרדיגמות: קל להדגים בצורה מוחשית כיצד אי-ציות להגבלה יתרום בטווח המאוד הקצר - לשחרור הפיצ'ר הבא.
קשה הרבה יותר להדגים, כיצד קיצורי הדרך מצטברים - לכדי אזור שלא ניתן לתחזק (כלומר: להמשיך לבצע בו שינויים - בזמנים סבירים). תמיד אפשר לטעון שהמתכנת הספציפי בנקודה הזו עשה עבודה גרועה, שזה מזל רע משמיים, או שזה מקרה חד-פעמי ולא מייצג.
לעתים, מפתחים מחליפים אחריות על מודול שכתבו (או למשל: עוזבים את החברה) - לפני שהם מספיקים "להרגיש" את תוצאות ארוכות הטווח של הקיצורים שעשו - וכך הם עלולים לא-ללמוד את קשר הסיבה - ותוצאה.
בתור מי שמנסה לדייק ולהיצמד לעובדות - יש קושי בקידום פרדיגמות תכנות. אני מניח שגישה דתית-משיחית יכולה לעזור כאן בהרבה 😅.
ההחלטות על אימוץ פרדיגמות ושיטות, הוא הרבה פעמים מערכתי: רק כשמסתכלים על כלל המערכת, ומספר מקרים בעייתיים שהצטבר - מגיעים להחלטה לאמץ באופן גורף כלל או פרקטיקה במערכת.
הורשה מרובה, למשל - היא לא בהכרח דבר רע, וב-90% מהפעמים - אפשר להשתמש בה בצורה נשלטת. אני זוכר שבעבודה עם ++C, היו שטענו שכל הפחד מהורשה-מרובה - הוא מוגזם.
10% מהפעמים שבהם היא יצאה משליטה - היו מספיק קשות, עד כדי כך שהתעשייה (!) באופן גורף החליטה לזנוח את האפשרות הזו.
אם כלי כלשהו כושל ויוצר בעיה מהותית, נאמר, ב-10% מהשימושים - זה עשויה להיות סיבה מספיקה בכדי להחליט ולהכחיד אותו מהמערכת. השיקול הכללי - גובר על השיקול המקומי.
גם היום, עדיין יש בשפות, וב-Frameworks יכולות בעייתיות: שמדי פעם מקצרות את הקוד - אבל בפעמים אחרות הן זרז לבעיה. מדוע חשיש יצא מחוץ לחוק ואלכוהול לא? - קשה לומר.
חשוב לזהות אלמנטים במערכת שגורמים לבעיות רבות מדי - ולחסום אותם. אני בטוח שיהיו מתנגדים, אבל זכרו שמערכות לא הופכות עם הזמן לפשוטות יותר, או קלות יותר לתחזוקה. הסתמכות על משמעת ודיוק של כל וכל מהנדס במערכת - היא מתכון לכישלון.
על זה נאמר: "It must be simple - or it simply won't be"
במאמר הבא, נבחן את חשיבות הפדיגמות המוקדמות עבורנו.
---
* דילגתי עם קוד מכונה, אסמבלי, ועל הדיון של המכונה של טיורינג לזו של פון-ניומן. זו היסטוריה low level מדי, ולא מעניינת לדיון.
הודעתך לא התקבלה - נסה שוב מאוחר יותר
Oops! Something went wrong while submitting the form