Singleton

GOF Intent:
Ensure a class only has one instance, and provide a global point of access to it.

گاهي مي خواهيم مطمئن باشيم که از يک کلاس خاص فقط يک instant مي‌شود ساخت.
يک راه مي تواند استفاده از يک متغير سراسري باشد. اما اين روش از ساخت instant هاي ديگر جلوگيري نمي کند.


راه بهتر اين است که خود آن کلاس اين وظيفه را به عهده گيرد. دياگرام و مثال زير نحوه انجام اين کار را نمايش مي دهند:

Singleton

public class Singleton {

   private static final Singleton instance = new Singleton();

   private Singleton() { }

   public static Singleton getInstance() {
      return instance;
   }
}

در مثال فوق هنگام Load شدن کلاس در JVM، خود instance آن نيز ساخته مي‌شود. حتي اگر هرگز نيازي به آن نباشد و مورد دستيابي قرار نگيرد.
مي‌شود کاري کرد که وقتي instance براي اولين بار مورد نياز است، ساخته شود. به اين حالت Lazy Instantiation گفته مي‌شود. پياده سازي آن چنين است:

public class Singleton {

   private static Singleton instance = null;

   private Singleton() { }

   public static synchronized Singleton getInstance() {
      if (instance == null)
         instance = new Singleton();

      return instance;
   }

}

چند نکته:

  1. در حالت Lazy Instantiation اين امکان وجود دارد که متد getInstance بطور همزمان توسط دو thread فراخوانده شود و بيش از يک instant ساخته شود. براي جلوگيري از اين مساله کليدواژه synchronized به متد اضافه شده است. اين مشکل در روش اول وجود ندارد.
  2. حتي در اين حالت نيز مي توان با دستور
    Singleton clonedObject = (Singleton) obj.clone();
    يک کپي از کلاس ايجاد کرد. براي اينکه از اين کار هم جلوگيري شود بايد متد clone بدين صورت override شود:

public Object clone() throws CloneNotSupportedException {
   throw new CloneNotSupportedException();
}

  1. اگر لازم باشد که بتوان از Singleton يک SubClass تعريف نمود، بايد constructor آن از حالت private به protected تغيير کند. البته اين کار توصيه نمي شود. چون SubClass ها مي توانند، Constructor را override کنند و به حالت public در آورند و بدين ترتيب Singleton را نقض نمايند.
  2. Singleton ها نبايد serialized شوند، چون اگر پس از serialized شدن بيش از يک بار deseriaized شوند، در آن صورت بيش از يک instance از آن خواهيم داشت.

فايده هاي Singleton:

  • از آنجا که Singleton instance در خود کلاس Encapsulate شده است، مي توان تمام دسترسي ها به آن را کنترل نمود.
  • استفاده از Singleton به جاي متغير Global از شلوغ شدن name space برنامه جلوگيري مي کند.
  • اگر به هر دليل از Singleton بودن يک کلاس، صرف نظر شود، به راحتي مي توان آن را تغيير داد.
  • به همين روش مي توان تعداد Instance هاي يک کلاس را در برنامه کنترل نمود.

عيب Singleton:
به دليل وجود راه هايي براي دور زدن مفهوم singleton، اين pattern مخالفان زيادي دارد.

استفاده از Singleton در ديگر Design Pattern ها:

  • Pattern هاي Abstract Factory, Builder و Prototype مي توانند از Singleton استفاده کنند.
  • Object هاي Façade اغلب Singleton هستند.


منبع ها:

  1. Design Patterns – Elements of Reusable Object Oriented Software (GOF) By Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
  2. Singleton in wikipedia
  3. Singleton in javabeginner
  4. Singleton in javacoffeebreak
  5. Clone in wikipedia

با برچسب: ,
پست شده در Design Pattern

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*


+ 2 = یازده

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

تماس با من: admin@paspars.com