Jak uzywac wzorca Singleton

Jak uzywac wzorca Singleton
0

Szukam informacji o wzorcach projektowych w internecie i wyczytałem, że Signleton umozliwia jednego obiektu z klasy z globalnym dostepem.
Potem jednak zatrzymuję się na nie do końca dla mnie czytelnym kodzie. Moze ktoś dobry opisać krótko jak używać singletonu na jakimś konkretnym przykładzie najlepiej podając w komentarzach obok linijki jak najprościej za co dana linijka jest odpowiedzialna? Znalazlem w internecie kilka krotkich przykładow programów, które implementują ten wzorzec, ale niestety ogolnikowo i slabo wyjasnionych.

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Chodzi ci o zastosowanie?
Wyobraź sobie że masz aplikację desktopową którą można sobie skonfigurować i powybierać różne opcje. Działanie wsystkich funkcji aplikacji zależy od tej konfiguracji.
Powiedzmy że masz w konfiguracji do ustawienia scieżkę do katalogu z plikami wejściowymi i wyjściowymi.
Jeśli teraz w aplikacji klikas guzik "otwórz plik" to powinno pojawić się okienko wyboru pliku, ale powinno wystartować w katalogu z konfiguracji. Analogicznie jak robisz "zapisz plik". Siłą rzeczy widać, że potrzeba tej konfiguracji w różnych miejscach. Widać też ze jest tylko jedna.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
0

I tak właśnie tworzymy programy, które są praktycznie nietestowalne.


jeden i pół terabajta powinno wystarczyć każdemu
Shalom
Jeśli to wstrzykujesz to nie jest aż tak źle.
jarekr000000
To pokaż Singletona, który wstrzykujesz i jest nadal singletonem, czyli nie możesz łatwo zrobić innej instancji.
danek
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Poznań
  • Postów:797
0

A nie jest tak, ze singleton zapewnia jedną instancję a nie globalny dostęp?


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
danek
chociaż po pewnym zastanowieniu się dochodzę do wniosku, że to trochę to samo
W0
Nie do końca. Nie za bardzo rekomenduję takie podejście, ale dzięki package-access możesz ograniczyć zasięg singletona do pakietu, w którym się znajduje. W teorii świetny pomysł, w praktyce pewnie jak to zbytnie poleganie na singletonach - po jakimś czasie się rozleci.
zyxist
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 6 lat
  • Postów:101
1

Jak stosować singleton? Nie stosować. Jeśli potrzebujesz, żeby jeden obiekt miał referencję do drugiego, wrzuć mu tę referencję np. przez konstruktor albo jako argument metody.

Kopiuj
public class A {
    private final B be;

    public A(B be) {
        this.be = be;
    }
}

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@jarekr000000 @zyxist trochę się tu z wami nie zgadzam, bo mylicie ideę z konkretną metodą implementacji. To troche jakby hejtować Dependency Injection bo ktos nie lubi kontenerów IoC.
Singleton oznacza generalnie, że mamy jedną instancję obiektu oraz zapewniony do niego dostęp, ale wcale nie musi koniecznie ozaczać że mamy tam klasyczne statyczne getInstance() albo coś podobnego, co potem utrudnia testowanie. Wydaje mi się że wstrzykniecie (w dowolny sposób) takiego singletona wcale nie odbiera mu nic z singletonowości.
Zresztą bardzo często w ogóle nie zależy nam koniecznie na tym żeby mieć jeden obiekt, a na tym, żeby operować na tym samym stanie, jak w patternie Borg.

@jarekr000000 dobrze wiesz, że poza enumem nie da się wymusić, żeby istniała tylko jedna instancja. Jak ktoś chce to zawsze może sobie drugą stworzyć, w bardziej lub mniej hardkorowy sposób ;)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
jarekr000000
Z tym enumem to nie mam teraz chwili się bawić, ale spoko, da się obejść.
Shalom
Jest jedna instancja per classloader, więc technicznie rzecz biorąc mając więcej classloaderów mógłbyś mieć więcej instancji tego samego enuma... ;]
jarekr000000
Ja tu raczej Unsafem i podobnymi był pojechał.
W0
@jarekr000000 czy założenie nie było takie, że "trudno" zrobić drugą onstancję, a nie że się nie da?
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
0

Pomijając fakt, że zawsze można hardkorowo stworzyć instancję to nie sądzisz, że ten Singleton umowny to troszkę słabizna.
Dziadowie założyciele Javy wymyślali jakieś public, private, a my tu robimy wszystko public i umawiamy się, że będziemy pamiętać, żeby niektórych konstruktorów i metod nie wywoływać, bo niu - niu. Piękne.


jeden i pół terabajta powinno wystarczyć każdemu
W0
Założyciele Javy w pierwszej wersji dorzucili też aplety.
katelx
  • Rejestracja:prawie 10 lat
  • Ostatnio:4 miesiące
  • Lokalizacja:Hong Kong
0

tak ogolnie to jest antywzorzec. jedyne sensowne uzycie jakie przychodzi mi do glowy to do bezstanowych klas implementujacych jakis interfejs (t.j. null object) ale i to jest raczej dyskusyjne

Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Stacktrace
  • Postów:6821
1

Taki mały offtopic, bo @jarekr000000 i @Shalom trochę popłynęli :)

  1. Singleton jako wzorzec projektowy ma zastosowanie wszędzie tam gdzie nie ma sensu tworzenie wielu instancji obiektów TEJ SAMEJ KLASY. Przykładem jest konfiguracja, ale też np. obiekty fabryk, czy też bezstanowe usługi.
  2. Czym innym jest jednak wstrzykiwanie singletonów, ponieważ to powinno opierać się o interfejsy. W ten sposób w jednym systemie możesz mieć wiele singletonów, które implementują ten sam interfejs.
  3. Testowalność zależy od tego jak używasz singletonu i jak go inicjujesz. Jeżeli używasz go jako zależności, którą wstrzykujesz przez konstruktor i powiązanie pomiędzy twoim kodem a singletonem jest na poziomie interfejsu, to kod nadal jest testowalny. Pytanie jak przetestować singleton?
  • Jeżeli jest bezstanowy i nie ma żadnych zależności/zależności przyjmuje w jako argumenty poszczególnych metod, to pikuś.
  • Jeżeli jest bezstanowy, ale ma zależności, to należy tak przygotować jego inicjalizację, by można było konfigurować nasz obiekt. Metoda fabrykująca jest całkiem OK.
  • Jeżeli jest stanowy, to masz problem.

Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
zyxist
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 6 lat
  • Postów:101
0

@Shalom, autor pytał o konkretny wzorzec projektowy, a nie o ideę:

Szukam informacji o wzorcach projektowych w internecie i wyczytałem, że Signleton umozliwia jednego obiektu z klasy z globalnym dostepem.

To jest oczywiste, że w aplikacji będą klasy, których liczba instancji wynosi 1 i chyba nikt tutaj tego nie zanegował.


Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)