CodeGym /وبلاگ جاوا /Random-FA /کلاس جاوا سینگلتون
John Squirrels
مرحله
San Francisco

کلاس جاوا سینگلتون

در گروه منتشر شد
سلام! امروز ما به جزئیات الگوهای طراحی مختلف می پردازیم که با الگوی جاوا سینگلتون شروع می شود. بیایید مرور کنیم: به طور کلی در مورد الگوهای طراحی چه می دانیم؟ الگوهای طراحی بهترین شیوه هایی هستند که می توانیم برای حل تعدادی از مشکلات شناخته شده به کار ببریم. الگوهای طراحی معمولاً به هیچ زبان برنامه نویسی گره نمی خورند. آنها را به عنوان مجموعه ای از توصیه ها در نظر بگیرید که به شما در جلوگیری از اشتباهات و جلوگیری از اختراع مجدد چرخ کمک می کند.الگوهای طراحی: Singleton - 1

سینگلتون در جاوا چیست؟

Singleton یکی از ساده ترین الگوهای طراحی در سطح کلاس است. گاهی اوقات افراد می گویند "این کلاس singleton است"، به این معنی که کلاس الگوی طراحی singleton را پیاده سازی می کند. گاهی اوقات لازم است کلاسی بنویسیم که در آن نمونه سازی را به یک شی محدود کنیم. برای مثال، کلاسی که مسئول ورود به سیستم یا اتصال به یک شی است. پایگاه داده الگوی طراحی سینگلتون توضیح می دهد که چگونه می توانیم به این هدف برسیم. Singleton یک الگوی طراحی است که دو کار را انجام می دهد:
  1. این تضمین می کند که تنها یک نمونه از کلاس وجود خواهد داشت.

  2. این یک نقطه واحد از دسترسی جهانی به آن نمونه را فراهم می کند.

از این رو، دو ویژگی وجود دارد که مشخصه تقریباً هر اجرای الگوی تک تنه است:
  1. یک سازنده خصوصی این توانایی ایجاد اشیاء کلاس خارج از خود کلاس را محدود می کند.

  2. یک متد استاتیک عمومی که نمونه کلاس را برمی گرداند. این روش getInstance نام دارد . این نقطه دسترسی جهانی به نمونه کلاس است.

گزینه های پیاده سازی

الگوی طراحی تک تن به روش های مختلفی اعمال می شود. هر گزینه در نوع خود خوب و بد است. مثل همیشه، هیچ گزینه کاملی در اینجا وجود ندارد، اما ما باید برای یکی تلاش کنیم. اول از همه، بیایید تصمیم بگیریم که چه چیزی خوب و بد را تشکیل می دهد، و چه معیارهایی بر نحوه ارزیابی پیاده سازی های مختلف الگوی طراحی تاثیر می گذارد. بیایید با خوبی ها شروع کنیم. در اینجا عواملی وجود دارد که یک پیاده سازی را شاداب تر و جذاب تر می کند:
  • مقداردهی اولیه تنبل: نمونه تا زمانی که مورد نیاز نباشد ایجاد نمی شود.

  • کد ساده و شفاف: این معیار، البته ذهنی است، اما مهم است.

  • ایمنی نخ: عملکرد صحیح در یک محیط چند رشته ای.

  • عملکرد بالا در یک محیط چند رشته ای: در هنگام به اشتراک گذاری یک منبع، نخ مسدود می شود یا اصلاً مسدود نمی شود.

حالا معایب ما عواملی را فهرست می کنیم که یک پیاده سازی را در نور بد قرار می دهند:
  • بدون مقداردهی اولیه تنبل: وقتی کلاس هنگام شروع برنامه بارگیری می شود، صرف نظر از اینکه به آن نیاز است یا نه (به طور متناقض، در دنیای IT بهتر است تنبل باشید)

  • کد پیچیده و سخت خوان. این معیار نیز ذهنی است. اگر چشمان شما شروع به خونریزی کرد، فرض می کنیم که اجرای آن بهترین نیست.

  • عدم ایمنی نخ به عبارت دیگر «خطر نخ». عملکرد نادرست در یک محیط چند رشته ای.

  • عملکرد ضعیف در یک محیط چند رشته ای: رشته ها همیشه یا اغلب هنگام به اشتراک گذاری یک منبع یکدیگر را مسدود می کنند.

کد

اکنون ما آماده هستیم تا گزینه های مختلف پیاده سازی را در نظر بگیریم و جوانب مثبت و منفی را نشان دهیم:

ساده

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

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}
ساده ترین پیاده سازی طرفداران:
  • کد ساده و شفاف

  • ایمنی نخ

  • عملکرد بالا در یک محیط چند رشته ای

معایب:
  • بدون مقداردهی اولیه تنبل.
در تلاش برای رفع نقص قبلی، پیاده سازی شماره دو را دریافت می کنیم:

مقداردهی اولیه تنبل

public class Singleton {
  private static final Singleton INSTANCE;

  private Singleton() {}

  public static Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
طرفداران:
  • مقداردهی اولیه تنبل

معایب:
  • نخ ایمن نیست

این پیاده سازی جالب است. می‌توانیم با تنبلی مقداردهی اولیه کنیم، اما ایمنی رشته را از دست داده‌ایم. جای نگرانی نیست - ما همه چیز را در اجرای شماره سه همگام می کنیم.

دسترسی همگام شده

public class Singleton {
  private static final Singleton INSTANCE;

  private Singleton() {
  }

  public static synchronized Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
طرفداران:
  • مقداردهی اولیه تنبل

  • ایمنی نخ

معایب:
  • عملکرد ضعیف چند رشته ای

عالی! در اجرای شماره سه، ایمنی نخ را بازیابی می کنیم! البته کند است... حالا متد getInstance همگام شده است، بنابراین می توان آن را در هر بار تنها با یک رشته اجرا کرد. به جای همگام سازی کل روش، در واقع فقط باید بخشی از آن را که نمونه جدید را مقداردهی اولیه می کند، همگام سازی کنیم. اما ما نمی توانیم به سادگی از یک بلوک همگام سازی شده برای بسته بندی بخشی که مسئول ایجاد نمونه جدید است استفاده کنیم. انجام این کار ایمنی نخ را تضمین نمی کند. همه چیز کمی پیچیده تر است. همگام سازی مناسب را می توان در زیر مشاهده کرد:

قفل دوبار چک شده

public class Singleton {
    private static final 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 باید نهایی یا فرار باشد . آخرین پیاده سازی که امروز در مورد آن بحث خواهیم کرد، کلاس دارنده 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 ایجاد می کنند .

این پیاده سازی تقریباً کامل است. تنبل است و نخ بی خطر و سریع است. اما همانطور که در لیست معایب توضیح داده شد، تفاوت ظریفی دارد. مقایسه پیاده سازی های مختلف الگوی تک تن:
پیاده سازی مقداردهی اولیه تنبل ایمنی نخ عملکرد چند رشته ای چه موقع باید استفاده کرد؟
ساده - + سریع هرگز. یا احتمالاً زمانی که تنظیم اولیه تنبل مهم نیست. اما هرگز بهتر نخواهد بود.
مقداردهی اولیه تنبل + - قابل اجرا نیست همیشه زمانی که نیازی به چند رشته ای نیست
دسترسی همگام شده + + آهسته. تدریجی هرگز. یا احتمالاً زمانی که عملکرد چند رشته ای اهمیتی ندارد. اما هرگز بهتر نخواهد بود.
قفل دوبار چک شده + + سریع در موارد نادری که هنگام ایجاد تک‌تنه نیاز به کنترل استثنا دارید (زمانی که تک‌تنه دارنده کلاس قابل اجرا نیست)
دارنده کلاس + + سریع هر زمان که نیاز به Multithreading باشد و تضمین وجود داشته باشد که شی singleton بدون مشکل ایجاد می شود.

مزایا و معایب الگوی تک تن

به طور کلی، یک تک تن دقیقاً همان کاری را انجام می دهد که از آن انتظار می رود:
  1. این تضمین می کند که تنها یک نمونه از کلاس وجود خواهد داشت.

  2. این یک نقطه واحد از دسترسی جهانی به آن نمونه را فراهم می کند.

با این حال، این الگو دارای کاستی هایی است:
  1. یک تک تن اصل مسئولیت واحد را نقض می کند: کلاس تک تن علاوه بر وظایف مستقیم خود، تعداد موارد را نیز کنترل می کند.

  2. وابستگی یک طبقه معمولی به تک قلو در قرارداد عمومی طبقه قابل مشاهده نیست.

  3. متغیرهای جهانی بد هستند. در نهایت، یک تک تن به یک متغیر جهانی سنگین تبدیل می شود.

  4. وجود سینگلتون آزمایش پذیری برنامه به طور کلی و کلاس هایی را که از سینگلتون استفاده می کنند به طور خاص کاهش می دهد.

و بس! :) ما کلاس جاوا Singleton را با شما بررسی کردیم. اکنون، تا آخر عمر، هنگام مکالمه با دوستان برنامه نویس خود، می توانید نه تنها به خوب بودن الگوی خود اشاره کنید، بلکه می توانید چند کلمه در مورد اینکه چه چیزی آن را بد می کند نیز ذکر کنید. موفق باشید در تسلط بر این دانش جدید.

خواندن تکمیلی:

نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION