Singleton wzorzec czy antywzorzec?

0

Jak w końcu jest z tym singletonem?
Na części stron jest on przedstawiony jak ważny wzorzec, na innych jako antywzorzec.
@Koziołek o ile dobrze pamiętam proponował zamienić go na fabrykę.

Jeżeli możecie to podajcie praktyczne przykłady kiedy singleton ma sens i jest wzorcem, a kiedy jest antywzorcem.

0

Ja wykorzystuje to do loggerow/testow.

0

Jezeli ktos potrzebuje pojedynczej instancji klasy to niech sobie stworzy osobna statyczna funkcje, ktora mu zwroci zawsze ten sam obiekt. Wtedy jest wyrazny podzial miedzy klasami w ktore wstrzeliwuje sie zaleznosci a kodem, ktory wstrzeliwuje te zaleznosci.
Innymi slowy jestem przeciwko dodawania do zwyklej klasy, statycznej metody instance() i taki desing traktuje to jako antywzorzec.

0

W dobie IoC nie wiem czy warto zawracać sobie tym głowę. Poza tym ciekawi mnie ile osób umie z palca napisać dobrego singletona, który byłby thread-safe a jednocześnie bez zabijania wydajności metody getInstance() przez lockowanie jej dla jednego wątku.

0

Znaczy zdać się na zasięg singleton w springu i resztę mieć gdzieś?
Inne wzorce też tak można żeby jakiś framework to za mnie zrobił?

0

@DużaTajemnicaWiedzy zasadniczo tak i tak. Jest cała masa frameworków która ułatwia pisanie zgodne z MVC (np. Spring MVC)

0

Dzięki.

0

Jak jest dużo singletonów to ciężko potem testować kod, który je wykorzystuje, zwłaszcza gdy wykonują dość intensywne operacje (nie mówię już o np. połączeniu z bazą danych, jeśli odbywa się ono przez singleton to praktycznie chyba nie da się zrobić testu jednostkowego, chyba że na jakiejś testowej bazie, ale zawsze to spowalnia testy). Zamiast tego dużo lepszym rozwiązaniem jest zastosowanie jakiegoś kontenera IoC, np. Guice, wtedy łatwo jest mockować ciężkie obiekty.

0

@Shalom Chodzi mi o to, że mamy kod wykorzystujący singleton, i chcemy przetestować tę metodę, w ten sposób nie da się zamockować tego singletona, spróbuję to przedstawić na przykładzie:

class Singleton {
void metoda() {...}
static Singleton getInstance() {...}
}

class KlasaKorzystającaZSingletona {
void fun() {
Singleton.getInstance().metoda();
}
}

Tutaj się nie da zamockować tego Singletona, chyba, że dodalibyśmy do klasy korzystającej z singletona setter (z widocznością package-private) przyjmujący obiekt singleton, i odwoływać się do niego w fun() za pomocą zapisanego pola (które na początku inicjować w konstruktorze przez Singleton.getInstance()) w taki sposób: void fun() { singleton.metoda(); }, wtedy w czasie testów od razu po stworzeniu obiektu tej klasy po prostu wstrzyknąć mu mocka i od tego momentu będzie z niego korzystać, ale tak czy inaczej będzie tworzona jedna instancja singletona w czasie testów, która może być ciężka.

1

@axxxxx bullshit. To że korzystasz z jakiejś słabej biblioteki do mockowania to jest twój problem, a nie jakaś generalna prawda. Czego dokładnie "nie da się" zrobić w tym pierwszym przypadku?
Mockować metody statycznej?
http://code.google.com/p/powermock/wiki/MockStatic
nie da się bo klasa singletona jest final?
http://code.google.com/p/powermock/wiki/MockFinal
nie da się bo prywatna metoda?
http://code.google.com/p/powermock/wiki/MockPrivate
nie da się bo gdzieśtam coś jest tworzone przez "new"?
http://code.google.com/p/powermock/wiki/MockConstructor
nie da się mockować bo chcemy testować metodę która używa innych metod tej samej klasy?
http://code.google.com/p/powermock/wiki/MockPartial

Wszystko się da, tylko trzeba korzystać z odpowiednich narzędzi.

1 użytkowników online, w tym zalogowanych: 0, gości: 1