JavaRush /Java блогу /Random-KY /Дизайн үлгүлөрү: Singleton

Дизайн үлгүлөрү: Singleton

Группада жарыяланган
Салам! Бүгүн биз ар кандай дизайн үлгүлөрүн жакшыраак карап чыгабыз жана биз Singleton үлгүсүнөн баштайбыз, ал дагы "singleton" деп аталат. Дизайн үлгүлөрү: Singleton - 1Келгиле, эстеп көрөлү: биз жалпы дизайн үлгүлөрү жөнүндө эмне билебиз? Дизайн үлгүлөрү - белгилүү бир катар көйгөйлөрдү чечүү үчүн колдонула турган мыкты тажрыйбалар. Дизайн үлгүлөрү, адатта, эч кандай программалоо тor менен байланышкан эмес. Аларды сунуштардын жыйындысы катары кабыл алыңыз, андан кийин сиз каталардан качсаңыз жана дөңгөлөгүңүздү кайра ойлоп таба албайсыз.

Синглон деген эмне?

Синглтон класска колдонула турган эң жөнөкөй дизайн үлгүлөрүнүн бири. Адамдар кээде "бул класс синглтон" деп айтышат, бул класс синглтон дизайн үлгүсүн ишке ашырат дегенди билдирет. Кээде бир гана an object түзүлө турган класс жазуу керек болот. Мисалы, журналга же маалымат базасына туташуу үчүн жооптуу класс. Singleton дизайн үлгүсү мындай тапшырманы кантип аткара аларыбызды сүрөттөйт. Синглон эки нерсени жасаган дизайн үлгүсү:
  1. Класс класстын бир гана нускасына ээ болоруна кепилдик берет.

  2. Бул класстын инстанциясына глобалдык кирүү чекити менен камсыз кылат.

Демек, синглтон үлгүсүн дээрлик ар бир ишке ашырууга мүнөздүү эки өзгөчөлүк бар:
  1. Жеке конструктор. Класстын өзүнөн тышкары класс an objectтерин түзүү мүмкүнчүлүгүн чектейт.

  2. Класстын үлгүсүн кайтаруучу коомдук статикалык ыкма. Бул ыкма деп аталат getInstance. Бул класстын инстанциясына глобалдык кирүү чекити.

Ишке ашыруу варианттары

Singleton дизайн үлгүсү ар кандай жолдор менен колдонулат. Ар бир вариант өз жолу менен жакшы жана жаман. Бул жерде, мурдагыдай эле: идеал жок, бирок ага умтулуу керек. Бирок, биринчи кезекте, эмне жакшы жана эмне жаман экенин аныктап көрөлү, жана кандай метрика дизайн үлгүсүн ишке ашырууга баа таасир этет. Позитивден баштайлы. Бул жерде ишке ашыруу ширелүүлүгүн жана жагымдуулугун берген критерийлер болуп саналат:
  • Жалкоо инициализация: колдонмо так керектүү учурда иштеп жатканда класс жүктөлгөндө.

  • Коддун жөнөкөйлүгү жана ачыктыгы: метрика, албетте, субъективдүү, бирок маанилүү.

  • Жиптин коопсуздугу: көп жиптүү чөйрөдө туура иштейт.

  • Көп жиптүү чөйрөдө жогорку өндүрүмдүүлүк: жиптер ресурсту бөлүшүүдө бири-бирин азыраак бөгөттөйт же такыр бөгөттөбөйт.

Эми минустар. Ишке ашырууну начар көрсөткөн критерийлерди санап көрөлү:
  • Жалкоо эмес инициализация: класс жүктөлгөндө, тиркеме керекпи же жокпу (парадокс, IT дүйнөсүндө жалкоолук жакшыраак)

  • Коддун татаалдыгы жана начар окулушу. Метрика да субъективдүү. Көздөн кан чыкса, ишке ашыруу ошончолук болот деп ойлойбуз.

  • Жиптин коопсуздугунун жоктугу. Башка сөз менен айтканда, "жип коркунучу". Көп жиптүү чөйрөдө туура эмес иштөө.

  • Көп жиптүү чөйрөдө начар иштеши: жиптер ар дайым же көп учурда ресурсту бөлүшүүдө бири-бирине бөгөт коёт.

Code

Эми биз жакшы жана жаман жактарын тизмелеп, ишке ашыруунун ар кандай варианттарын карап чыгууга даярбыз:

Жөнөкөй чечим

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

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}
Эң жөнөкөй ишке ашыруу. Артыкчылыктары:
  • Коддун жөнөкөйлүгү жана ачыктыгы

  • Жиптин коопсуздугу

  • Көп жиптүү чөйрөдө жогорку өндүрүмдүүлүк

Минустары:
  • Жалкоо инициализация эмес.
Акыркы кемчorкти оңдоого аракет кылып, биз ишке ашыруунун экинчи номерин алабыз:

Lazy Initialization

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синхрондолуп, аны бирден эле киргизе аласыз. Чынында, биз бүткүл методду синхрондоштуруунун кереги жок, бирок анын жаңы класс an objectисин инициализациялаган бөлүгү гана. synchronizedБирок жаңы an objectти түзүү үчүн жооптуу бөлүктү блокко жөн эле ороп коё албайбыз : бул жиптин коопсуздугун камсыз кылbyte. Бул бир аз татаалыраак. Туура синхрондоштуруу ыкмасы төмөндө келтирилген:

Double Checked Locking

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тен төмөн Java versionларында колдоого алынbyte (турма ачкыч сөз 1.5 versionсында бекитилген)

Бул ишке ашыруу опциясы туура иштеши үчүн эки шарттын бири талап кылынат. Өзгөрмө же , же INSTANCEболушу керек . Биз бүгүн талкуулай турган акыркы ишке ашыруу болуп саналат . finalvolatileClass Holder Singleton

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Туура иштеши үчүн класс an objectинин катасыз инициализацияланганына кепилдик берүү керек . Болбосо, биринчи ыкманын чалуусу getInstanceката менен аяктайт ExceptionInInitializerErrorжана кийинкилердин баары ишке ашпай калат NoClassDefFoundError.

Ишке ашыруу дээрлик кемчorксиз. Жана жалкоо, жана жип-коопсуз жана тез. Бирок минус сүрөттөлгөн бир нюанс бар. Singleton үлгүсүнүн ар кандай аткарылышын салыштыруу tableсы:
Ишке ашыруу Жалкоо инициализация Жиптин коопсуздугу Көп агым ылдамдыгы Качан колдонуу керек?
Жөнөкөй чечим - + Тез Эч качан. Же жалкоо инициализация маанилүү болбогондо. Бирок эч качан жакшы эмес.
Lazy Initialization + - Жараксыз Ар дайым көп агымдын кереги жок болгондо
Синхрондолгон аксессуар + + Акырын Эч качан. Же multithreading менен иштөө ылдамдыгы маанилүү эмес болгондо. Бирок эч качан жакшы эмес
Double Checked Locking + + Тез Сейрек учурларда, синглтонду түзүүдө өзгөчө кырдаалдарды чечүү керек болгондо. (Class Holder Singleton колдонулбаганда)
Class Holder Singleton + + Тез Ар дайым multithreading керек болгондо жана синглтон классынын an objectи көйгөйсүз түзүлөт деген кепилдик бар.

Singleton үлгүсүнүн жакшы жана жаман жактары

Жалпысынан алганда, синглтон андан күтүлгөн нерсени так аткарат:
  1. Класс класстын бир гана нускасына ээ болоруна кепилдик берет.

  2. Бул класстын инстанциясына глобалдык кирүү чекити менен камсыз кылат.

Бирок, бул моделдин кемчorктери бар:
  1. Singleton SRPти (Single Responsibility Principle) бузат - Singleton классы өзүнүн түздөн-түз милдеттеринен тышкары, анын нускаларынын санын да көзөмөлдөйт.

  2. Кадимки класстын же методдун синглтонго көз карандылыгы класстын ачык келишиминде көрүнбөйт.

  3. Глобалдык өзгөрмөлөр начар. Синглтон акыры бир чоң глобалдык өзгөрмөгө айланат.

  4. Синглтондун болушу жалпысынан колдонмонун жана өзгөчө синглтонду колдонгон класстардын сыналышын азайтат.

Макул азыр баары бүттү. Биз синглтон дизайн үлгүсүн карадык. Эми, программист досторуңуз менен өмүр бою баарлашууда сиз анын жакшы жактарын гана эмес, анын эмнеси жаман экенин да бир нече сөз айта аласыз. Жаңы бorмди өздөштүрүүгө ийгorк.

Кошумча окуу:

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION