Singleton – czyli jak sobie strzelić w stopę …

… podczas rekrutacji, a zwłaszcza w codziennym kodowaniu.

Jakie zna pan wzorce projektowe i proszę opisać jeden z nich?

strzał w stopę

Mi też zdarzało się tutaj odpowiadać, że Singleton. Bo prosty, bo rozumiem jak działa i jakie problemy rozwiązuje. Myliłem się – Singleton to antywzorzec. W uczciwej dyskusji o wzorcach projektowych trzeba powiedzieć jakie problemy rozwiązuję, ale też jakie wprowadzają (bo zawsze są jakieś efekty uboczne).

What is so bad about Singletons?

  1. They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
  2. They violate the Single Responsibility Principle: by virtue of the fact that they control their own creation and lifecycle.
  3. They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
  4. They carry state around for the lifetime of the app. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Oczywiście tam na StackOverflow jest dyskusja i warto się z argumentami jednych i drugich zapoznać, aby wyrobić sobie ostateczne zdanie.

Nie pamiętam, żebym w ostatnim roku napisał coś na kształt Singletona. Owszem zdarza mi się korzystać, lae przychodzą mi do głowy tylko dwa przypadki:

  1. ServiceLocator.Instance.GetInstance() – ServiceLocator jest Singletonem, nie zastanwiałem się nigdy czy tak musi być, ale chyba nie można tego obejść.
  2. Logger.Log(…) – jest kilka sposobów jak dobrze pobrać instancję do logowania, więc to tylko przykład. Czasem loggera pobieram z ServiceLocatora.

Te dwa przypadki to nie jest to kod, który się pisze, są to tylko takie przydatne, dobrze przemyślane narzędzia z których korzystamy.

9 Comments on “Singleton – czyli jak sobie strzelić w stopę …

  1. Singleton to dość skuteczne rozwiązanie dla urządzeń mobilnych z systemem Windows CE/Mobile. Urządzeni nie są zbyt szybkie i niektóre instancje klas tworzą się dość wolno porównując to do innych platform. Tam Singleton sprawdza się dość dobrze, zazbraja całą aplikację w potrzebne klasy i zapobiega tworzeniu nowej instacji i zablokowaniu wątków itp. W takim przypadku to nawet konieczność.

  2. Pingback: dotnetomaniak.pl

  3. service locator to też jest przykład antywzorca 🙂

  4. Najlepiej na wypadek takiego pytania miec w pameci jakis projekty w ktorym wykorzystalo sie wzorzec 🙂 Ja np zapamietalem fajne zastosowanie subscribera / receivera

  5. @Łukasz Racja, czytałem o tym już kiedyś (http://www.pzielinski.com/?p=1154). Trzeba każdorozowo wyważyć wady vs zalety. Odpowiedź nie jest zresztą taka oczywista jak w przypadku Singletona.

    Szczęśliwie korzystam bo framework na którym oparty jest mój kod wymaga takiego podejścia. Sam osobiście w moim kodzie wszystkie zależności wstrzykuję poprzez konstruktor (korzystam z StructureMap).

  6. @Michał, bingo. Tłumaczyłem kiedyś koledze, żeby na rozmowie nie opowiadał o żadnym wzorcu, którego nie zastosował w kodzie.

  7. W aplikacjach biznesowych rzeczywiście trudno o dobry przykład. Zazwyczaj bardzo rzadko nam zależy na jednej instancji klasy, zwłaszcza że w przypadku gdy aplikacja pracuje w kilku instancjach albo na kilku nodeach Singleton nie gwarantuje jednej instancji danej klasy.
    Osobiście widzę jego zastosowanie w przypadku gdy nasza aplikacja ma wiele wątków ale współpracuje z *jednym* urządzeniem z bardzo prostymi kanałami komunikacji.
    Osobiście w tym roku użyłem tego wzorca raz. Przy implementacji Fabryki wytwarzającej instancje serwisów (które są klasami dość ciężkimi w wytworzeniu, a przy tym bezpiecznymi pod względem współbieżności więc są ‚cachowane’ w polach fabryki) i nie chciałem żeby programista – klient tworzył wiele instancji samej fabryki. Nie wiem czy to była słuszna decyzja.
    Z Singletonem jak z każdym wzorcem jeżeli użyjemy go do rozwiązania problemów których nie mamy prosimy się o kłopoty.

  8. W miejscach gdzie kiedyś użyłbym Singletona ze względu za koszt wytworzenia, teraz czasem korzystam z Cache’a. Co prawda jak to piszę to widzę, że nie rozwiązuje to do końca Twojego problemu – dalej programiści mogą tworzyć własne instancje. Może pomogłoby właśnie podanie im takiego Cache’a z przykładem na tacy. Z jasnym przekazem, że tylko w ten sposób w aplikacji pobiera się ww. serwisy ?

  9. Dlatego ja nigdy nie podaję singletona jako przykład wzorca w rozmowach rekrutacyjnych. 🙂 Jest tyle innych prostych i pięknych wzorców, o których można coś powiedzieć i podać przykład praktycznego zastosowania, np. strategia i metoda szablonowa.