CodeGym /Blog Java /Aleatoriu /Modele și Singleton în Java
John Squirrels
Nivel
San Francisco

Modele și Singleton în Java

Publicat în grup
Acest articol se adresează oricui, pentru prima dată, întâlnește conceptul de modele de design, a auzit termenul singleton sau a implementat cumva modelul singleton, dar nu a înțeles ce se întâmplă. Bine ati venit! Elevii CodeGym întâlnesc modele de design pentru prima dată la Nivelul 15, când căpitanul le cere în mod neașteptat să-și „întărească” înțelegerea prin implementarea modelului Java Singleton cu implementare leneșă. Elevii care aud despre modelul singleton pentru prima dată au instantaneu o mulțime de întrebări: ce naiba este un model de design? De ce avem nevoie de ea? Ce este un singleton ? Și, în sfârșit, ce este implementarea leneșă? Să răspundem la aceste întrebări în ordine.

Ce naiba este un model de design?

Cred că puțină istorie este pentru a răspunde la această întrebare cu cea mai bună înțelegere. Există patru autori celebri de programare (Erich Gamma, John Vlissides, Ralph Johnson și Richard Helm) care au venit cu o idee interesantă. Ei au observat că dezvoltarea de software le cere adesea să rezolve aproximativ aceleași probleme și să scrie cod structurat în același mod. Așa că au decis să descrie modele tipice care adesea trebuie folosite în programarea orientată pe obiecte. Cartea lor a fost publicată în 1994 sub titlul Design Patterns: Elements of Reusable Object-Oriented Software. Numele cărții s-a dovedit a fi prea lung și oamenii au început să o numească pur și simplu cartea Gang of Four. Prima ediție a inclus 23 de modele. Ulterior, au fost descoperite zeci de alte modele.
Un model de design este o soluție standardizată la o problemă comună.
Și modelul singleton este doar unul dintre ele.

De ce avem nevoie de modele de design?

Puteți programa fără să cunoașteți modele: până la urmă, până la Nivelul 15, ați scris deja sute de mini-programe pe CodeGym fără să știți măcar că există. Acest lucru sugerează că modelele de design sunt un fel de instrument a cărui utilizare îl distinge pe maestru de amator: modelele de design descriu cum să rezolve corect o problemă tipică. Aceasta înseamnă că cunoașterea tiparelor vă economisește timp. În acest fel, ele sunt similare cu algoritmii. De exemplu, puteți crea propriul algoritm de sortare cu blackjack și numereși petreceți mult timp făcând acest lucru, sau puteți implementa unul care a fost înțeles și descris de mult timp. Același lucru este valabil și cu modelele de design. În plus, cu modelele de design, codul devine mai standard și, atunci când utilizați modelul corespunzător, este mai puțin probabil să faceți greșeli, deoarece capcanele comune ale modelului au fost identificate și eliminate cu mult timp în urmă. Pe lângă orice altceva, cunoașterea tiparelor îi ajută pe programatori să se înțeleagă mai bine. Puteți spune pur și simplu numele unui model, în loc să încercați să oferiți o explicație lungă colegilor dvs. programatori. În concluzie, modelele de design vă ajută:
  • nu reinventează roata, ci folosește soluții standard;
  • standardizarea codului;
  • standardizarea terminologiei;
Pentru a încheia această secțiune, observăm că întregul corp de modele de design poate fi împărțit în trei grupuri mari: Modele și singleton - pentru toți cei care le întâlnesc pentru prima dată - 2

În cele din urmă, modelul singleton

Singleton este un model de creație . Acest model asigură că există o singură instanță a unei clase și oferă un punct de acces global pentru acest obiect. Din descriere, ar trebui să fie clar că acest model ar trebui aplicat în două cazuri:
  1. atunci când programul dvs. necesită crearea nu mai mult de un obiect dintr-o anumită clasă. De exemplu, un joc pe computer poate avea o clasă Hero și un singur obiect Hero care descrie singurul erou din joc.

  2. atunci când trebuie să furnizați un punct pentru acces global la un obiect. Cu alte cuvinte, trebuie să faceți obiectul disponibil de oriunde în program. Din păcate, nu este suficient să creezi o variabilă globală, deoarece nu este protejată la scriere: oricine poate schimba valoarea variabilei, astfel încât punctul de acces global al obiectului s-ar putea pierde. Aceste proprietăți ale unui Singleton sunt necesare, de exemplu, atunci când aveți un obiect care funcționează cu o bază de date și trebuie să accesați baza de date din diferite părți ale programului. Un Singleton se va asigura că nimeni nu scrie cod care înlocuiește instanța creată anterior.
Deci un Singleton a satisfăcut aceste două nevoi: trebuie să existe doar unul dintr-un anumit tip de obiect în program și trebuie să existe acces global la acesta. În exemplul de la nivelul 15, căpitanul vă cere să implementați acest model pentru următoarea sarcină:
  1. Găsiți un exemplu de Singleton cu inițializare leneșă.

  2. Creați trei clase singleton - Soare, Lună, Pământ - în fișiere separate, folosind același principiu.

  3. ImplementeazăPlanetăinterfață în clasele Soare , Lună și Pământ .

  4. În blocul static al clasei Solution , apelațireadKeyFromConsoleAndInitPlanetmetodă.

  5. ImplementațireadKeyFromConsoleAndInitPlanetfuncționalitatea metodei:

    • 5.1. Citiți un parametru String din consolă

    • 5.2. Dacă parametrul este egal cu unul dintrePlanetăconstantele interfeței, creați obiectul ThePlanet adecvat.

După ce citim cu atenție condițiile sarcinii, putem vedea clar de ce este nevoie de un Singleton aici. Într-adevăr, ni se cere să creăm o instanță pentru fiecare dintre următoarele clase: Soare , Lună , Pământ . Este logic să presupunem că nu ar trebui să creăm mai mult de un Soare/Lună/Pământ. Altfel, ajungem într-o situație absurdă, cu excepția cazului în care, bineînțeles, scrieți versiunea voastră a Războiului Stelelor. Implementarea modelului Singleton în Java în trei pași În Java, comportamentul Singleton nu poate fi implementat folosind un constructor obișnuit, deoarece un constructor returnează întotdeauna un obiect nou. Prin urmare, toate implementările Singletonse reduce la ascunderea constructorului, la crearea unei metode statice publice care controlează durata de viață a obiectului singleton și la „distrugerea” tuturor obiectelor care apar nou. Dacă este accesat un Singleton , acesta ar trebui fie să creeze un nou obiect (dacă unul nu există deja în program), fie să returneze unul existent. Pentru a realiza acest lucru:
  1. Trebuie să oferiți clasei un câmp static privat care stochează un singur obiect:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance; // #1
    }
    
  2. Faceți constructorul (implicit) privat. Aceasta înseamnă că nu poate fi accesat în afara clasei și nu va putea returna obiecte noi:

    
    public class LazyInitializedSingleton {
    	private static LazyInitializedSingleton instance;
    private LazyInitializedSingleton(){} // #2
    } 
    
  3. Declarați o metodă de creare statică care va fi folosită pentru a obține singletonul:

    
    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
        }
    }
    
Exemplul de mai sus este oarecum neîndemânatic, deoarece pur și simplu ascundem constructorul și furnizăm propria noastră metodă în loc de un constructor standard. Deoarece acest articol își propune să se asigure că studenții CodeGym vin în contact cu acest model (și cu modelele de design în general), nuanțele implementărilor singleton mai complexe nu vor fi descrise aici. Menționăm doar că, în funcție de complexitatea programului, este posibil ca acest model să fie mai rafinat. De exemplu, într-un mediu cu mai multe fire (vezi articolele despre fire), mai multe fire diferite pot accesa metoda singleton simultan, iar codul descris mai sus nu va mai funcționa, deoarece fiecare fir separat ar putea crea o instanță a clasei. Drept urmare, există încă mai multe abordări diferite pentru a crea unități single-safe adecvate. Dar asta e alta poveste =)

Și în sfârșit... Ce este această inițializare leneșă despre care a întrebat căpitanul?

Inițializarea leneșă se mai numește și inițializare amânată. Acesta este un truc de programare în care o operație care necesită mult resurse (și crearea unui obiect este o operație care necesită mult resurse) este efectuată la cerere și nu în avans. Deci, ce se întâmplă de fapt în codul nostru Java Singleton ? Cu alte cuvinte, obiectul nostru este creat în momentul în care este accesat, nu în avans. Nu ar trebui să presupuneți că inițializarea leneșă este oarecum legată rigid de modelul Singleton . Inițializarea leneșă este folosită și în alte modele de design creațional, cum ar fi Proxy și Factory Method, dar aceasta este și o altă poveste =)
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION