CodeGym /Java blog /Tilfældig /Mønstre og Singleton i Java
John Squirrels
Niveau
San Francisco

Mønstre og Singleton i Java

Udgivet i gruppen
Denne artikel henvender sig til alle, der for første gang støder på konceptet designmønstre, har hørt udtrykket singleton eller på en eller anden måde implementeret singleton-mønsteret, men ikke forstod, hvad der skete. Velkommen! CodeGym-studerende møder designmønstre for første gang på niveau 15, da kaptajnen uventet beder dem om at "forstærke" deres forståelse ved at implementere Java Singleton-mønsteret med doven implementering. Studerende, der hører om singleton- mønsteret for første gang, har med det samme en masse spørgsmål: hvad i alverden er et designmønster? Hvorfor har vi brug for det? Hvad er en singleton ? Og endelig, hvad er doven implementering? Lad os besvare disse spørgsmål i rækkefølge.

Hvad i alverden er et designmønster?

Jeg tror, ​​at lidt historie er for at besvare dette spørgsmål med den bedste forståelse. Der er fire berømte programmeringsforfattere (Erich Gamma, John Vlissides, Ralph Johnson og Richard Helm), som kom med en interessant idé. De bemærkede, at softwareudvikling ofte krævede, at de løser nogenlunde de samme problemer og skrev kode struktureret på samme måde. Så de besluttede at beskrive typiske mønstre, der ofte skal bruges i objektorienteret programmering. Deres bog blev udgivet i 1994 under titlen Design Patterns: Elements of Reusable Object-Oriented Software. Bogens navn viste sig at være for langt, og folk begyndte simpelthen at kalde den for bogen af ​​Firebanden. Den første udgave indeholdt 23 mønstre. Bagefter blev snesevis af andre mønstre opdaget.
Et designmønster er en standardiseret løsning på et almindeligt problem.
Og singleton- mønsteret er kun en af ​​dem.

Hvorfor har vi brug for designmønstre?

Du kan programmere uden at kende mønstre: på niveau 15 har du allerede skrevet hundredvis af miniprogrammer på CodeGym uden overhovedet at vide, at de eksisterer. Dette tyder på, at designmønstre er en slags værktøj, hvis brug adskiller mesteren fra amatøren: Designmønstre beskriver, hvordan man korrekt løser et typisk problem. Det betyder, at du sparer tid ved at kende mønstre. På den måde ligner de algoritmer. Du kan for eksempel lave din egen sorteringsalgoritme med blackjack og talog bruge meget tid på at gøre det, eller du kan implementere en, der har været forstået og beskrevet i lang tid. Det samme er tilfældet med designmønstre. Derudover bliver kode med designmønstre mere standard, og når du bruger det passende mønster, er du mindre tilbøjelig til at lave fejl, da mønstrets almindelige faldgruber blev identificeret og elimineret for længe siden. Ud over alt andet hjælper viden om mønstre programmører til at forstå hinanden bedre. Du kan blot sige navnet på et mønster i stedet for at prøve at give en lang forklaring til dine andre programmører. Sammenfattende hjælper designmønstre dig:
  • ikke genopfinde hjulet, men i stedet bruge standardløsninger;
  • standardisere kode;
  • standardisere terminologi;
For at afslutte dette afsnit bemærker vi, at hele kroppen af ​​designmønstre kan opdeles i tre store grupper: Mønstre og singleton - for alle, der støder på dem for første gang - 2

Endelig singleton-mønsteret

Singleton er et kreativt mønster . Dette mønster sikrer, at der kun er én forekomst af en klasse og giver et globalt adgangspunkt til dette objekt. Fra beskrivelsen bør det være klart, at dette mønster skal anvendes i to tilfælde:
  1. når dit program kræver, at der ikke skal oprettes mere end ét objekt af en bestemt klasse. For eksempel kan et computerspil have en Hero-klasse og kun ét Hero-objekt, der beskriver den eneste helt i spillet.

  2. når du skal angive et punkt for global adgang til et objekt. Med andre ord skal du gøre objektet tilgængeligt hvor som helst i programmet. Ak, det er ikke nok blot at oprette en global variabel, da den ikke er skrivebeskyttet: alle kan ændre variablens værdi, så objektets globale adgangspunkt kan gå tabt. Disse egenskaber for en Singleton er nødvendige, for eksempel når du har et objekt, der fungerer med en database, og du skal have adgang til databasen fra forskellige dele af programmet. En Singleton vil sikre, at ingen skriver kode, der erstatter den tidligere oprettede instans.
Så en Singleton opfyldte disse to behov: der skal kun være et af en bestemt slags objekt i programmet, og der skal være global adgang til det. I eksemplet på niveau 15 beder kaptajnen dig implementere dette mønster til følgende opgave:
  1. Find et eksempel på Singleton med doven initialisering.

  2. Opret tre singleton-klasser - Sol, Måne, Jord - i separate filer ved at bruge samme princip.

  3. ImplementerePlanetgrænseflade i sol- , måne- og jordklasser .

  4. I statisk blok af Solution -klassen kalder dureadKeyFromConsoleAndInitPlanetmetode.

  5. ImplementerreadKeyFromConsoleAndInitPlanetmetode funktionalitet:

    • 5.1. Læs en strengparameter fra konsollen

    • 5.2. Hvis parameteren er lig med en afPlanetgrænsefladens konstanter, skab passende Planet- objektet.

Efter omhyggeligt at have læst opgavebetingelserne, kan vi tydeligt se, hvorfor en Singleton er nødvendig her. Faktisk bliver vi bedt om at oprette en forekomst af hver af følgende klasser: Solen , Månen , Jorden . Det giver mening at antage, at vi ikke skal skabe mere end én sol/måne/jord. Ellers kommer vi i en absurd situation, medmindre du selvfølgelig skriver din version af Star Wars. Implementering af Singleton- mønsteret i Java i tre trin I Java kan Singleton-adfærd ikke implementeres ved hjælp af en almindelig konstruktør, fordi en konstruktør altid returnerer et nyt objekt. Derfor er alle implementeringer af Singletonkoges ned til at skjule konstruktøren, skabe en offentlig statisk metode, der styrer singleton-objektets levetid, og "ødelægge" alle nye objekter. Hvis en Singleton tilgås, skal den enten oprette et nyt objekt (hvis et ikke allerede findes i programmet), eller returnere et eksisterende. For at opnå dette:
  1. Du skal give klassen et privat statisk felt, der gemmer et enkelt objekt:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
    
  2. Gør (standard)konstruktøren privat. Det betyder, at den ikke kan tilgås uden for klassen og ikke vil være i stand til at returnere nye objekter:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    } 
    
  3. Erklærer en statisk oprettelsesmetode, der vil blive brugt til at 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
        }
    }
    
Ovenstående eksempel er noget klodset, da vi simpelthen skjuler konstruktøren og giver vores egen metode i stedet for en standardkonstruktør. Da denne artikel har til formål at sikre, at CodeGym-studerende kommer i kontakt med dette mønster (og designmønstre generelt), vil nuancerne af mere komplekse singleton-implementeringer ikke blive beskrevet her. Vi bemærker kun, at dette mønster, afhængigt af programmets kompleksitet, muligvis skal forfines yderligere. For eksempel, i et multithreaded-miljø (se artikler om tråde), kan flere forskellige tråde få adgang til singleton-metoden samtidigt, og koden beskrevet ovenfor vil holde op med at virke, da hver separat tråd kunne skabe en forekomst af klassen. Som et resultat er der stadig flere forskellige tilgange til at skabe ordentlige trådsikre singletons. Men det er en anden historie =)

Og til sidst... Hvad er denne dovne initialisering, som kaptajnen spurgte om?

Lazy initialisering kaldes også udskudt initialisering. Dette er programmeringstrick, hvor en ressourcekrævende operation (og oprettelse af et objekt er en ressourcekrævende operation) udføres på efterspørgsel i stedet for på forhånd. Så hvad sker der egentlig i vores Singleton Java-kode? Med andre ord, vores objekt er skabt på det tidspunkt, det er tilgået, ikke på forhånd. Du skal ikke antage, at doven initialisering på en eller anden måde er stift bundet til Singleton- mønsteret. Lazy initialisering bruges også i andre kreative designmønstre, såsom Proxy og Factory Method, men dette er også en anden historie =)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION