JavaRush /Blog Java /Random-PL /Wzory i Singleton - dla wszystkich, którzy zetknęli się z...

Wzory i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy

Opublikowano w grupie Random-PL
Artykuł ten skierowany jest do tych, którzy po raz pierwszy zetknęli się z pojęciem wzorców, słyszeli o Singleton„e” lub w jakiś sposób je stworzyli, ale nadal niczego nie rozumieli. Powitanie! Uczniowie JavaRush po raz pierwszy spotykają się z wzorcami na poziomie 15, kiedy nieoczekiwanie cap prosi o „naprawienie” i zaimplementowanie wzorca Singletonz leniwą implementacją. Studenci, którzy słyszą o tym po raz pierwszy, Singletonod razu mają mnóstwo pytań: czym jest wzorzec, do czego jest potrzebny, jaki to rodzaj wzorca Singletoni wreszcie, co to za leniwa implementacja. Zacznijmy odpowiadać w kolejności: Wzorce i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy - 1

Czym w ogóle jest wzór?

Myślę, że dla lepszego zrozumienia warto odpowiedzieć sobie na to pytanie z historii. Wśród programistów jest tak znanych czterech autorów: Erich Gamma, Richard Helm, Ralph Johnson i John Vlissides, którzy wpadli na ciekawy pomysł.
Wzorce i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy - 2
Zauważyli, że pisząc programy często musieli rozwiązywać w przybliżeniu te same problemy i pisać kod tego samego typu w strukturze. Dlatego postanowiono opisać w formie wzorców typowe wzorce, które często są stosowane w programowaniu obiektowym. Książka ukazała się w 1995 roku pod tytułem „Techniki projektowania obiektowego. Wzorce projektowe" . Tytuł książki okazał się za długi i stała się po prostu znana jako Księga bandy czwórki . W pierwszym wydaniu opublikowano 23 wzory, po czym odkryto dziesiątki kolejnych. Zatem odpowiadając na pytanie zawarte w tym akapicie: „Czym są wzorce?” , podsumujmy w kilku słowach:
Wzorzec to ustandaryzowane rozwiązanie typowego problemu.
A Singletonto tylko jeden z takich wzorów.

Dlaczego potrzebujemy wzorców (wzorców projektowych)

Możesz programować bez znajomości wzorców; możesz to zweryfikować po prostu zdając sobie sprawę z faktu, że na 15. poziomie w JavaRush napisałeś setki miniprogramów, nie wiedząc nic o ich istnieniu. Sugeruje to, że wzór jest rodzajem narzędzia, którego obecność odróżnia mistrza od amatora:
Wzorce i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy - 3
Wzorce opisują, jak poprawnie rozwiązać jeden z typowych problemów. W rezultacie znajomość wzorców oszczędza czas. Analogię można przeprowadzić z algorytmami. Można na przykład wymyślić własny algorytm sortowania z blackjackiem i liczbami i spędzić nad nim dużo czasu, lub można skorzystać z takiego, który został już opisany dawno temu i go wdrożyć. Podobnie jest ze wzorami. Dodatkowo dzięki zastosowaniu wzorców kod staje się bardziej ujednolicony, a stosując odpowiednie wzorce, będziesz mniej skłonny do popełniania błędów, gdyż zostały one już w tym wzorcu przewidziane i wyeliminowane. No i przede wszystkim znajomość wzorców pozwala programistom lepiej się rozumieć. Wystarczy powiedzieć nazwę szablonu, zamiast próbować wyjaśniać innym programistom, czego od nich oczekujesz. Podsumowując, wzorce projektowe pomagają:
  • nie wymyślaj koła na nowo, ale skorzystaj ze standardowych rozwiązań;
  • standaryzować kod;
  • ujednolicić terminologię;
Podsumowując tę ​​sekcję, zauważamy, że całą różnorodność wzorów można uprościć w trzech dużych grupach:
Wzorce i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy - 4

Wreszcie wzór Singletona

Singletonodnosi się do wzorców generatywnych . Jego dosłowne tłumaczenie to samotnik. Ten wzorzec zapewnia, że ​​klasa ma tylko jeden obiekt (jedną instancję klasy) i że dla tego obiektu jest zapewniony globalny punkt dostępu. Z opisu powinno jasno wynikać, że wzór ten należy zastosować w dwóch przypadkach:
  1. gdy w programie nie powinien być utworzony więcej niż jeden obiekt dowolnej klasy. Na przykład w grze komputerowej masz klasę „Postać”, a klasa ta powinna zawierać tylko jeden obiekt opisujący samą postać.

  2. kiedy musisz zapewnić globalny punkt dostępu do obiektu klasy. Innymi słowy, musisz się upewnić, że obiekt zostanie wywołany z dowolnego miejsca w programie. I niestety w tym celu nie wystarczy po prostu utworzyć zmienną globalną, ponieważ nie jest ona chroniona przed zapisem i każdy może zmienić wartość tej zmiennej, a globalny punkt dostępu do obiektu zostanie utracony. Te właściwości Singletonsą potrzebne na przykład wtedy, gdy masz obiekt klasy współpracującej z bazą danych i potrzebujesz, aby baza danych była dostępna z różnych części programu. I Singletonzagwarantuje, że żaden inny kod nie zastąpi wcześniej utworzonej instancji klasy.
Te dwa problemy rozwiązuje się w następujący sposób Singleton: w programie musi znajdować się tylko jeden obiekt i musi być do niego globalny dostęp. W przykładzie na poziomie 15 cap prosi o zaimplementowanie tego wzorca dla następującego zadania (tutaj jego opis):
Wzorce i Singleton - dla wszystkich, którzy zetknęli się z nimi po raz pierwszy - 5
Po uważnym przeczytaniu warunku staje się jasne, dlaczego dokładnie Singleton(Pojedynczy) jest tutaj potrzebny. W końcu program prosi o utworzenie po jednym obiekcie każdej klasy: Sun, Moon, Earth. I logiczne jest założenie, że każda klasa w programie powinna stworzyć nie więcej niż jedno Słońce/Księżyc/Ziemię, w przeciwnym razie będzie to absurdalne, chyba że oczywiście napiszesz własną wersję Gwiezdnych Wojen. Cecha implementacji SingletonJava w trzech krokach Zachowania Singleton w Javie nie można zaimplementować przy użyciu zwykłego konstruktora, ponieważ konstruktor zawsze zwraca nowy obiekt. Dlatego wszystkie implementacje Singleton'a sprowadzają się do ukrycia konstruktora i stworzenia publicznej metody statycznej, która będzie kontrolować istnienie pojedynczego obiektu i „niszczyć” wszystkie nowo pojawiające się obiekty. Jeśli Singletonzostanie wywołane 'a, musi albo utworzyć nowy obiekt (jeśli nie ma go jeszcze w programie), albo zwrócić taki, który został już utworzony. Aby to zrobić: #1. – Musisz dodać prywatne pole statyczne do klasy zawierającej pojedynczy obiekt:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – Ustaw konstruktor klasy (konstruktor domyślny) jako prywatny (tak, aby dostęp do niego był zamknięty poza klasą, wtedy nie będzie mógł zwracać nowych obiektów):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – Zadeklaruj statyczną metodę tworzenia, która będzie używana do uzyskania singletonu:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//jeśli obiekt nie został jeszcze utworzony
            instance = new LazyInitializedSingleton();	//utwórz nowy obiekt
        }
        return instance;		// zwróć poprzednio utworzony obiekt
    }
}
Powyższy przykład jest nieco niezgrabny, ponieważ po prostu ukrywamy konstruktor i udostępniamy własną metodę zamiast standardowego konstruktora. Ponieważ ten artykuł ma na celu umożliwienie studentom JavaRush zetknięcia się z tym wzorcem (i wzorcami w ogóle) po raz pierwszy, nie będą tutaj podawane cechy implementacyjne bardziej złożonych Singletonów. Zauważamy jedynie, że w zależności od złożoności programu może być wymagane bardziej szczegółowe udoskonalenie tego wzoru. Przykładowo w środowisku wielowątkowym (zobacz temat Threads) kilka różnych wątków może jednocześnie wywołać metodę gettera Singletona, a opisany powyżej kod przestanie działać, gdyż każdy indywidualny wątek będzie mógł utworzyć wiele instancji klasy natychmiast. Dlatego nadal istnieje kilka różnych podejść do tworzenia poprawnych singletonów bezpiecznych dla wątków. Ale to już inna historia =) I na koniec. Co to jest leniwa inicjalizacja, o którą prosił limit ? Leniwa inicjalizacja jest również nazywana leniwą inicjalizacją. Jest to technika programowania, w której operacja pochłaniająca duże zasoby (a tworzenie obiektu jest operacją wymagającą dużych zasobów) jest wykonywana na żądanie, a nie z wyprzedzeniem. Co zasadniczo dzieje się w naszym kodzie Singleton„a. Innymi słowy, nasz obiekt jest tworzony w momencie uzyskania dostępu, a nie z wyprzedzeniem. Nie należy zakładać, że koncepcja leniwej inicjalizacji jest w jakiś sposób ściśle związana z Singleton„om”. Leniwa inicjalizacja jest również stosowana w innych generatywnych wzorcach projektowych, na przykład w Proxy i Factory Method, ale to już inna historia =) Przy przygotowaniu artykułu wykorzystano następujące źródła:
  1. Najlepsze praktyki dotyczące wzorców projektowych Java Singleton z przykładami
  2. Wzorce projektowe
  3. Popraw Singleton w Javie
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION