سلام
علاوه بر توضیحات دوستمون یه سری نکات رو هم من بگم.
درباره design pattern ها بهترین توضیحات رو میتونید از کتاب Gang of Four بخونید.
موارد استفاده singleton خیلی زیاده. اما بعضی جاها استفادش بی مورده که اصطلاحا بهش anti-pattern میگن.
یه مورده استفاده خوب از singleton object ها، توی معماری mvc ه. مثلا در لایه model یه سری کلاس داری که وظایفی مثل CRUD رو برای هر entity انجام میدن.
فرض کنیم قراره در هر ثانیه هزاران نفر درخواست بفرستن به سرور و یه رکورد از یه تیبلی رو بخوان. اونوقت شما میای هربار اون کلاسی که وظیفش گرفتن آبجکت از دیتابیسه رو new میکنی و بقیه ماجرا...
خب اینجا یه فاجعه رخ میده، یعنی؛ به ازای هر درخواست، یبار new کردن یه آبجکت نسبتا سنگین.
پس بهتره که اون آبجکت singleton باشه. اما singleton بودن هم مشکلات خاص خودشو داره.
یکیش thread-safe بودنه.
یه راه خیلی بدش اینه که بیای توابعت رو synchronized تعریف کنی و برای دسترسی متغیرها lock بزاری و ...
اما راه خیلی بهترش اینه که اون کلاس رو به صورت stateless پیاده کنی.
برای اینکه کلاسی رو stateless کنی، باید تمامی property های سطح کلاس رو حذف کنی (به جز مواردی که مشکل ساز نمیشه). یعنی هیچ چیز مشترکی بین thread هایی که قراره از اون آبجکت singleton استفاده کنن نباشه.
مثلا دوتا ترد همزمان بیان اون آبجکت singleton رو بگیرن و یه چیزی رو تغییر بدن!
در کل چنین کلاسی فقط باید دارای متد باشه.
اما شاید یکی بگه خب اگه قرار باشه یه آبجکت بین همه ترد ها شیر بشه که performance میاد پایین! اما در واقع چنین چیزی اتفاق نمیفته و کاهش سرعتی نداریم (به شرطی که موارد بالا رعایت بشه)
مورد دیگه اینکه، اگه قراره این کلاس فقط توش متد باشه و فقط ام یه دونه آبجکت قراره ازش ساخته بشه، چرا اصلا متدها رو static تعریف نکنیم و اصلا آبجکتی ازش نسازیم؟
جوابش اینه که بله میشه همچین کاری کرد! اتفاقا اینطوری performance هم میره بالاتر و متدها سریع تر کال میشن.
اما در اینصورت از خیلی چیزای دیگه محروم میشیم. مثلا ارث بری، پیاده سازی interface و abstract و ... که این موارد جز موارد ضروری برای طراحی معماری برنامس و انعطاف پذیری به کدمون میده یعنی میشه بعدا منطق رو عوض کرد و کلی مسائل دیگه...
مثالی که براش میشه زد مثلا کلاس java.lang.Math که اگر دقت کنید همه متدهاش static هست و هیچ property ای هم در سطح کلاس براش تعریف نشده (به جز چنتا فیلد static final مثل PI که مشکل ساز نیستن)
الان میشد این کلاسو singleton اش کنن و مثلا همچین چیزی داشتیم :
Math.getInstance().max(1,2);
اما واقعا هیچ دلیلی برای singleton تعریف کردن این کلاس وجود نداره، همونطور که اول هم گفتم، بعضی مواقع استفاده کردن از singleton یه چیز اضافس و anti-pattern ه.