logo

Singleton Method Design Pattern

Singleton Pattern er sannsynligvis det mest brukte designmønsteret. Det er et enkelt mønster, lett å forstå og bruke. Noen ganger brukes det i overkant og i scenarier der det ikke er nødvendig. I slike tilfeller oppveier ulempene ved å bruke det fordelene det gir. Av denne grunn blir singleton-mønsteret noen ganger betraktet som et antimønster eller mønster singleton .

Singleton-Metode-Design-mønster



Viktige emner for Singleton Method Design Pattern

1. Hva er Singleton Method Design Pattern?

Singleton-metoden eller Singleton Design-mønsteret er et av de enkleste designmønstrene. Det sikrer at en klasse bare har én forekomst, og gir et globalt tilgangspunkt til den.

java matematikk tilfeldig

2. Når skal man bruke Singleton Method Design Pattern?

Bruk Singleton-metoden Design Pattern når:



  • Det må være nøyaktig én forekomst av en klasse, og den må være tilgjengelig for klienter fra et velkjent tilgangspunkt.
  • Når den eneste forekomsten skal kunne utvides med underklassifisering og klienter skal kunne bruke en utvidet forekomst uten å endre
  • Singleton-klasser brukes til logging, driverobjekter, caching og trådpool, databasetilkoblinger.

3. Initialiseringstyper av Singleton

Singleton-klassen kan instansieres ved to metoder:

  • Tidlig initialisering: I denne metoden initialiseres klassen enten den skal brukes eller ikke. Den største fordelen med denne metoden er dens enkelhet. Du starter klassen når klassen lastes inn. Ulempen er at klassen alltid initialiseres enten den brukes eller ikke.
  • Lazy initialisering: I denne metoden initialiseres klasse bare når det er nødvendig. Det kan spare deg fra å instansiere klassen når du ikke trenger den. Vanligvis brukes lat initialisering når vi lager en singleton-klasse.

4. Nøkkelkomponent i Singleton Method Design Pattern:

Key-Component-of-Singleton-Method-Design-Patern-(1)

4.1. Statisk medlem:

Singleton-mønsteret eller mønsteret Singleton bruker et statisk medlem i klassen. Dette statiske medlemmet sikrer at minne kun tildeles én gang, og bevarer enkeltforekomsten av Singleton-klassen.



Java
// Static member to hold the single instance private static Singleton instance;>

4.2. Privat konstruktør:

Singleton-mønsteret eller mønster-singelen inneholder en privat konstruktør, som fungerer som en barrikade mot eksterne forsøk på å lage forekomster av Singleton-klassen. Dette sikrer at klassen har kontroll over instansieringsprosessen.

Java
// Private constructor to // prevent external instantiation class Singleton {  // Making the constructor as Private  private Singleton()  {  // Initialization code here  } }>

4.3. Statisk fabrikkmetode:

Et avgjørende aspekt ved Singleton-mønsteret er tilstedeværelsen av en statisk fabrikkmetode. Denne metoden fungerer som en gateway, og gir et globalt tilgangspunkt til Singleton-objektet. Når noen ber om en forekomst, oppretter denne metoden enten en ny forekomst (hvis ingen finnes) eller returnerer den eksisterende forekomsten til den som ringer.

Java
// Static factory method for global access public static Singleton getInstance() {  // Check if an instance exists  if (instance == null) {  // If no instance exists, create one  instance = new Singleton();  }  // Return the existing instance  return instance; }>

5. Implementering av Singleton Method Design Pattern

Implementeringen av et Singleton Design Pattern eller Pattern Singleton er beskrevet i følgende klassediagram:

Skjermbilde-2023-12-07-174635

Implementering av Singleton Method Design Pattern

Implementeringen av singleton Design-mønsteret er veldig enkelt og består av en enkelt klasse. For å sikre at singleton-forekomsten er unik, bør alle singleton-konstruktørene gjøres private. Global tilgang gjøres gjennom en statisk metode som globalt kan få tilgang til en enkelt forekomst som vist i koden.

Java
/*package whatever //do not write package name here */ import java.io.*; class Singleton {  // static class  private static Singleton instance;  private Singleton()  {  System.out.println('Singleton is Instantiated.');  }  public static Singleton getInstance()  {  if (instance == null)  instance = new Singleton();  return instance;  }  public static void doSomething()  {  System.out.println('Somethong is Done.');  } } class GFG {  public static void main(String[] args)  {  Singleton.getInstance().doSomething();  } }>

Produksjon
Singleton is Instantiated. Somethong is Done.>

GetInstance-metoden, vi sjekker om forekomsten er null. Hvis forekomsten ikke er null, betyr det at objektet ble opprettet før; ellers oppretter vi den med den nye operatoren.

6. Ulike måter å implementere Singleton Method Design Pattern

Noen ganger trenger vi bare å ha én forekomst av klassen vår, for eksempel en enkelt DB-tilkobling som deles av flere objekter, da det kan være kostbart å opprette en separat DB-tilkobling for hvert objekt. På samme måte kan det være en enkelt konfigurasjonsbehandler eller feilbehandler i en applikasjon som håndterer alle problemer i stedet for å opprette flere administratorer.

Klassisk-implementering

La oss se ulike designalternativer for å implementere en slik klasse. Hvis du har et godt grep om statiske klassevariabler og tilgangsmodifikatorer, burde dette ikke være en vanskelig oppgave.

Metode 1 – Klassisk implementering || Gjør getInstance() statisk for å implementere Singleton Method Design Pattern

Java
// Classical Java implementation of singleton // design pattern class Singleton {  private static Singleton obj;  // private constructor to force use of  // getInstance() to create Singleton object  private Singleton() {}  public static Singleton getInstance()  {  if (obj == null)  obj = new Singleton();  return obj;  } }>

Her har vi erklært getInstance() statisk slik at vi kan kalle det uten å instansiere klassen. Den første gangen getInstance() kalles det oppretter et nytt singleton-objekt, og etter det returnerer det bare det samme objektet.

Merk: Singleton obj blir ikke opprettet før vi trenger den og kaller den getInstance() metode. Dette kalles lat instansiering. Hovedproblemet med metoden ovenfor er at den ikke er trådsikker. Tenk på følgende utførelsessekvens.

Denne utførelsessekvensen lager to objekter for singletonen. Derfor er ikke denne klassiske implementeringen trådsikker.

Metode 2 || Gjør getInstance() synkronisert for å implementere Singleton Method Design Pattern

Java
// Thread Synchronized Java implementation of // singleton design pattern class Singleton {  private static Singleton obj;  private Singleton() {}  // Only one thread can execute this at a time  public static synchronized Singleton getInstance()  {  if (obj == null)  obj = new Singleton();  return obj;  } }>

Her sikrer bruk av synkronisert at kun én tråd om gangen kan kjøres getInstance() . Den største ulempen med denne metoden er at bruk av synkronisert hver gang mens du oppretter singleton-objektet er dyrt og kan redusere ytelsen til programmet. Men hvis ytelsen til getInstance() er ikke kritisk for din applikasjon denne metoden gir en ren og enkel løsning.

Metode 3 – Ivrig instansiering || Statisk initialiseringsbasert implementering av singleton-designmønster

Java
// Static initializer based Java implementation of // singleton design pattern class Singleton {  private static Singleton obj = new Singleton();  private Singleton() {}  public static Singleton getInstance() { return obj; } }>

Her har vi laget en forekomst av en singleton i en statisk initialisator. JVM kjører en statisk initialisering når klassen er lastet, og derfor er denne garantert trådsikker. Bruk denne metoden bare når singleton-klassen din er lett og brukes gjennom hele programmet.

java liste metoder

Metode 4 – Mest effektiv || Bruk Double Checked Locking for å implementere singleton designmønster

Hvis du legger merke til det når et objekt er opprettet, er synkronisering ikke lenger nyttig fordi nå vil ikke obj være null og en hvilken som helst sekvens av operasjoner vil føre til konsistente resultater. Så vi får bare låsen på getInstance() én gang når obj er null. På denne måten synkroniserer vi bare den første veien gjennom, akkurat det vi ønsker.

Java
// Double Checked Locking based Java implementation of // singleton design pattern class Singleton {  private static volatile Singleton obj = null;  private Singleton() {}  public static Singleton getInstance()  {  if (obj == null) {  // To make thread safe  synchronized (Singleton.class)  {  // check again as multiple threads  // can reach above step  if (obj == null)  obj = new Singleton();  }  }  return obj;  } }>

Vi har erklært obj flyktige som sikrer at flere tråder tilbyr obj-variabelen riktig når den initialiseres til Singleton-forekomsten. Denne metoden reduserer drastisk kostnadene ved å ringe den synkroniserte metoden hver gang.

7. Bruk Case of Pattern Singleton Method

  • Databasetilkoblinger: I applikasjoner hvor det er en kostbar operasjon å opprette og administrere databaseforbindelser, kan en Singleton brukes til å opprettholde en enkelt databasetilkobling gjennom hele applikasjonen.
  • Konfigurasjonsstyring: Når du har globale konfigurasjonsinnstillinger som må åpnes av ulike komponenter i applikasjonen, kan en Singleton-konfigurasjonsbehandling gi ett enkelt tilgangspunkt til disse innstillingene.
  • GUI-komponenter: For komponenter eller kontroller for grafisk brukergrensesnitt (GUI) kan en Singleton hjelpe til med å administrere tilstanden og handlingene til brukergrensesnittet, og gi et enkelt kontrollpunkt.
  • Enhetsadministratorer: I innebygde systemer eller applikasjoner som samhandler med maskinvareenheter, kan en Singleton brukes til å administrere og kontrollere tilgang til maskinvareenheter for å unngå konflikter.
  • Utskriftstjeneste: I systemer som involverer utskrift av dokumenter eller rapporter, kan en Singleton-utskriftstjeneste koordinere og administrere utskriftsjobber, og sikre effektiv bruk av utskriftsressurser.

8. Fordeler med Singleton Method Design Pattern:

  • Løser navnekollisjoner: I scenarier der et enkelt kontrollpunkt er nødvendig for å unngå navnekonflikter eller kollisjoner, sikrer Singleton-mønsteret at det bare er én forekomst med et unikt navn.
  • Ivrig eller lat initialisering: Singleton-mønsteret støtter både ivrig initialisering (opprette forekomsten når klassen er lastet) og lat initialisering (opprette forekomsten når den først blir forespurt), og gir fleksibilitet basert på brukstilfellet.
  • Trådsikkerhet: Riktig implementerte Singleton-mønstre kan gi trådsikkerhet, og sikre at forekomsten opprettes atomisk og at flere tråder ikke utilsiktet lager dupliserte forekomster.
  • Redusert minneavtrykk: I applikasjoner der ressursforbruk er kritisk, kan Singleton-mønsteret bidra til et redusert minneavtrykk ved å sikre at det bare er én forekomst av klassen.

9. Ulemper med Singleton Design Pattern

  • Testvansker: Fordi Singletons introduserer global stat, kan enhetstesting bli utfordrende. Å teste en komponent isolert kan være mer komplisert hvis den er avhengig av en Singleton, ettersom tilstanden til Singleton kan påvirke resultatet av tester.
  • Samtidighetsproblemer: I et flertrådsmiljø kan det være problemer knyttet til opprettelse og initialisering av Singleton-forekomsten. Hvis flere tråder prøver å lage Singleton samtidig, kan det resultere i løpsforhold.
  • Begrenset utvidbarhet: Singleton-mønsteret kan gjøre koden mindre utvidbar. Hvis du senere bestemmer deg for at du trenger flere forekomster av klassen eller ønsker å endre instansieringslogikken, kan det kreve betydelig refaktorisering.
  • Global avhengighet: Singleton-mønsteret skaper en global avhengighet, noe som gjør det vanskeligere å erstatte Singleton med en alternativ implementering eller å bruke avhengighetsinjeksjon for å gi forekomster.
  • Vanskelig å underklasse: Å underklasse en Singleton kan være utfordrende. Fordi konstruktøren vanligvis er privat, krever utvidelse av en Singleton ekstra omsorg og følger kanskje ikke standard arvemønstre.
  • Livssyklusadministrasjon: Singleton-mønsteret håndterer kanskje ikke scenarier der forekomsten eksplisitt må ødelegges eller tilbakestilles. Å administrere livssyklusen til Singleton kan bli en bekymring.
  • Misbruk av globalt tilgangspunkt: Mens et globalt tilgangspunkt er en fordel, kan det også misbrukes. Utviklere kan bli fristet til å bruke Singleton til alt, noe som fører til overforbruk av global stat og en mindre modulær design.

10. Konklusjon

Det er viktig for noen klasser å ha nøyaktig én instans. Selv om det kan være mange skrivere i et system, bør det bare være én skriverkø. Det skal bare være ett filsystem og en vindusbehandling. Et digitalt filter vil ha én A/D-omformer. Et regnskapssystem vil være dedikert til å betjene ett selskap. Hvordan sikrer vi at en klasse bare har én forekomst og at forekomsten er lett tilgjengelig? En global variabel gjør et objekt tilgjengelig, men det hindrer deg ikke i å instansiere flere objekter.

En bedre løsning er å gjøre klassen selv ansvarlig for å holde styr på sin eneste instans. Klassen kan sikre at ingen annen forekomst kan opprettes (ved å avskjære forespørsler om å lage nye objekter), og den kan gi en måte å få tilgang til forekomsten på. Dette er Singleton-mønsteret.