يتميز النمط المفرد بالخصائص التالية:
1. يمكن أن تحتوي الفئة المفردة على مثيل واحد فقط.
2. يجب على الفصل المفرد إنشاء مثيل فريد خاص به.
3. يجب أن توفر الفئة المفردة هذا المثيل لجميع الكائنات الأخرى.
يضمن النمط المفرد وجود مثيل واحد فقط للفئة، ويقوم بإنشاء مثيل لنفسه ويوفر هذا المثيل للنظام بأكمله. في أنظمة الكمبيوتر، غالبًا ما يتم تصميم تجمعات الخيوط وذاكرة التخزين المؤقت وكائنات السجل ومربعات الحوار والطابعات وكائنات برنامج تشغيل بطاقة الرسومات على أنها مفردة. تتمتع جميع هذه التطبيقات بوظائف مديري الموارد بشكل أو بآخر. يمكن أن يحتوي كل كمبيوتر على عدة طابعات، ولكن لا يمكن أن يكون هناك سوى مخزن مؤقت واحد للطابعة لمنع إخراج مهمتي طباعة إلى الطابعة في نفس الوقت. يمكن أن يحتوي كل كمبيوتر على عدة منافذ اتصال، ويجب على النظام إدارة منافذ الاتصال هذه مركزيًا لمنع استدعاء منفذ اتصال واحد من خلال طلبين في نفس الوقت. باختصار، الغرض من اختيار الوضع الفردي هو تجنب الحالات غير المتسقة وتجنب السياسات طويلة المدى.
أولاً، دعونا نلقي نظرة على التنفيذ المفرد الكلاسيكي.
انسخ رمز الكود كما يلي:
الطبقة العامة سينجلتون {
مفردة ثابتة خاصة UniqueInstance = null;
سينجلتون خاص () {
// موجود فقط لهزيمة إنشاء مثيل.
}
public static Singleton getInstance() { if (uniqueInstance == null) {
UniqueInstance = new Singleton();
}
إرجاع حالة فريدة؛
}
// طرق أخرى...
}
يتجنب Singleton إنشاء مثيل للفئة خارجيًا عن طريق قصر طريقة البناء على طريقة خاصة ضمن نطاق نفس الجهاز الظاهري، ولا يمكن الوصول إلى المثيل الوحيد لـ Singleton إلا من خلال طريقة getInstance(). (في الواقع، من الممكن إنشاء فئة بمنشئ خاص من خلال آلية انعكاس Java، والتي ستبطل بشكل أساسي جميع تطبيقات Java الفردية. لن تتم مناقشة هذه المشكلة هنا. دعنا نتظاهر بأن آلية الانعكاس غير موجودة. .)
ومع ذلك، لا يأخذ التنفيذ أعلاه في الاعتبار مشكلات سلامة الخيط. يعني ما يسمى بسلامة الخيط: إذا كانت هناك سلاسل رسائل متعددة تعمل في نفس الوقت في العملية التي يوجد بها الكود الخاص بك، فقد تقوم هذه الخيوط بتشغيل هذا الرمز في نفس الوقت. إذا كانت نتائج كل تشغيل هي نفس نتائج التشغيل ذو الخيط الواحد، وكانت قيم المتغيرات الأخرى هي نفسها كما هو متوقع، فهي آمنة للخيط. بمعنى آخر: الواجهة التي يوفرها الفصل أو البرنامج عبارة عن عملية ذرية لخيوط أو التبديل بين خيوط متعددة لن يسبب غموضًا في نتائج تنفيذ الواجهة، مما يعني أننا لسنا بحاجة إلى مراعاة مشكلات المزامنة. من الواضح أن التنفيذ أعلاه لا يلبي متطلبات سلامة سلسلة الرسائل، ومن المحتمل أن تظهر مثيلات Singleton المتعددة في بيئة متزامنة.
انسخ رمز الكود كما يلي:
// فئة مفردة على النمط الجائع تم إنشاء مثيل لها من تلقاء نفسها عند تهيئة الفصل.
الطبقة العامة Singleton1 {
// المُنشئ الافتراضي الخاص
سينجلتون خاص 1() {}
// تم إنشاء مثيل له بالفعل من تلقاء نفسه
نهائي ثابت خاص Singleton1 Single = new Singleton1();
// طريقة المصنع الثابتة
عام ثابت Singleton1 getInstance() {
عودة واحدة؛
}
}
// إنشاء نسخة مفردة كسول عند الاتصال بها لأول مرة
الطبقة العامة Singleton2 {
// المُنشئ الافتراضي الخاص
سينجلتون خاص 2 () {}
// ملاحظة، لا يوجد نهائي هنا
Singleton2 ثابت خاص = فارغ؛
// طريقة المصنع الثابتة
Singleton2 getInstance () العام المتزامن الثابت
إذا (مفرد == فارغ) {
Single = new Singleton2();
}
عودة واحدة؛
}
}