كشف نمط التصميم: نمط الاستراتيجية



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

'

مرحبًا بكم في المنشور الأول من سلسلة 'Design Patterns Exposed'. في هذه السلسلة سنقوم بالكشف عن كل نمط تصميم من البداية.





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

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



كل نمط تصميم مخصص لحل نوع معين من المواقف قد تكون هناك مواقف يمكن فيها استخدام أكثر من نمط تصميم واحد.

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

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



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

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

كيف أقوم بذلك؟

حسنًا ، يمكن القيام بذلك باتباع مبادئ التصميم وأنماط التصميم بناءً على تلك المبادئ.

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

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

ما هو نمط الإستراتيجية؟

هذا هو التعريف مباشرة من كتاب 'عصابة الأربعة':يُستخدم نمط الإستراتيجية لإنشاء مجموعة خوارزميات قابلة للتبديل يتم من خلالها اختيار العملية المطلوبة في وقت التشغيل'.

في حال كنتغير قادر على الفهم ، لا تقلق ، سنشرح ذلك فيأبسطالطريقلك لتفهم.

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

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

لذلك دعونا نحدد فئة Animal abstract وفئتين ملموستين ، Dog and Bird.

ما رأيك في التصميم أعلاه؟ هناك خطأ كبير في تصميمنا.

كل الحيوانات لا تستطيع الطيران ، كما في الحالة المذكورة أعلاه لا يستطيع الكلب الطيران. لكن لا يزال لديها سلوك 'الطيران'.

لقد ارتكبنا خطأ بكتابة طريقة fly () المجردة داخل فئة الحيوانات. سيؤدي هذا التصميم إلى إجبار كل فئة فرعية من Dog ، و Bird ، و Penguin ، و Crocodile ، و Goose ، وما إلى ذلك ، على تنفيذ طريقة fly ().

كان يجب أن نفهم أن الطيران قدرة لا تمتلكها جميع الحيوانات. من خلال توفير طريقة fly () في فئة Animal abstract ، قمنا بتعيين قدرة الطيران في جميع الفئات الفرعية وهو أمر غير صحيح لجميع الفئات الفرعية للحيوانات.

قد تفكر في ما هي المشكلة في تنفيذ طريقة الطيران في الفئات الفرعية. على الرغم من أنه يمكنك تنفيذ طريقة fly () في الفئات الفرعية للحيوانات غير الطائرة فقط لطباعة 'لا أستطيع الطيران'. لكن المشكلة هي أنك مازلت تعطي سلوك الذبابة للحيوانات غير الطائرة. هذا ليس صحيحا.

ما هو شعورك عند استدعاء dog.fly () أو crocodile.fly ().

لذا ، فهمنا الآن أن تصميمنا غير صحيح ويجب علينا إزالة طريقة fly () من فئة Animal الفرعية.

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

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

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

الآن دعنا نحدد واجهة الطيران

الآن ، سيتم تغيير فئة الكلابمثلالكود أدناه ولا يحتاج إلى سلوك طيران.

دعنا نرى بعض فئات الحيوانات الفرعية لدينا التي سيكون لها سلوك الطيران.

لقد حللنا مشكلتنا السابقة ، لكننا واجهنا مشكلة جديدة وهي 'تكرار الرمز'.

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

لكن لا تقلق ، فإن نمط الإستراتيجية موجود لإخراجك من هذه المشكلة.

لذلك دعونا نعيد صياغة الكود الخاص بنا لاستخدام نمط الإستراتيجية.

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

لذا ، كيف يعمل كل شيء ، دعونا نرى TestClass

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

متى تستخدم نمط الإستراتيجية؟

عندما تريد أن تكون قادرًا على تغيير السلوك في وقت التشغيل ديناميكيًا.

للتأكد من فهمك لنمط الإستراتيجية بوضوح ، فلنأخذ مثالاً آخر.

في فئة الموظف أعلاه ، نحدد أجر الموظف اعتمادًا على تعيينه / تعيينها. إذا كان الموظف 'متدربًا' فإننا نضيف 10٪ علاوة في الراتب الأساسي لحساب الأجر الفعلي.

إذا كان الموظف 'مطور ويب' ، فإننا نضيف مكافأة بنسبة 20٪ في الراتب الأساسي لحساب الراتب الفعلي وتتبع العملية المماثلة لأنواع أخرى من الموظفين. على الرغم من أن الخوارزمية الخاصة بنا لحساب الراتب الفعلي بسيطة للغاية لتسهيل فهمها ، إلا أنها تتضمن في معظم الأحيان العديد من المقارنات والحسابات.

إذن ، ما الخطأ في رمز فئة الموظف؟

حسنًا ، رمز حساب الأجر (getPay ()) ثابت. افترض أنني أريد تغيير مكافأة 'المتدرب' من 10٪ إلى 14٪. سأضطر إلى فتح رمز فئة الموظف وتغييره.

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

دعونا نعيد صياغة الكود لاستخدام نمط الإستراتيجية.

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

الآن ، دعونا نرى كيف ستتغير فئة الموظف.

ملحوظة: لقد قمت بإزالة منطق حساب الأجور من فئة الموظف وأنشأت طريقة خوارزمية PayAlgorithm محددة من خلالها سأقوم بتعيين خوارزمية PayAlgorithm التي أريد استخدامها لحساب الأجور.

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

لذلك دعونا نرى أنه يعمل.

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

هندسة معمارية mvc في جافا مع رسم بياني

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

احترس من المنشور التالي ، حيث سنكشف عن أحد أنماط التصميم الأكثر شيوعًا ، نمط المصنع.

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

لديك سؤال لنا؟ أذكرها في قسم التعليقات وسنعاود الاتصال بك.

المنشورات ذات الصلة: