كيفية جعل سينغلتون الكمال؟

أنماط التصميم شائعة بين مطوري البرامج. نمط التصميم هو حل موصوف جيدًا لمشكلة البرامج الشائعة. يعد Singleton أحد أنماط التصميم الإبداعي في Java.

ما الهدف من الفردية؟

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

نظرًا لوجود مثيل Singleton واحد فقط ، فإن أي حقول مثيل لـ Singleton ستحدث مرة واحدة فقط لكل فصل ، تمامًا مثل الحقول الثابتة. غالبًا ما تكون المفردات مفيدة حيث يجب عليك التحكم في الموارد ، مثل اتصالات قاعدة البيانات أو مآخذ التوصيل.

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

تقييد إنشاء مثيل للفصل ويضمن وجود مثيل واحد فقط للفئة في الجهاز الظاهري java.

لنقم بإنشاء فصل مفرد في جافا واختباره في ظروف مختلفة.

إنشاء فئة سينجلتون

لتطبيق فئة المفرد ، أبسط طريقة هي جعل مُنشئ الفصل خاصًا. هناك طريقتان للتهيئة.

1. التهيئة حريصة:

في التهيئة حريصة ، يتم إنشاء مثيل Singleton Class في وقت تحميل الفئة ، وهذا هو أسهل طريقة لإنشاء فئة Singleton.

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

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

2. تهيئة كسول:

مقابل تهيئة Eager ، ستقوم هنا بتهيئة مثيل جديد للفئة في طريقة getInstance () بنفسها. هذه الطريقة سوف تحقق مما إذا كان هناك أي مثيل لتلك الفئة تم إنشاؤه بالفعل؟ إذا كانت الإجابة بنعم ، فستُرجع طريقتنا (getInstance ()) تلك المثيل القديم ، وإذا لم يكن الأمر كذلك ، فستقوم بإنشاء مثيل جديد من فئة المفرد في JVM وإرجاع ذلك المثيل. ويسمى هذا النهج كما كسول التهيئة.

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

أدناه هو سجل الإخراج مع رمز التجزئة في كل من الحالات.

كلاهما لديه نفس التجزئة.

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

جعل انعكاس سينجلتون دليل

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

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

هنا هو إخراج رموز التجزئة في كلتا الحالتين.

اختبار الانعكاس

كل الحالات لها رمز تجزئة مختلفة. يشير ذلك بوضوح إلى أن مستوى Singleton فشل في هذا الاختبار.

حل:

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

جعل موضوع Singleton آمنة

إذا حاول مؤشر ترابط تهيئة فئة Singleton في نفس الوقت تقريبًا ، ماذا يحدث؟ دعنا نختبر أدناه الكود الذي يتم فيه إنشاء اثنين من سلاسل الرسائل في وقت واحد تقريبًا ويدعون getInstance ().

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

هذا يعني أن فصلك المفرد ليس آمنًا. كلا مؤشرات الترابط يستدعي أسلوب getInstance () في نفس الوقت ، سيعود sSoleInstance == حالة فارغة لكل مؤشر الترابط. لذلك ، سيتم إنشاء مثيلين مختلفين من نفس الفئة. وهذا سوف كسر مبدأ سينغلتون.

حل:

1. جعل getInstance () متزامنة:

لنجعل طريقة getInstance () متزامنة.

أثناء قيامك بإجراء مزامنة فئة getInstance () ، سيتعين على مؤشر الترابط الثاني الانتظار حتى تكتمل طريقة getInstance () لمؤشر الترابط الأول. بهذه الطريقة يمكننا تحقيق سلامة موضوع.

ولكن ، هناك بعض سلبيات استخدام هذا النهج:

  • أداء بطيء بسبب قفل النفقات العامة.
  • المزامنة غير الضرورية غير مطلوبة بمجرد تهيئة متغير المثيل.

2. تحقق طريقة قفل مزدوج:

يمكنك التغلب على هذه المشكلة إذا كنت تستخدم طريقة تأمين الاختيار المزدوج لإنشاء Singleton.

في هذا ، ستجعل فئة Singleton في الكتلة المتزامنة إذا كان المثيل فارغًا. لذلك ، سيتم تنفيذ الكتلة المتزامنة فقط عندما تكون sSoleInstance خالية وتمنع المزامنة غير الضرورية بمجرد تهيئة متغير المثيل.

3. استخدام كلمة رئيسية متقلبة:

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

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

الآن ، فوق فئة سينجلتون هو موضوع آمن. يلزم جعل مؤشر ترابط Singleton آمنًا بشكل خاص في بيئة التطبيقات متعددة الخيوط مثل تطبيقات Android.

جعل Singleton في مأمن من التسلسل

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

دعنا نختبر صف منفرد سواء كان يحتفظ بنسخة واحدة بعد عمليات قابلة للتسلسل أو إلغاء التسلسل؟

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

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

استنتاج:

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

https://paypal.me/kpatel2106؟locale.x=en_GB

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