JavaRush /جاوا بلاگ /Random-UR /ڈیزائن پیٹرن: سنگلٹن

ڈیزائن پیٹرن: سنگلٹن

گروپ میں شائع ہوا۔
ہیلو! آج ہم مختلف ڈیزائن پیٹرن پر گہری نظر ڈالیں گے، اور ہم سنگلٹن پیٹرن سے آغاز کریں گے، جسے "سنگلٹن" بھی کہا جاتا ہے۔ ڈیزائن پیٹرن: سنگلٹن - 1آئیے یاد رکھیں: ہم عام طور پر ڈیزائن پیٹرن کے بارے میں کیا جانتے ہیں؟ ڈیزائن پیٹرن بہترین طرز عمل ہیں جن کی پیروی کئی معلوم مسائل کو حل کرنے کے لیے کی جا سکتی ہے۔ ڈیزائن پیٹرن عام طور پر کسی بھی پروگرامنگ زبان سے منسلک نہیں ہوتے ہیں۔ انہیں سفارشات کے ایک سیٹ کے طور پر لیں، جس پر عمل کرتے ہوئے آپ غلطیوں سے بچ سکتے ہیں اور اپنے پہیے کو دوبارہ نہیں بنا سکتے۔

سنگلٹن کیا ہے؟

سنگلٹن سادہ ترین ڈیزائن پیٹرن میں سے ایک ہے جسے کلاس پر لاگو کیا جا سکتا ہے۔ لوگ بعض اوقات کہتے ہیں "یہ کلاس سنگلٹن ہے"، یعنی یہ کلاس سنگلٹن ڈیزائن پیٹرن کو نافذ کرتی ہے۔ بعض اوقات ایک کلاس لکھنا ضروری ہوتا ہے جس کے لیے صرف ایک آبجیکٹ بنایا جا سکتا ہے۔ مثال کے طور پر، ایک کلاس جو لاگ ان کرنے یا ڈیٹا بیس سے جڑنے کے لیے ذمہ دار ہے۔ سنگلٹن ڈیزائن پیٹرن بیان کرتا ہے کہ ہم اس طرح کے کام کو کیسے پورا کر سکتے ہیں۔ سنگلٹن ایک ڈیزائن پیٹرن ہے جو دو چیزیں کرتا ہے:
  1. اس بات کی ضمانت فراہم کرتا ہے کہ کلاس میں کلاس کی صرف ایک مثال ہوگی۔

  2. اس کلاس کی مثال کے لیے ایک عالمی رسائی پوائنٹ فراہم کرتا ہے۔

لہذا، دو خصوصیات ہیں جو سنگلٹن پیٹرن کے تقریباً ہر نفاذ کی خصوصیت ہیں:
  1. پرائیویٹ کنسٹرکٹر۔ کلاس سے باہر کلاس آبجیکٹ بنانے کی صلاحیت کو محدود کرتا ہے۔

  2. ایک عوامی جامد طریقہ جو کلاس کی ایک مثال واپس کرتا ہے۔ اس طریقہ کو کہا جاتا ہے getInstance۔ یہ کلاس مثال کے لیے عالمی رسائی کا نقطہ ہے۔

نفاذ کے اختیارات

سنگلٹن ڈیزائن پیٹرن کو مختلف طریقوں سے استعمال کیا جاتا ہے۔ ہر آپشن اپنے طریقے سے اچھا اور برا ہوتا ہے۔ یہاں، ہمیشہ کی طرح: کوئی مثالی نہیں ہے، لیکن آپ کو اس کے لئے کوشش کرنے کی ضرورت ہے. لیکن سب سے پہلے، آئیے اس بات کی وضاحت کرتے ہیں کہ کیا اچھا ہے اور کیا برا، اور کون سے میٹرکس ڈیزائن پیٹرن کے نفاذ کی تشخیص کو متاثر کرتے ہیں۔ آئیے مثبت کے ساتھ شروع کریں۔ یہاں وہ معیار ہیں جو نفاذ کو رسیلی اور کشش دیتے ہیں:
  • سست ابتداء: جب ایک کلاس لوڈ کی جاتی ہے جب ایپلی کیشن بالکل اسی وقت چل رہی ہو جب اس کی ضرورت ہو۔

  • کوڈ کی سادگی اور شفافیت: میٹرک، یقیناً ساپیکش، لیکن اہم ہے۔

  • تھریڈ سیفٹی: ملٹی تھریڈ والے ماحول میں صحیح طریقے سے کام کرتا ہے۔

  • ملٹی تھریڈ والے ماحول میں اعلی کارکردگی: دھاگے ایک دوسرے کو کم سے کم روکتے ہیں یا وسائل کا اشتراک کرتے وقت بالکل نہیں۔

اب cons. آئیے ان معیارات کی فہرست بنائیں جو عمل درآمد کو بری روشنی میں ظاہر کرتے ہیں:
  • غیر سست ابتداء: جب ایپلیکیشن شروع ہونے پر کلاس لوڈ کی جاتی ہے، قطع نظر اس کے کہ اس کی ضرورت ہے یا نہیں (ایک تضاد، آئی ٹی کی دنیا میں سست ہونا بہتر ہے)

  • کوڈ کی پیچیدگی اور ناقص پڑھنے کی اہلیت۔ میٹرک بھی موضوعی ہے۔ ہم مان لیں گے کہ اگر آنکھوں سے خون آئے تو اس پر عمل ہوتا ہے۔

  • دھاگے کی حفاظت کا فقدان۔ دوسرے الفاظ میں، "دھاگے کا خطرہ"۔ ملٹی تھریڈ والے ماحول میں غلط آپریشن۔

  • ملٹی تھریڈ والے ماحول میں خراب کارکردگی: دھاگے ہر وقت یا اکثر وسائل کا اشتراک کرتے وقت ایک دوسرے کو روکتے ہیں۔

کوڈ

اب ہم مختلف نفاذ کے اختیارات پر غور کرنے کے لیے تیار ہیں، فوائد اور نقصانات کی فہرست:

آسان حل

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}
سب سے آسان عمل درآمد۔ فوائد:
  • کوڈ کی سادگی اور شفافیت

  • دھاگے کی حفاظت

  • ملٹی تھریڈڈ ماحول میں اعلی کارکردگی

مائنس:
  • سست آغاز نہیں.
آخری خامی کو درست کرنے کی کوشش میں، ہمیں نفاذ نمبر دو ملتا ہے:

سست آغاز

public class Singleton {
  private static Singleton INSTANCE;

  private Singleton() {}

  public static Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
فوائد:
  • سست آغاز۔

مائنس:
  • دھاگہ محفوظ نہیں ہے۔

عمل درآمد دلچسپ ہے۔ ہم سستی سے شروع کر سکتے ہیں، لیکن ہم نے دھاگے کی حفاظت کھو دی ہے۔ کوئی مسئلہ نہیں: نفاذ نمبر تین میں ہم ہر چیز کو ہم آہنگ کرتے ہیں۔

مطابقت پذیر ایکسیسر

public class Singleton {
  private static Singleton INSTANCE;

  private Singleton() {
  }

  public static synchronized Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
فوائد:
  • سست آغاز۔

  • دھاگے کی حفاظت

مائنس:
  • ملٹی تھریڈڈ ماحول میں خراب کارکردگی

زبردست! عمل درآمد نمبر تین میں، ہم دھاگے کی حفاظت کو واپس لائے! سچ ہے، یہ سست ہے... اب طریقہ getInstanceمطابقت پذیر ہے، اور آپ اسے ایک وقت میں صرف ایک ہی درج کر سکتے ہیں۔ درحقیقت، ہمیں پورے طریقہ کو ہم آہنگ کرنے کی ضرورت نہیں ہے، بلکہ اس کا صرف وہ حصہ ہے جس میں ہم ایک نئی کلاس آبجیکٹ کو شروع کرتے ہیں۔ لیکن ہم کسی بلاک میں ایک نئی آبجیکٹ بنانے کے لیے ذمہ دار حصے کو صرف لپیٹ نہیں سکتے synchronized: یہ تھریڈ سیفٹی فراہم نہیں کرے گا۔ یہ تھوڑا زیادہ پیچیدہ ہے۔ ہم وقت سازی کا صحیح طریقہ ذیل میں دیا گیا ہے:

ڈبل چیک شدہ لاکنگ

public class Singleton {
    private static Singleton INSTANCE;

  private Singleton() {
  }

    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}
فوائد:
  • سست آغاز۔

  • دھاگے کی حفاظت

  • ملٹی تھریڈڈ ماحول میں اعلی کارکردگی

مائنس:
  • 1.5 سے کم جاوا ورژنز پر تعاون یافتہ نہیں ہے (متغیر مطلوبہ الفاظ کو ورژن 1.5 میں طے کیا گیا تھا)

میں نوٹ کرتا ہوں کہ نفاذ کے اس آپشن کو صحیح طریقے سے کام کرنے کے لیے، دو میں سے ایک شرط درکار ہے۔ متغیر INSTANCEیا تو ہونا چاہیے final، یا volatile۔ آخری نفاذ جس پر ہم آج بات کریں گے Class Holder Singleton۔

کلاس ہولڈر سنگلٹن

public class Singleton {

   private Singleton() {
   }

   private static class SingletonHolder {
       public static final Singleton HOLDER_INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
       return SingletonHolder.HOLDER_INSTANCE;
   }
}
فوائد:
  • سست آغاز۔

  • دھاگے کی حفاظت۔

  • ملٹی تھریڈڈ ماحول میں اعلی کارکردگی۔

مائنس:
  • درست آپریشن کے لیے، اس بات کی ضمانت دینا ضروری ہے کہ کلاس آبجیکٹ کو Singletonغلطیوں کے بغیر شروع کیا گیا ہے۔ بصورت دیگر، پہلا طریقہ کال getInstanceغلطی سے ختم ہو جائے گا ExceptionInInitializerError، اور اس کے بعد کی تمام ناکام ہو جائیں گی NoClassDefFoundError۔

عمل درآمد تقریباً کامل ہے۔ اور سست، اور دھاگے سے محفوظ، اور تیز۔ لیکن مائنس میں بیان کردہ ایک nuance ہے. سنگلٹن پیٹرن کے مختلف نفاذ کا موازنہ جدول:
عمل درآمد سست آغاز دھاگے کی حفاظت ملٹی تھریڈنگ کی رفتار کب استعمال کریں؟
آسان حل - + تیز کبھی نہیں۔ یا جب سست ابتداء اہم نہیں ہے۔ لیکن کبھی بہتر نہیں۔
سست آغاز + - قابل اطلاق نہیں۔ ہمیشہ جب ملٹی تھریڈنگ کی ضرورت نہ ہو۔
مطابقت پذیر ایکسیسر + + آہستہ آہستہ کبھی نہیں۔ یا جب ملٹی تھریڈنگ کے ساتھ کام کی رفتار میں کوئی فرق نہیں پڑتا۔ لیکن کبھی بہتر نہیں۔
ڈبل چیک شدہ لاکنگ + + تیز غیر معمولی معاملات میں جب آپ کو سنگلٹن بناتے وقت مستثنیات کو سنبھالنے کی ضرورت ہوتی ہے۔ (جب کلاس ہولڈر سنگلٹن لاگو نہیں ہوتا ہے)
کلاس ہولڈر سنگلٹن + + تیز ہمیشہ جب ملٹی تھریڈنگ کی ضرورت ہوتی ہے اور اس بات کی گارنٹی ہوتی ہے کہ سنگلٹن کلاس آبجیکٹ بغیر کسی پریشانی کے بنایا جائے گا۔

سنگلٹن پیٹرن کے فوائد اور نقصانات

عام طور پر، سنگلٹن بالکل وہی کرتا ہے جس کی اس سے توقع کی جاتی ہے:
  1. اس بات کی ضمانت فراہم کرتا ہے کہ کلاس میں کلاس کی صرف ایک مثال ہوگی۔

  2. اس کلاس کی مثال کے لیے ایک عالمی رسائی پوائنٹ فراہم کرتا ہے۔

تاہم، اس پیٹرن کے نقصانات ہیں:
  1. سنگلٹن SRP (سنگل ذمہ داری کے اصول) کی خلاف ورزی کرتا ہے - سنگلٹن کلاس، اپنی فوری ذمہ داریوں کے علاوہ، اپنی کاپیوں کی تعداد کو بھی کنٹرول کرتی ہے۔

  2. سنگلٹن پر باقاعدہ کلاس یا طریقہ کا انحصار کلاس کے پبلک کنٹریکٹ میں نظر نہیں آتا۔

  3. عالمی متغیرات خراب ہیں۔ سنگلٹن آخر کار ایک بھاری عالمی متغیر میں بدل جاتا ہے۔

  4. سنگلٹن کی موجودگی عام طور پر ایپلی کیشن اور خاص طور پر سنگلٹن استعمال کرنے والی کلاسوں کی قابلیت کو کم کرتی ہے۔

ٹھیک ہے اب سب ختم ہو گیا ہے۔ ہم نے سنگلٹن ڈیزائن پیٹرن کو دیکھا۔ اب، اپنے پروگرامر دوستوں کے ساتھ زندگی بھر کی گفتگو میں، آپ نہ صرف یہ کہہ سکیں گے کہ اس کے بارے میں کیا اچھا ہے، بلکہ اس کے بارے میں کیا برا ہے اس کے بارے میں بھی کچھ الفاظ کہہ سکیں گے۔ نئے علم میں مہارت حاصل کرنے میں اچھی قسمت۔

اضافی پڑھنا:

تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION