CodeGym /مدونة جافا /Random-AR /الأنماط والمفردة في جافا
John Squirrels
مستوى
San Francisco

الأنماط والمفردة في جافا

نشرت في المجموعة
هذه المقالة موجهة إلى أي شخص، لأول مرة، يواجه مفهوم أنماط التصميم، أو سمع المصطلح Singleton ، أو قام بطريقة ما بتنفيذ النمط الفردي ولكنه لم يفهم ما كان يحدث. مرحباً! يواجه طلاب CodeGym أنماط التصميم لأول مرة في المستوى 15، عندما يطلب منهم الكابتن بشكل غير متوقع "تعزيز" فهمهم من خلال تنفيذ نمط Java Singleton مع التنفيذ البطيء. الطلاب الذين يسمعون عن النمط الفردي لأول مرة لديهم على الفور الكثير من الأسئلة: ما هو نمط التصميم في العالم؟ لماذا نحتاجه؟ ما هو المفرد ؟ وأخيرًا، ما هو التنفيذ البطيء؟ دعونا نجيب على هذه الأسئلة بالترتيب.

ما في العالم هو نمط التصميم؟

أعتقد أن القليل من التاريخ هو من أجل الإجابة على هذا السؤال بأفضل فهم. هناك أربعة مؤلفين برمجيين مشهورين (إريك جاما، جون فليسيدس، رالف جونسون، وريتشارد هيلم) الذين توصلوا إلى فكرة مثيرة للاهتمام. لقد لاحظوا أن تطوير البرمجيات غالبًا ما يتطلب منهم حل نفس المشكلات تقريبًا وكتابة التعليمات البرمجية المنظمة بنفس الطريقة. لذلك قرروا وصف الأنماط النموذجية التي غالبًا ما يلزم استخدامها في البرمجة الموجهة للكائنات. نُشر كتابهم في عام 1994 تحت عنوان أنماط التصميم: عناصر البرامج الموجهة للكائنات القابلة لإعادة الاستخدام. تبين أن اسم الكتاب طويل جدًا وبدأ الناس يطلقون عليه ببساطة اسم كتاب عصابة الأربعة. تضمنت الطبعة الأولى 23 نمطًا. وبعد ذلك تم اكتشاف العشرات من الأنماط الأخرى. لذلك دعونا نلخص إجابة سؤال هذه الفقرة (ما هي أنماط التصميم في العالم؟) في بضع كلمات:
نمط التصميم هو حل موحد لمشكلة شائعة.
والنمط الفردي هو مجرد واحد منهم.

لماذا نحتاج إلى أنماط التصميم؟

يمكنك البرمجة دون معرفة الأنماط: فبعد كل شيء، بحلول المستوى 15، تكون قد كتبت بالفعل مئات البرامج المصغرة على CodeGym دون حتى معرفة وجودها. يشير هذا إلى أن أنماط التصميم هي نوع من الأدوات التي يميز استخدامها المعلم عن الهواة: أنماط التصميم تصف كيفية حل مشكلة نموذجية بشكل صحيح. وهذا يعني أن معرفة الأنماط توفر عليك الوقت. وبهذه الطريقة، فهي تشبه الخوارزميات. على سبيل المثال، يمكنك إنشاء خوارزمية فرز خاصة بك باستخدام لعبة البلاك جاك والأرقام وقضاء الكثير من الوقت في القيام بذلك، أو يمكنك تنفيذ خوارزمية تم فهمها ووصفها لفترة طويلة. وينطبق الشيء نفسه على أنماط التصميم. بالإضافة إلى ذلك، مع أنماط التصميم، تصبح التعليمات البرمجية أكثر معيارية، وعند استخدام النمط المناسب، تقل احتمالية ارتكاب الأخطاء، حيث تم تحديد المخاطر الشائعة للنمط والقضاء عليها منذ فترة طويلة. علاوة على كل شيء آخر، تساعد معرفة الأنماط المبرمجين على فهم بعضهم البعض بشكل أفضل. يمكنك ببساطة قول اسم النمط بدلاً من محاولة تقديم شرح مطول لزملائك المبرمجين. خلاصة القول، أنماط التصميم تساعدك على:
  • عدم إعادة اختراع العجلة، بل استخدام الحلول القياسية بدلاً من ذلك؛
  • توحيد الكود؛
  • توحيد المصطلحات؛
في ختام هذا القسم، نلاحظ أنه يمكن تقسيم كامل أنماط التصميم إلى ثلاث مجموعات كبيرة: الأنماط والمفردات - لكل من يواجهها لأول مرة - 2

وأخيرا، نمط المفردة

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

  2. عندما تحتاج إلى توفير نقطة للوصول الشامل إلى كائن ما. بمعنى آخر، تحتاج إلى إتاحة الكائن من أي مكان في البرنامج. للأسف، لا يكفي إنشاء متغير عام ببساطة، لأنه ليس محميًا ضد الكتابة: يمكن لأي شخص تغيير قيمة المتغير، لذلك قد يتم فقدان نقطة الوصول العامة للكائن. تعتبر خصائص Singleton هذه ضرورية، على سبيل المثال، عندما يكون لديك كائن يعمل مع قاعدة بيانات، وتحتاج إلى الوصول إلى قاعدة البيانات من أجزاء مختلفة من البرنامج. سيضمن Singleton عدم قيام أي شخص بكتابة تعليمات برمجية تحل محل المثيل الذي تم إنشاؤه مسبقًا .
لذا فإن Singleton يلبي هذين الحاجتين: يجب أن يكون هناك كائن واحد فقط من نوع معين في البرنامج ويجب أن يكون هناك وصول عالمي إليه. في المثال الموجود في المستوى 15، يطلب منك الكابتن تنفيذ هذا النمط للمهمة التالية:
  1. ابحث عن مثال لـ Singleton مع التهيئة البطيئة.

  2. قم بإنشاء ثلاث فئات مفردة - الشمس والقمر والأرض - في ملفات منفصلة باستخدام نفس المبدأ.

  3. ينفذكوكبواجهة في فئات الشمس والقمر والأرض .

  4. في الكتلة الثابتة لفئة الحل ، قم باستدعاءreadKeyFromConsoleAndInitPlanetطريقة.

  5. تنفيذreadKeyFromConsoleAndInitPlanetوظيفة الطريقة:

    • 5.1. قراءة معلمة سلسلة واحدة من وحدة التحكم

    • 5.2. إذا كانت المعلمة تساوي أحدكوكبثوابت الواجهة، قم بإنشاء كائن الكوكب المناسب .

بعد قراءة شروط المهمة بعناية، يمكننا أن نرى بوضوح سبب الحاجة إلى Singleton هنا. في الواقع، طُلب منا إنشاء مثيل لكل فئة من الفئات التالية: Sun ، Moon ، Earth . فمن المنطقي أن نفترض أننا لا ينبغي أن نخلق أكثر من شمس/قمر/أرض واحدة. وإلا فإننا ندخل في موقف سخيف، إلا إذا كنت بالطبع تكتب نسختك من Star Wars. تنفيذ نمط Singleton في Java في ثلاث خطوات في Java، لا يمكن تنفيذ سلوك Singleton باستخدام مُنشئ عادي، لأن المُنشئ يُرجع دائمًا كائنًا جديدًا. لذلك ، تتلخص جميع تطبيقات Singleton في إخفاء المُنشئ، وإنشاء طريقة ثابتة عامة تتحكم في عمر الكائن المفرد، و"تدمير" جميع الكائنات التي تظهر حديثًا. إذا تم الوصول إلى Singleton ، فيجب إما إنشاء كائن جديد (إذا لم يكن موجودًا بالفعل في البرنامج)، أو إرجاع كائن موجود. لانجاز هذا:
  1. تحتاج إلى منح الفصل حقلًا ثابتًا خاصًا يخزن كائنًا واحدًا:

    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
  2. اجعل المُنشئ (الافتراضي) خاصًا. هذا يعني أنه لا يمكن الوصول إليه خارج الفصل ولن يتمكن من إرجاع كائنات جديدة:

    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    }
  3. أعلن عن طريقة إنشاء ثابتة سيتم استخدامها للحصول على المفردة:

    public class LazyInitializedSingleton {
        private static LazyInitializedSingleton instance;
            private LazyInitializedSingleton() {}
            public static LazyInitializedSingleton getInstance() { // #3
            if (instance == null) { // If the object has not yet been created
                instance = new LazyInitializedSingleton(); // Create a new object
            }
            return instance; // Return the previously created object
        }
    }
المثال أعلاه أخرق إلى حد ما، لأننا ببساطة نخفي المُنشئ ونوفر طريقتنا الخاصة بدلاً من المُنشئ القياسي. نظرًا لأن هذه المقالة تهدف إلى ضمان تواصل طلاب CodeGym مع هذا النمط (وأنماط التصميم بشكل عام)، فلن يتم هنا وصف الفروق الدقيقة في التطبيقات المفردة الأكثر تعقيدًا. نلاحظ فقط أنه، اعتمادًا على مدى تعقيد البرنامج، قد يحتاج هذا النمط إلى مزيد من التحسين. على سبيل المثال، في بيئة متعددة مؤشرات الترابط (راجع المقالات حول سلاسل الرسائل)، قد تصل عدة سلاسل رسائل مختلفة إلى الأسلوب المفرد في وقت واحد، وسيتوقف الكود الموضح أعلاه عن العمل، حيث يمكن لكل مؤشر ترابط منفصل إنشاء مثيل للفئة. ونتيجة لذلك، لا تزال هناك عدة طرق مختلفة لإنشاء مفردات مناسبة وآمنة للخيط. لكن تلك قصة أخرى =)

وأخيراً... ما هذا التهيئة البطيئة التي سأل عنها الكابتن؟

تسمى التهيئة البطيئة أيضًا بالتهيئة المؤجلة. هذه هي خدعة البرمجة حيث يتم تنفيذ عملية كثيفة الاستخدام للموارد (وإنشاء كائن هو عملية كثيفة الاستخدام للموارد) عند الطلب وليس مقدمًا. إذن ما الذي يحدث بالفعل في كود Singleton Java الخاص بنا؟ بمعنى آخر، يتم إنشاء كائننا في وقت الوصول إليه، وليس مقدمًا. لا ينبغي أن تفترض أن التهيئة البطيئة مرتبطة بشكل صارم بنمط Singleton . تُستخدم التهيئة البطيئة أيضًا في أنماط التصميم الإبداعي الأخرى، مثل Proxy وFactory Method، ولكن هذه أيضًا قصة أخرى =)
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION