الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Anti-pattern ، الأنماط البرمجية السيئة

بدأه Abdullah.Alshammeri في 13 مارس 2012 · 6 رد · 941 مشاهدة · في الأخبار والنقاشات التقنية
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

قبل قليل كنت أقرأ مقال عن عبقرية Drupal و مرونته ( وهو CMS باستخدام php ) ، و بدأت بمحاولة تطوير أول module ، و من الأشياء البديهية التي يمكن أن أفكر بها ، أن أعمل extend لـ Class اسمه Module ، و أرث دالة Function اسمها onCreate ، لأعمل لها Implementation بطريقتي. لكن للأسف وجدت Design Pattern مختلف ممكن نسمّيه " نمط : أكمل الفراغ " ، فكرته كالتالي :

0- لنفرض أنك تريد إنشاء Module بإسم Article .

1- أنشئ دالة اسمها onCreate_X .

2- استبدل X باسم module الخاص بك .

3- Drupal تستدعي بطريقة سحرية الدالة onCreate_Article .

هذا النمط الذي ابتلي به مبرمجي php و ( مبرمجي لغات أخرى ) ، نمط سيء من وجهة نظري المتواضعة. لأنه لا يوفر مقروئية جيدة للكود ، لن تستطيع فهم الكود إلا بعد أن ترى الفراغات و قد اكتملت وهذا لن يحدث إلا في وضع التشغيل وتحت اختبار شامل لكل المسارات . Java تدعم هذا الأسلوب ( بشيء يسمّى Reflection إن لم أكن مخطئ ) ، لكن في الغالب لا يستخدم إلا على نطاق ضيق و تحت ظروف قاهرة . و من يستخدمه لا يخبر به أحداً ، و يستر على نفسه و يستحي على وجهه .

php لديهم call_user_func و Java لديهم Class.forName . لكن الفرق في " كيف نستخدمها و أين ؟ " .

Anti-pattern

اكتشفت أثناء كتابتي لهذا الموضوع أن هناك تصنيف للأنماط السيئة التي يتبعها المبرمجون ، نمط " قص و لصق الكود " ، و نمط " جحيم DLL " ، و أنماط أخرى :

http://en.wikipedia.org/wiki/Anti-pattern#Software_design_anti-patterns

لا أعرف إن كان النمط المذكور في بداية الموضوع من ضمن الأنماط السيئة لكن شخصياً ، أؤمن بذلك .

هل تعرف أنماط سيئة ( برمجية طبعأً ) ؟

4

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#2

أكثر ما يزعجني - سوف أطلق عليها IDE anti-pattern : )

1) وجود Setter/Getter لأي member variable وحتى ولو لم يتم استخدامهم ،، البعض يعتمد على IDE في توليد ذلك ، مشكلة الIDE أنه لن يعرف أن هذا الكلاس مناسب ليكون Immutable أم لأ وانما سيولد كل شيء ,,

2) تطبيق public access modifier على كل الclasses, interfaces, methods .. أيضاً الIDE يقوم في العادة بتوليد ذلك تلقائياً,, مشكلة الpublic أنه سيظل معك للأبد ( سوف يكون Part of exported API) بينما الصحيح استخدام الأقل Private ثم الأقل package-private وهكذا (كل ما تكون part of implementation) كل ما أصبح الكود Modular وقابل للتغيير بسهولة واصلاح المشاكل والخ...

بالتوفيق،،

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#3

هلا وجدي ،

اقتباس
2) تطبيق public access modifier على كل الclasses, interfaces, methods .. أيضاً الIDE يقوم في العادة بتوليد ذلك تلقائياً,, مشكلة الpublic أنه سيظل معك للأبد ( سوف يكون Part of exported API) بينما الصحيح استخدام الأقل Private ثم الأقل package-private وهكذا (كل ما تكون part of implementation) كل ما أصبح الكود Modular وقابل للتغيير بسهولة واصلاح المشاكل والخ...

لم افهم قصدك ، ممكن توضح ؟

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#4
اقتباس
1- أنشئ دالة اسمها onCreate_X .

بذكرني هذا الإسلوب بفئات visual basic 6 حيث دائما ما كان ينشئ لك الدوال المقابله لـ constructor/destructor تقريبا نفس الإسلوب حتى تستطيع COM ان تتعامل معهم.

اقتباس

1) وجود Setter/Getter لأي member variable وحتى ولو لم يتم استخدامهم ،، البعض يعتمد على IDE في توليد ذلك، مشكلة الIDE أنه لن يعرف أن هذا الكلاس مناسب ليكون Immutable أم لأ وانما سيولد كل شيء ,,

على العكس هذه ميزه و ليست عيب و السبب ذكرته انت فى النقطه رقم 2 و هي ان الـ member variable سيتواجد فى الـ exported interface حينها ماذا يحدث إن اردت التحقق من القيمه لذلك المتغير، ستحتاج لتغيير الـ interface و كتابة getter/setter لذلك المتغير و لكن في حالة وجودهم فيكفي التعديل فى الـ implementation.

اقتباس

2) تطبيق public access modifier على كل الclasses, interfaces, methods .. أيضاً الIDE يقوم في العادة بتوليد ذلك تلقائياً,, مشكلة الpublic أنه سيظل معك للأبد ( سوف يكون Part of exported API) بينما الصحيح استخدام الأقل Private ثم الأقل package-private وهكذا (كل ما تكون part of implementation) كل ما أصبح الكود Modular وقابل للتغيير بسهولة واصلاح المشاكل والخ...

الـ IDE يقوم بتوليد الكود لتيسير عليك كتابة و ليس لتعتمده كما هو فى برنامجك و بالتالي الطبيعي ان تقوم بتغيير الـ access modifiers بعد توليد الكود.

و الله ولي التوفيق

1

مدونتي: C++ Tips and Tricks

#5

أخ وجدي

شاهد هذا الفيديو يتحدث عن نفس النقطة الي انت تكلمت عنها وفي لغة سكالا تم حل هذه المشكلة

في الدقيقة العاشرة

وإذا عندك وقت كمل المحاضرة للآخر، ابداااع

بالنسبة لي لغة Scala هي لغتي الأساسية

المطورين في جريدة الجارديان انتقلوا كليا الى سكالا وتركوا الجافا

المطورين في موقع تويتر كذلك، الباك إند كتبوه كاملا بسكالا بعدما تركوا روبي

وأنوي أن أضع موضوع منفرد عن لغة سكالا لكني منشغل

3
#6
Wajdy Essam كتب:

أكثر ما يزعجني - سوف أطلق عليها IDE anti-pattern : )

1) وجود Setter/Getter لأي member variable وحتى ولو لم يتم استخدامهم ،، البعض يعتمد على IDE في توليد ذلك ، مشكلة الIDE أنه لن يعرف أن هذا الكلاس مناسب ليكون Immutable أم لأ وانما سيولد كل شيء ,,

2) تطبيق public access modifier على كل الclasses, interfaces, methods .. أيضاً الIDE يقوم في العادة بتوليد ذلك تلقائياً,, مشكلة الpublic أنه سيظل معك للأبد ( سوف يكون Part of exported API) بينما الصحيح استخدام الأقل Private ثم الأقل package-private وهكذا (كل ما تكون part of implementation) كل ما أصبح الكود Modular وقابل للتغيير بسهولة واصلاح المشاكل والخ...

بالتوفيق،،

1- حسب علمى ب Eclipse (مثال على أشهر IDE في الجافا) فإن المعالج الذي يساعدك في عمل ذلك لا يكون فيه شئ بشكل إفتراضى بمعنى أنه إذا إستخدمت هذا المعالج فإنه يطلب منك إختيار الخصائص التى تريد عمل عليها Getter و Setter.

2- مم أيضا هذه النقطه تعتمد على إستخدامك ... ففي إكليبس أيضا لا أجده يفرض على أي Access Modifier.

اقتباس
وأنوي أن أضع موضوع منفرد عن لغة سكالا لكني منشغل

أنتظرها بفارغ الصبر :)

@عبدالله الشمري ..

أوليس يندرج هذا تحت Convention over Configuration

(ملحوظه لا أختلف معك في كونه نمط سئ ولكن مبدأ COC ليس بهذا السوء)

1
#7

من أحد الأشياء التي تفصل بين الModule المصممة بشكل جيد، من المصممة بشكل سيء هي درجة اخفاء الInternal Data And Implementation من الModules الأخرى ,, حيث يكون التعامل بين كل Module وأخرى من خلال مجموعه معينة من الAPI بدون معرفة تفاصيل أكثر ، وهذا هو مفهوم الInformation Hiding (أو Encapsulation ) والذي كما هو معلوم أحد العناصر المهمة في تصميم البرامج..

اخفاء التفاصيل بين اللModule مهمة لكثير من الأمور، أولها لن يكون هناك ارتباط قوي Tightly Coupled بينها وهذا يعني أنه بالإمكان تغيير الImplementation ( سواء كان Adding More Features أو حتى Optimizing) في أحدى الModule ولن تتأثر الأخرى على الإطلاق، وهذا يعني سرعة في التطوير، فالإمكان أن يعمل فريق في Module معين مثلاً Reports بينما يعمل فريق أخرى مثلاً في Searching بينما يعمل أخر في License وهكذا .. قد قمت بذلك عملياً في احدى الأنظمة مع فريق من المبرمجين ، وأحد الفوائد الأخرى التي جنيتها هو عدم الخوف من أحد المبرمجين -المبتدئين- من التمادي :) أكثر من الModule الذي يعمل ، والذي يمكن تغييره بالكامل (تحسينه ، اصلاحه) فيما بعد فور أن ينتهي هو من العمل .. أمر أخر وهو تقليل خطورة تطوير منتج ضخم ،، فحتى لو فشل التطبيق سوف تكون لديك أجزاء جيدة يمكن تركيبها في تطبيق أخر بنفس الفكرة أو حتى نفس التطبيق النسخه رقم 2 ..

هذه أحدى مزاياه الInformation Hiding ولم أسترسل بها حيث أنها نظرياً معروفة لدى الجميع،، وفي لغات البرمجة (وسأتحدث في جافا على وجه الخصوص) سوف تساعدنا الAccess Control في ذلك كثيراً.. واستخدامها بشكل صحيح هي خطوة أولى في التصميم الصحيح ،، ولذلك تحدثت عن هذه النقطة ،، حيث القاعدة هنا يمكن وصفها بهذه العباره الرائعه (make each class or member as inaccessible as possible ) وهنا المقصد أستخدام أقل Access Level بقدر المستطاع لكل ما سوف تقوم بكتابته ،،

مثلاً للTop Level Classes (أي كلاس ما عدا الNested) في جافا لدينا أحتمالين هو public class MyClass أو class MyClass الخيار الأول هو public بينما الثاني Package-private ، الأول سوف يكون من ضمن الAPI (التي يستطيع الكلاينت استخدامها، بينما الثانية سوف لك أنت part of implementation) وتستطيع تغييرها كما تريد ولن يعرف الكلاينت ،، وهكذا الأمر بالنسبة للmethods و الvariables ،، كلما نصل الى أكبر عدد من الHiding للتفاصيل ونقلل من الpublic كلما كان التصميم أقضل وأسهل للتعامل معه لاحقاً,,

بالنسبة لقضية الSetter/Getter فهم بحد ذاتهم لا مشاكل في استخدامها في المكان الصحيح، المشكلة هي استخدامها لكل شيء فقط بمجرد مشاهدة متغير private في الكلاس فعلى الفور يتم توليد الGetter/Setter ،، هكذا لن يوجد اي Hiding أو Encapsulation الكل سوف يكون متاح ، هذا الموضوع لن يظهر اذا كان الكلاس هو مجرد حامل للبيانات بدون اي عمليات أو Behaver في الكلاس ... مثلاً لدي Queue من أي كائن ،، قد يكون الImplementation هو LinkedList أو يكون Array ،، فلماذا أقوم بعمل getArray أو setLinkedList كدوال public في هذا الكلاس وبالتالي سوف أحتاج الى أن تصبح هذه الImplementation جزءاً من الAPI التي يستطيع الكلاينت العمل عليها ،، الصحيح هو اخفائها تماماً،، اللهم الا في حالة كنت أود تغيير الImplementation وقت التشغيل فأيضاً في هذه الحالة لن أقوم أيضاً بالعمل على getArray أو setLinkedList (قد يكون لدينا setAlgrithm تستقيل interface أو parent class تمثل الImplementation)..

الأمر الثاني ضد الSetter خصوصاً هو أنه في بعض الأحيان تحتاج لارسال البيانات عبر الConstructor فقط ،، ولن تحتاج لتغيير القيمة في ذلك الكلاس بعد ذلك،، فلم الحاجة لSetter قد تعيقك فيما بعد عندما يكون الكائن من هذا الكلاس Shared لأكثر من الThread ،، محاولة تطبيق كلاس غير قابل للتعديل Immutable class هو من الحلول السهله والناحجه للهروب من مشاكل الThread Safety Problems ..

بالنسبة لي أقوم في كثير الأحيان بوضع أغلب الأشياء private وحتى الConstructors :) وأنشى الكائن باستخدام static factory method :

http://www.javapractices.com/topic/TopicAction.do?Id=21

كخلاصه عليك أن تقلل اي اتصال بين Module و أخر ، وتحاول أن تقلل الpublic بشكل كبير (سوف تتجلي ذلك في البرامج الكبيرة ) ، ولا تستخدم الsetter/getter الا في الأمكان المناسبة لذلك,, أرجوا أن تكون الفكرة قد اتضحت،،

لمن يريد المزيد عليه بالكتاب الرائع Effective Java:

Item 13: Minimize the accessibility of classes and members

Item 15: Minimize mutability

Item 1: Consider static factory methods instead of constructors

بالتوفيق،

تم تعديل هذه المشاركة بواسطة Wajdy Essam في 15 مارس 2012 في 02:04

4

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

مواضيع مشابهة