Singleton تحليل نمط تصميم مثيل بسيط
مقدمة
اليوم سأقدم لك ملخصًا شاملاً لنمط التصميم الأكثر شيوعًا في تطوير Android - وضع Singleton.
فيما يتعلق بمقدمة أنماط التصميم ، يمكنك قراءة ما كتبته من قبل: دقيقة واحدة لفهم "أنماط التصميم" تمامًا
جدول المحتويات
1
1.1 ما هي المشكلات التي يتم حلها
كما ذكرنا من قبل ، نمط التصميم = حل لنوع معين من المشكلات المحددة ، فما المشكلة التي هو نمط المفرد ؟
المعنى: singleton = مثيل ؛
تم حل المشكلة: قلل من الاقتران بين الكائنات
الحل: نمط Singleton ، أي تنفيذ أن الفئة لديها كائن واحد فقط تم إنشاءه ويوفر نقطة وصول عالمية
1.2 مقدمة مثيل
بعد ذلك ، أستخدم مثيلًا لتقديم نمط المفرد
الخلفية: Xiaocheng لديه مصنع للبلاستيك ، ولكن لا يوجد سوى مستودع واحد في الداخل.
الغرض: أريد استخدام الكود لتنفيذ إدارة المستودعات
الممارسات الحالية: إنشاء مستودعات وعمال
من بينها ، الكمية في فئة المستودعات = كمية البضائع ؛ العمال لديهم أساليب المناولة تتحرك (int i) و moveout (int i).
المشاكل: من خلال الاختبار ، تبين أنه في كل مرة يتحرك فيها عامل ، سيتم بناء مستودع جديد ، أي أن البضائع لا يتم وضعها في نفس المستودع. ماذا يحدث هنا؟ (انظر الرمز أدناه)
حزمة scut.designmodel.singletonpattern ؛ // فئة Warehouse Class Storehouse {private int Quantity = 100 ؛ public void setquantity (int Quantity) {this.quantity = Quantity ؛ } public int getQuantity () {return Quantity ؛ }} // Walking Human Class Carrier {Public Storehouse Mstorehouse ؛ الناقل العام (Storehouse Storehouse) {mstorehouse = storehouse ؛ } // نقل البضائع إلى movein foid warehouse (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()+i) ؛ } // انتقل من MoveOut public void Warehouse (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()-i) ؛ }} // معالجة العمال اختبار الفئة العامة singlepattern {public static void main (string [] args) {Storehouse mstorehouse1 = new Storehouse () ؛ storehouse mstorehouse2 = new Storehouse () ؛ Carrier Carrier1 = New Carrier (Mstorehouse1) ؛ Carrier Carrier2 = New Carrier (Mstorehouse2) ؛ System.out.println ("هل الاثنان متماثلان؟") ؛ if (mstorehouse1.equals (mstorehouse2)) {// استخدم متساويًا هنا بدلاً من الرمز == ، لأن الرمز == هو فقط لمقارنة عناوين الكائنين system.out.println ("هو نفسه") ؛ } آخر {system.out.println ("ليس هو نفسه") ؛ } // بعد قيام الحمال بنقل البضائع ، أبلغ عن كمية البضائع الموجودة في المستودع 1.movein (30) ؛ System.out.println ("Margin Warehouse:"+carrier1.mstorehouse.getQuantity ()) ؛ carrier2.moveout (50) ؛ System.out.println ("Marehouse Product Margin:"+carrier2.mstorehouse.getQuantity ()) ؛ }}نتيجة:
هل الاثنان متماثلان؟ هامش المنتج في نفس المستودع: 130 هامش منتج المستودعات: 50
2. مقدمة لنمط المفرد
2.1 حل المشاكل (سيناريوهات التطبيق)
الصراع: من النتائج المذكورة أعلاه ، يمكن ملاحظة أن العمال يعملون من الواضح أنه ليس نفس مثيل المستودع.
الهدف: يعمل جميع العمال على نفس مثال المستودع
يعد نمط Singleton حلاً لهذا النوع من المشكلات: تنفيذ فئة مع كائن واحد فقط من إنشاء مثيل له ويوفر مبدأ عمل عالمي للوصول 2.2
في Java ، نقوم بتشغيل هذه الفئات باستخدام كائنات (بعد إنشاء فئة). يتم تنفيذ إنشاء فئة من خلال مُنشئها . إذا أردنا تنفيذ أن فئة واحدة تحتوي على كائن واحد فقط ، فيجب علينا العمل على مُنشئ الفصل:
التنفيذ العام لوضع المفرد: (بما في ذلك خطوات الاستخدام)
الطبقة العامة Singleton {// 1. قم بإنشاء متغير خاص ourinstance (يستخدم لتسجيل مثيل فريد من Singleton) // 2. مثيل داخلي خاص داخليًا ثابتًا في Singleton Ourinstance = New Singleton () ؛ // 3. خصخصة مُنشئ الفئة ومنع المكالمات الخارجية لإنشاء مثيل خاص () {} // 4. حدد طريقة عامة لتوفير نقطة وصول فريدة عالمية للفئة // 5. إرجاع مثيل فريد خارجيًا من خلال استدعاء طريقة getInstance () العامة الثابتة Singleton NewInstance () {return ourinstance ؛ }}حسنًا ، يجب أن تفهم مقدمة ومبادئ نمط Singleton ، أليس كذلك؟ لذلك دعونا نحل المشكلة القائلة بأن "المستودع ليس هو نفسه" الذي ظهر فوق Xiaocheng!
2.3 مثال مقدمة
يستخدم Xiaocheng وضع Singleton لتحسين رمز المثال أعلاه:
package scut.designmodel.singletonpattern ؛ استيراد java.util.concurrent.lock.lock ؛ import java.util.concurrent.locks.reentrantlock ؛ // singleton warehouse class {// كمية منتجات المستودعات الخاصة = 100 ؛ // instantiate static static oreinstance = new Storehouse () ؛؛ // اسمحوا للاتصال الخارجي بالطريقة getInstance () لإرجاع المثيل الفريد. Static Static Storehouse getInstance () {return ourinstance ؛ }. } public int getQuantity () {return Quantity ؛ }} // Carrier Man Class Carrier {public storehouse mstorehouse ؛ الناقل العام (Storehouse Storehouse) {mstorehouse = storehouse ؛ } // نقل البضائع إلى movein foid warehouse (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()+i) ؛ } // انتقل من MoveOut public void Warehouse (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()-i) ؛ }} // معالجة العمال اختبار الفئة العامة singlepattern {public static void main (string [] args) {Storehouse mstorehouse1 = storehouse.getInstance () ؛ storehouse mstorehouse2 = storehouse.getInstance () ؛ Carrier Carrier1 = New Carrier (Mstorehouse1) ؛ Carrier Carrier2 = New Carrier (Mstorehouse2) ؛ System.out.println ("هل الاثنان متماثلان؟") ؛ if (mstorehouse1.equals (mstorehouse2)) {system.out.println ("هو نفسه") ؛ } آخر {system.out.println ("ليس نفس الشيء") ؛ } // بعد قيام الحمال بنقل البضائع ، أبلغ عن كمية البضائع في المستودع ، carrier1.movein (30) ؛ System.out.println ("Margin Warehouse:"+carrier1.mstorehouse.getQuantity ()) ؛ carrier2.moveout (50) ؛ System.out.println ("Marehouse Product Margin:"+carrier2.mstorehouse.getQuantity ()) ؛ }}نتيجة:
هل الاثنان متماثلان؟ إنه نفس هامش سلعة المستودع: 130 هامش سلع المستودع: 80
وفقًا لتحليل النتائج ، بعد استخدام نموذج Singleton ، لا يوجد سوى مثيل مستودع واحد في فئة المستودعات ، وليس هناك حاجة للقلق بشأن دخول الحمالين إلى المستودع الخاطئ! ! !
2.4 المزايا
2.5 العيوب
3. تنفيذ وضع المفرد
3.1 الوضع العام
أسلوب جائع (أبسط طريقة تنفيذ سينجلتون)
Class Singleton {Private Static Singleton Ourinstance = New Singleton () ؛ خاص singleton () {} الثابتة العامة singleton newinstance () {return ourinstance ؛ }}سيناريوهات التطبيق:
أسلوب كسول
الفرق الأكبر بين الكسول والجائع هو توقيت عملية تهيئة المفردات :
Class Singleton {private Static Singleton ourinstance = null ؛ Singleton الخاص () {} ثابتة عامة Singleton NewInstance () {if (ourinstance == null) {ourinstance = new Singleton () ؛ } إرجاع ourinstance ؛ }}سيناريوهات التطبيق:
3.2 تنفيذ وضع Singleton تحت الرأي المتعدد
في حالة Multithreading:
الحل 1: مزامنة القفل
استخدم قفل المزامنة المزامنة (singleton.class) لمنع إدخال مؤشرات ترابط متعددة في وقت واحد ، مما تسبب في إنشاء مثيل عدة مرات.
Class Singleton {private Static Singleton ourinstance = null ؛ Singleton الخاص () {} ثابتة عامة Singleton NewInstance () {Synchronized (Singleton.class) {if (ourinstance == null) {ourinstance = new Singleton () ؛ }} إرجاع ourinstance ؛ }}الحل 2: قفل التحقق المزدوج
تتمثل طبقة إذا تمت إضافتها على أساس قفل المزامنة (باستثناء متزامن (singleton.class)) لتحسين الأداء بعد أن تم إنشاء مثيل للمثال وفي المرة القادمة التي يدخل فيها ، لا يتعين عليه تنفيذ متزامن (singleton.class) للحصول على قفل الكائن ، مما يؤدي إلى تحسين الأداء.
Class Singleton {Private Static Singleton ourinstance = null ؛ خاص singleton () {} static static singleton newinstance () {if (ourinstance == null) {synchronized (singleton.class) {if (ourinstance == null) {ourinstance = new singleton () ؛ }}} إرجاع ourinstance ؛ }}الحل 3: فئة داخلية ثابتة
عند تحميل فئة JVM ، يتم ضمان مزامنة البيانات. نستخدم تطبيق الفئة الداخلية: إنشاء مثيلات كائن في الفصل الداخلي.
طالما أن التطبيق لا يستخدم الفئة الداخلية JVM ، فلن يتم تحميل فئة Singleton ، ولن يتم إنشاء كائن Singleton ، وبالتالي تحقيق التحميل الكسول "Lazy" وسلامة الخيط.
سيتم إنشاء كائن Singleton Class {// فقط عندما يتم تحميل الفئة الداخلية من الدرجة الثابتة الخاصة Singleton2 {private Static Singleton ourinstance = new Singleton () ؛ } singleton private () {} Singleton Newinstance () {return Singleton2.ourinstance ؛ }}الحل 4: تعداد الأنواع
أبسط طريقة تنفيذ Singleton Singleton (الموصى بها من قبل "Java الفعالة")
التعداد العام singleton {// تحديد عنصر التعداد ، وهو مثيل مثيل Singleton ؛ void public dosomething () {}}كيفية استخدامه على النحو التالي:
singleton singleton = singleton.instance ؛ singleton.dosomething () ؛
5. ملخص
تقدم هذه المقالة بشكل أساسي نموذج Singleton ، بما في ذلك المبادئ وطرق التنفيذ. بعد ذلك ، سأستمر في شرح نماذج التصميم الأخرى. إذا كنت مهتمًا ، فيمكنك الاستمرار في الانتباه إليها.
شكرا لك على القراءة ، آمل أن تساعدك. شكرا لك على دعمك لهذا الموقع!