אנטי דפוסים שעליך להימנע בקוד שלך

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

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

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

אז מה זה אנטי דפוס?

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

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

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

קוד ספגטי

קוד הספגטי הוא האנטי-דפוס הידוע ביותר. זה קוד עם מעט מבנה עד אפס.

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

בדרך כלל, זהו נושא שמישהו לא חשב היטב על זרימת התוכנית שלו ורק התחיל לקודד.

מה זה עושה?! אני לא יכול לעקוב אחרי זה

image.png

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

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

תוכלו לקרוא כאן עוד על קוד הספגטי נגד תבניות.

האמר הזהב

"אני מניח שזה מפתה, אם הכלי היחיד שיש לך הוא פטיש, להתייחס לכל דבר כאילו היה מסמר." אברהם מסלו

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

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

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

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

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

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

תוכלו לקרוא כאן עוד על אנטי דפוס האמר האמריקני.

עוגן סירות

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

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

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

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

הבעיה הסופית היא שקוד מיושן מאריך את זמן הבנייה ואתה עלול לערבב קוד מיושן. אתה יכול אפילו להתחיל "להפעיל אותו" בשוגג בהפקה.

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

אתה יכול לקרוא עוד כאן על עוגן האנטי נגד תבניות.

קוד מת

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

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

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

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

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

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

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

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

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

אתה יכול לקרוא עוד כאן על אנטי דפוס קוד מת .

הפצת קוד

Objects or modules regularly communicate with others. If you have a clean, modularised codebase you often will need to call into other separate modules and call new functions.

The Proliferation of Code anti-pattern is when you have objects in your codebase that only exist to invoke another more important object. Its purpose is only as a middleman.

This adds an unnecessary level of abstraction (adds something that you have to remember) and serves no purpose, other than to confuse people who need to understand the flow and execution of your codebase.

A simple fix here is to just remove it. Move the responsibility of invoking the object you really want to the calling object.

You can read more here about the Proliferation of Code anti-pattern.

God Object

If everywhere in your codebase needs access to one object, it might be a God object.

God objects do too much. They are responsible for the user id, the transaction id, the customer's first and last name, the total sum of the transaction, the item/s the user is purchasing...you get the picture.

It is sometimes called the Swiss Army Knife anti-pattern because you only really need it to cut some twine, but it also can be a nail file, saw, pair of tweezers, scissors, bottle opener and a cork screw too.

In this instance you need to separate out and modularise your code better.

Programmers often compare this problem to asking for a banana, but receiving a gorilla holding a banana. You got what you asked for, but more than what you need.

The SOLID principles explicitly discuss this in object orientated languages, to help us model our software better (if you don't know what the SOLID principles are, you can read this article).

The S in the acronym stands for Single Responsibility - every class/module/function should have responsibility over one part of the system, not multiple.

You can see this problem over and over again, how about the below interface?

interface Animal { numOfLegs: string; weight: number; engine: string; model: string; sound: string; claws: boolean; wingspan: string; customerId: string; } 

Can you see by even just briefly scanning this interface that the responsibility of this is far too broad, and needs refactoring? Whatever implements this has the potential to be a God object.

How about this?

 interface Animal { numOfLegs: string; weight: number; sound: string; claws: boolean; } interface Car { engine: string; model: string; } interface Bird { wingspan: string; } interface Transaction { customerId: string; } 

Interface segregation will keep your code clear about where the responsibilities lie, and stop forcing classes that only need wingspan to also implement the engine, customerId and model  and so on.

אתה יכול לקרוא כאן עוד על האנטי-דפוס נגד האל .

סיכום

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

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

אני משתף את כתיבתי בטוויטר אם נהנית ממאמר זה ורוצה לראות עוד.