CodeGym /Java-blogg /Tilfeldig /Mønstre og Singleton i Java
John Squirrels
Nivå
San Francisco

Mønstre og Singleton i Java

Publisert i gruppen
Denne artikkelen er rettet mot alle som for første gang møter konseptet med designmønstre, har hørt begrepet singleton , eller på en eller annen måte implementert singleton-mønsteret, men ikke forsto hva som skjedde. Velkommen! CodeGym-studenter møter designmønstre for første gang på nivå 15, når kapteinen uventet ber dem om å "forsterke" deres forståelse ved å implementere Java Singleton-mønsteret med lat implementering. Studenter som hører om singleton- mønsteret for første gang har umiddelbart mange spørsmål: hva i all verden er et designmønster? Hvorfor trenger vi det? Hva er en singleton ? Og til slutt, hva er lat implementering? La oss svare på disse spørsmålene i rekkefølge.

Hva i all verden er et designmønster?

Jeg tror litt historie er for å svare på dette spørsmålet med best mulig forståelse. Det er fire kjente programmeringsforfattere (Erich Gamma, John Vlissides, Ralph Johnson og Richard Helm) som kom opp med en interessant idé. De la merke til at programvareutvikling ofte krevde at de skulle løse omtrent de samme problemene og skrive kode strukturert på samme måte. Så de bestemte seg for å beskrive typiske mønstre som ofte må brukes i objektorientert programmering. Boken deres ble utgitt i 1994 under tittelen Design Patterns: Elements of Reusable Object-Oriented Software. Bokens navn viste seg å være for langt og folk begynte rett og slett å kalle den boken til The Gang of Four. Den første utgaven inkluderte 23 mønstre. Etterpå ble dusinvis av andre mønstre oppdaget.
Et designmønster er en standardisert løsning på et vanlig problem.
Og singleton -mønsteret er bare ett av dem.

Hvorfor trenger vi designmønstre?

Du kan programmere uten å kjenne til mønstre: på nivå 15 har du allerede skrevet hundrevis av miniprogrammer på CodeGym uten å vite at de eksisterer. Dette antyder at designmønstre er et slags verktøy hvis bruk skiller mesteren fra amatøren: Designmønstre beskriver hvordan man løser et typisk problem på riktig måte. Dette betyr at du sparer tid ved å kjenne til mønstre. På den måten ligner de på algoritmer. Du kan for eksempel lage din egen sorteringsalgoritme med blackjack og tallog bruke mye tid på det, eller du kan implementere en som har vært forstått og beskrevet i lang tid. Det samme gjelder med designmønstre. I tillegg, med designmønstre, blir kode mer standard, og når du bruker riktig mønster, er det mindre sannsynlig at du gjør feil, siden mønsterets vanlige fallgruver ble identifisert og eliminert for lenge siden. På toppen av alt annet hjelper kunnskap om mønstre programmerere til å forstå hverandre bedre. Du kan ganske enkelt si navnet på et mønster i stedet for å prøve å gi en lang forklaring til andre programmerere. Oppsummert hjelper designmønstre deg:
  • ikke finne opp hjulet på nytt, men i stedet bruke standardløsninger;
  • standardisere kode;
  • standardisere terminologi;
For å avslutte denne delen, merker vi at hele kroppen av designmønstre kan deles inn i tre store grupper: Mønstre og singleton - for alle som møter dem for første gang - 2

Til slutt, singleton-mønsteret

Singleton er et kreasjonsmønster . Dette mønsteret sikrer at det bare er én forekomst av en klasse og gir et globalt tilgangspunkt for dette objektet. Fra beskrivelsen bør det være klart at dette mønsteret skal brukes i to tilfeller:
  1. når programmet krever at ikke mer enn ett objekt av en bestemt klasse skal opprettes. For eksempel kan et dataspill ha en Hero-klasse og bare ett Hero-objekt som beskriver den eneste helten i spillet.

  2. når du trenger å gi et punkt for global tilgang til et objekt. Du må med andre ord gjøre objektet tilgjengelig fra hvor som helst i programmet. Dessverre, det er ikke nok å bare lage en global variabel, siden den ikke er skrivebeskyttet: hvem som helst kan endre variabelens verdi, slik at objektets globale tilgangspunkt kan gå tapt. Disse egenskapene til en Singleton er nødvendige, for eksempel når du har et objekt som fungerer med en database, og du trenger tilgang til databasen fra ulike deler av programmet. En Singleton vil sikre at ingen skriver kode som erstatter den tidligere opprettede forekomsten.
Så en Singleton tilfredsstilte disse to behovene: det må bare være ett av en bestemt type objekt i programmet, og det må være global tilgang til det. I eksemplet på nivå 15 ber kapteinen deg implementere dette mønsteret for følgende oppgave:
  1. Finn et eksempel på Singleton med lat initialisering.

  2. Lag tre singleton-klasser - Sol, Måne, Jord - i separate filer ved å bruke samme prinsipp.

  3. ImplementerePlanetgrensesnitt i sol- , måne- og jordklasser .

  4. I statisk blokk av Solution -klassen kaller dureadKeyFromConsoleAndInitPlanetmetode.

  5. ImplementerreadKeyFromConsoleAndInitPlanetmetode funksjonalitet:

    • 5.1. Les én strengparameter fra konsollen

    • 5.2. Hvis parameteren er lik en avPlanetgrensesnittets konstanter, lag passende Planet- objektet.

Etter å ha lest oppgavebetingelsene nøye, kan vi tydelig se hvorfor en Singleton er nødvendig her. Vi blir faktisk bedt om å lage en forekomst av hver av følgende klasser: Sol , Måne , Jord . Det er fornuftig å anta at vi ikke skal skape mer enn én sol/måne/jord. Ellers kommer vi i en absurd situasjon, med mindre du selvfølgelig skriver din versjon av Star Wars. Implementering av Singleton- mønsteret i Java i tre trinn I Java kan ikke Singleton-atferd implementeres ved bruk av en vanlig konstruktør, fordi en konstruktør alltid returnerer et nytt objekt. Derfor er alle implementeringer av Singletonkoker ned til å skjule konstruktøren, lage en offentlig statisk metode som kontrollerer singleton-objektets levetid, og "ødelegge" alle nylig dukkede objekter. Hvis en Singleton er tilgjengelig, bør den enten opprette et nytt objekt (hvis et ikke allerede finnes i programmet), eller returnere et eksisterende. For å oppnå dette:
  1. Du må gi klassen et privat statisk felt som lagrer et enkelt objekt:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
    
  2. Gjør (standard) konstruktøren privat. Dette betyr at den ikke kan nås utenfor klassen og vil ikke kunne returnere nye objekter:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    } 
    
  3. Erklær en statisk opprettelsesmetode som vil bli brukt for å få singletonen:

    
    public class LazyInitializedSingleton {
        private static LazyInitializedSingleton instance;
            private LazyInitializedSingleton() {}
            public static LazyInitializedSingleton getInstance() { // #3
            if (instance == null) { // If the object has not yet been created
                instance = new LazyInitializedSingleton(); // Create a new object
            }
            return instance; // Return the previously created object
        }
    }
    
Eksemplet ovenfor er noe klønete, siden vi ganske enkelt skjuler konstruktøren og gir vår egen metode i stedet for en standard konstruktør. Siden denne artikkelen tar sikte på å sikre at CodeGym-studenter kommer i kontakt med dette mønsteret (og designmønstre generelt), vil ikke nyansene til mer komplekse singleton-implementeringer bli beskrevet her. Vi bemerker bare at, avhengig av kompleksiteten til programmet, kan dette mønsteret trenge ytterligere forfining. For eksempel, i et flertrådsmiljø (se artikler om tråder), kan flere forskjellige tråder få tilgang til singleton-metoden samtidig, og koden beskrevet ovenfor vil slutte å virke, siden hver separat tråd kan lage en forekomst av klassen. Som et resultat er det fortsatt flere forskjellige tilnærminger til å lage riktige trådsikre singletons. Men det er en annen historie =)

Og til slutt... Hva er denne late initialiseringen som kapteinen spurte om?

Lazy initialisering kalles også utsatt initialisering. Dette er programmeringstriks der en ressurskrevende operasjon (og å lage et objekt er en ressurskrevende operasjon) utføres på forespørsel i stedet for på forhånd. Så hva skjer egentlig i vår Singleton Java-kode? Objektet vårt er med andre ord opprettet når det åpnes, ikke på forhånd. Du bør ikke anta at lat initialisering på en eller annen måte er stivt knyttet til Singleton -mønsteret. Lazy initialisering brukes også i andre kreative designmønstre, som Proxy og Factory Method, men dette er også en annen historie =)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION