الأنماط المضادة التي يجب تجنبها في التعليمات البرمجية الخاصة بك

يريد كل مطور كتابة كود منظم ، مخطط ببساطة ، ومعلق بشكل جيد. حتى أن هناك عددًا لا يحصى من أنماط التصميم التي تعطينا قواعد واضحة يجب اتباعها وإطار عمل يجب أخذه في الاعتبار.

لكن لا يزال بإمكاننا العثور على أنماط مضادة في البرامج التي تمت كتابتها في وقت ما ، أو تمت كتابتها بسرعة كبيرة.

يمكن أن يؤدي الاختراق الأساسي غير الضار لحل مشكلة ما بسرعة إلى وضع سابقة في قاعدة التعليمات البرمجية الخاصة بك. يمكن نسخها عبر أماكن متعددة وتحويلها إلى نمط مضاد تحتاج إلى معالجته.

إذن ما هو النمط المضاد؟

في البرنامج ، مكافحة النمط هو مصطلح يصف كيفية عدم حل المشكلات المتكررة في التعليمات البرمجية الخاصة بك. تعتبر الأنماط المضادة تصميم برامج سيئ ، وعادة ما تكون إصلاحات غير فعالة أو غامضة.  

بشكل عام ، يضيفون أيضًا "الدين الفني" - وهو رمز يجب عليك العودة وإصلاحه بشكل صحيح لاحقًا.

الأنماط الستة المضادة التي سأناقشها في هذه المقالة هي Spaghetti Code ، و Golden Hammer ، و Boat Anchor ، و Dead Code ، و Prolising of Code ، و God Object .

كود السباغيتي

كود السباغيتي هو أكثر أنواع مكافحة الأنماط شهرة. إنه رمز بهيكل قليل إلى صفر.

لا شيء موحد. توجد ملفات عشوائية متناثرة في دلائل عشوائية. من الصعب متابعة التدفق بالكامل ، وهو متشابك تمامًا معًا (مثل السباغيتي).

عادةً ما تكون هذه مشكلة حيث لم يفكر شخص ما بعناية في تدفق برنامجه مسبقًا وبدأ للتو في الترميز.

ماذا تعمل، أو ماذا تفعل؟! لا أستطيع متابعة هذا

image.png

هذا ليس فقط كابوس صيانة ، ولكنه يجعل من المستحيل إضافة وظائف جديدة.

سوف تكسر الأشياء باستمرار ، ولن تفهم نطاق تغييراتك ، أو تقدم أي تقديرات دقيقة لعملك لأنه من المستحيل توقع المشكلات التي لا حصر لها التي تظهر عند القيام بمثل هذا علم الآثار / التخمين.

يمكنك قراءة المزيد هنا حول مكافحة نمط Spaghetti Code .

المطرقة الذهبية

"أعتقد أنه من المغري ، إذا كانت الأداة الوحيدة التي لديك هي المطرقة ، أن تعامل كل شيء كما لو كان مسمارًا." ابراهام ماسلو

تخيل سيناريو معي: فريق التطوير لديك مؤهل للغاية في هندسة Hammer الجديدة تمامًا. لقد نجحت بشكل رائع في جميع مجموعة القضايا السابقة. أنت فريق هامر المعماري الرائد في العالم.

لكن الآن ، بطريقة ما ، كل شيء ينتهي دائمًا باستخدام هذه البنية. برغي مسطح الرأس؟ شاكوش. المسمار رئيس فيليبس؟ شاكوش. هل تحتاج إلى مفتاح ألين؟ لا أنت لا تفعل ذلك.

تبدأ في تطبيق نهج معماري لا يناسب تمامًا ما تحتاجه ولكنه ينجز المهمة. أنت تعتمد بشكل مفرط على نمط واحد وتحتاج إلى تعلم أفضل أداة لأفضل وظيفة.

قد يؤدي برنامجك بالكامل إلى تحقيق أداء جاد لأنك تحاول ضرب مربع في شكل دائرة. أنت تعلم أن الأمر يستغرق ضعف الوقت للتشفير ، وتنفيذ برنامج باستخدام بنية المطرقة لهذه المشكلة ، لكنه أسهل وهو ما تشعر بالراحة معه.

كما أنه لا يمكن التنبؤ به. اللغات المختلفة لها إصلاحات مشتركة للمشكلات التي تواجهها ومعاييرها الخاصة. لا يمكنك تطبيق كل قاعدة عملت بشكل جيد بالنسبة لك من لغة إلى أخرى ، بدون مشاكل.

لا تهمل التعلم المستمر في حياتك المهنية. اختر اللغة المناسبة لمشكلتك. فكر في الهندسة المعمارية ، وادفع منطقة الراحة الخاصة بك. ابحث واستكشف الأدوات الجديدة والطرق الجديدة للتعامل مع المشكلات التي تواجهها.

يمكنك قراءة المزيد هنا عن النمط المضاد للمطرقة الذهبية .

مرساة القارب

و قارب مرساة نموذج مضاد هو المكان الذي ترك المبرمجين التعليمات البرمجية في مصدر برنامج ل أنها قد تحتاج إليها لاحقا.

لقد قاموا بترميز شيء ما خارج المواصفات قليلاً ولم يكن هناك حاجة إليه بعد ، لكنهم على يقين من أنهم سيفعلون ذلك الشهر المقبل. لذا فهم لا يريدون حذفه. أرسله إلى الإنتاج وبعد ذلك عندما يحتاجون إليه ، يمكنهم تشغيله بسرعة.

لكن هذا يتسبب في كوابيس الصيانة في قاعدة الشفرة التي تحتوي على كل تلك الشفرات القديمة. المشكلة الكبيرة هي أن زملائهم سيجدون صعوبة في تحديد الكود الذي عفا عليه الزمن ولا يغير التدفق ، مقابل الكود الذي يفعل.

تخيل أنك في حل سريع ، وتحاول بشدة تحديد المسؤول عن إرسال تفاصيل بطاقة العملاء إلى واجهة برمجة التطبيقات لسحب الأموال من مصرفهم. يمكنك إضاعة الوقت في قراءة التعليمات البرمجية القديمة وتصحيحها ، دون أن تدرك أنك لست في المكان المناسب في قاعدة التعليمات البرمجية.

المشكلة الأخيرة هي أن الكود القديم يجعل وقت البناء أطول وقد تخلط بين العمل والتعليمات البرمجية القديمة. يمكنك حتى البدء عن غير قصد في "تشغيله" في الإنتاج.

الآن يمكنك على الأرجح معرفة سبب تسميته بالنمط المضاد لمرساة القارب - فهو ثقيل الحمل (يضيف دينًا تقنيًا) ولكنه لا يفعل أي شيء (حرفيًا ، لا يخدم الكود أي غرض ، فهو لا يعمل).

يمكنك قراءة المزيد هنا عن النمط المضاد لمرساة القارب .

كود ميت

هل سبق لك أن نظرت في التعليمات البرمجية التي كتبها شخص لا يعمل في شركتك بعد الآن؟ هناك وظيفة لا يبدو أنها تفعل أي شيء. لكنها تسمى من كل مكان! أنت تسأل من حولك ولا أحد غيرك متأكد تمامًا مما يفعله ، لكن الجميع قلقون جدًا من حذفه.

في بعض الأحيان يمكنك أن ترى ما تفعله ، لكن السياق مفقود. أنت قادر على قراءة وفهم التدفق ، لكن لماذا؟ لا يبدو أننا بحاجة للوصول إلى نقطة النهاية هذه بعد الآن. تكون الاستجابة دائمًا نفس الاستجابة لكل مستخدم مختلف.

يوصف هذا عادة بالنمط المضاد للرمز الميت . عندما لا تستطيع رؤية ما هو الكود "الفعلي" الضروري للتدفق والتنفيذ الناجح لبرنامجك ، مقابل ما كان مطلوبًا منذ 3 سنوات فقط ، وليس الآن.

هذا النمط المضاد أكثر شيوعًا في إثبات المفهوم أو رمز البحث الذي انتهى به المطاف في الإنتاج.

مرة واحدة في لقاء تقني التقيت برجل لديه هذه المشكلة بالضبط. كان لديه الكثير من الرموز الميتة ، والتي كان يعلم أنها ماتت ، والكثير من الرموز التي اشتبه في أنها ماتت. لكنه لم يستطع الحصول على إذن من الإدارة لإزالة كل الرموز الميتة.

وأشار إلى نهجه على أنه اختبار Monkey ، حيث بدأ في التعليق وإيقاف تشغيل الأشياء لمعرفة ما انفجر في الإنتاج. ربما قليلا مخاطرة كبيرة!

إذا كنت لا ترغب في اختبار 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.

يمكنك قراءة المزيد هنا عن نمط كائن الله المضاد.

استنتاج

في أي قاعدة بيانات كبيرة ، يوجد توازن ثابت بين إدارة الديون التقنية ، وبدء تطوير جديد ، وإدارة قائمة من الأخطاء لمنتجك.

آمل أن يكون هذا المقال قد أعطاك نظرة على اكتشاف متى قد تنزل في حفرة الأرانب بنمط مضاد ، وبعض الأدوات لحلها بطريقة نظيفة.

أشارك كتاباتي على Twitter إذا كنت قد استمتعت بهذا المقال ، وتريد رؤية المزيد.