Singleton pattern في java و android

3zcsمنذ 8 سنوات

بسم الله الرحمن الرحيم

نكمل ما بدأناه في الحديث عن design pattern التي يكثر استخدامها في بيئة android

اليوم سيكون حديثنا عن Singleton

هذا pattern يصنف ضمن Creational Patterns والتي تهتم بطرق إنشاء objct أو مجموعة objects والعلاقات التي بينها في حال كان لدينا أكثر من object.

ونبدأ بتعريف هذا Pattern من كتاب GoF :

اقتباس

The singleton pattern ensures that only one object of a particular class is ever created. All further references to objects of the singleton class refer to the same underlying instance.

إذا في Singleton  يجعلك متأكدا من أن class الذي بنيته باستخدام هذا pattern انشأ منه object اوحد فقط .

وأول ما يخطر في بالك في حال كنت جديدا على هذا النمط, لماذا object اوحد فقط ؟ سيكون الجواب في نهاية المقالة بإذن الله

بداية سنبدأ بكتابة مثال بسيط على  Singleton pattern بلغة java


public class Singleton {
  
private static Singleton singleton = null ;

    private Singleton() {}

    public static Singleton getSingleton() {
        
        if (singleton == null)
            singleton = new Singleton();
        
        return singleton;
    }
    
}

يبدو واضحا من الوهلة الأولى أن class انف الذكر لا يمكن إنشاء أكثر من object منه.

في private Constructor لا تقوم بإنشاء أي object كما أن data member التي لديك static لكنها private بمعنى لديك static data member لا تستطيع الوصول إليه إلا عن طريق method داخل class

وهذه method تقوم بالتأكد فيما إذا كان لديك object تم إنشاؤه, والذي لن ينشأ غيره.

لكن في الحقيقة لو استخدمنا نفس هذا implementation في multithreading فقد ينشأ أكثر من object, فلمنع هذا حدوث هذه المشكلة لدينا أكثر من حل,فمثلا نستخدم synchronized keyword  والتي

ستعمل فقط مع thread واحده في نفس الوقت, لتفادي إنشاء أكثر من instance - وقد لا يكون أفضل حل-

قدد تتعدد طرق implementation ولكن تشترك في شيء واحد وهو أنه لا يمكن أنشاء أكثر من object من هذا class

طيب جميل جداً لان لنطبق هذا pattern على Android

سنقوم بالتالي بناء دالة تتأكد من حالة network وترجع true في حال كان هناك اتصال وError في حال لم يكن.


        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();

       if(info != null 
          		 && info.isConnectedOrConnecting()
   				 && cm.getActiveNetworkInfo() != null
                 && cm.getActiveNetworkInfo().isConnectedOrConnecting()){
         //your code 
       }
         

ستكرر هذه code في كل مكان تنوي فيه التحقق من حالة الشبكة,, وعندما تكرر code فيعتبر إشكال في تصميمه.

إذا ماذا سنفعل ؟

سنقوم بالتالي بناء App class , وهو class على مستوى التطبيق بمعنى يمكن لأي جزء من تطبيق أن يصل إليه, كيف ؟

يكون لدينا class فيه static method لكل object لا نحتاج لتكراره في code ومن ثم نستدعيه عن طريق class .

مثال


    public static boolean NetworkState(Context context){
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();

        return info != null
                && info.isConnectedOrConnecting()
                && cm.getActiveNetworkInfo() != null
                && cm.getActiveNetworkInfo().isConnectedOrConnecting();
    }

في هذه الحالة يمكننا التحقق من حالة network بهذه الطريقة


if(Application.NetworkState(Context context)){
//your code 
}

وهذا يمنحنا ميزة سهولة التعديل maintainable  في حال أردنا تغيير طريقة عمل function كإظهار تنبيه معين.

وقس على ذلك من المزايا , كما أن هذا المثال يمكن استخدامه مع عدد كبير من الحالات كإنشاء object من مكتبة retrofit والوصول له من أي مكان على مسوى التطبيق.

 

لا ينبغي عمل subclass ل Singleton  class حيث سيتوجب عليك جعل Constructor public وبعد هذا التغيير لم يعد class يسمى Singleton حيث يمكن إنشاء instance منه.

بالإضافة إلى أنك قد تكون جعلت static data member مما يعني أن subclass سيكون مشترك مع superclass في نفس data member وقد يؤدي إلى نتائج غير مرغوب فيها غالبا.

 

نجيب على التساؤل الذي طرحناه في بداية المقالة لماذا object اوحد فقط ؟

أتضح ولو بشكل جزئي من الأمثلة التي ذكرناها في بداية المقالة بعض فوائد Singleton, وهو أنه ستمر بك بعض الحالات لا تريد فيها أكثر من object وحيد تتعامل معه ومن هذه الحالات

Toast كما ذكرنا ,و thread pools و caches و logging والقائمة تطول, فمتى ما رأيت أن class فيه static class or data member هي التي تحتاجها فقط فسيكون Singleton حل مناسب لك.

 

المراجع:

Head First Design Patterns

http://www.javaworld.com/article/2073352/core-java/simply-singleton.html

http://www.blackwasp.co.uk/gofpatterns.aspx

http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples

كلمات دليلية:
3
إعجاب
8077
مشاهدات
0
مشاركة
4
متابع
متميز
محتوى رهيب

التعليقات (1)

AbdulAlim Rajjoub:

شكرا لك على الطرح الرائع ،ولكن عندي سؤال يخص المثال الذي ذكرته.

اذا قمنا بنسخ نفس الميثود التي تتحقق من الإتصال بالإنترنت وضعناها في Util Class وجعلنا هذه الميثود static بدون ان نطبق Singleton ،في هذه الحالة ما الفرق الذي سيكون مع وجود Singleton وبدون Singleton ؟

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !