Jaka jest rzeczywista (tzn. praktyczna) różnica między klasą statyczną a wzorcem singleton?
Oba mogą być wywoływane bez instancjonowania, oba zapewniają tylko jedną "instancję", czego lepiej używać?
Jaka jest rzeczywista (tzn. praktyczna) różnica między klasą statyczną a wzorcem singleton?
Oba mogą być wywoływane bez instancjonowania, oba zapewniają tylko jedną "instancję", czego lepiej używać?
Trudno powiedzieć. Klasa to klasa, singleton to instancja klasy.
W skrócie - to tak, jakbyś pytał jaka jest różnica pomiędzy samochodami (klasa obiektów), a tym Fiatem, który stoi u ciebie w garażu.
Zacznijmy od tego że w Javie nie ma czegoś takiego jak klasa statyczna
. Jest klasa z samymi metodami statycznymi i polami statycznymi z prywatnym konstruktorem i od biedy taki twór można by nazwać klasą statyczną. Główna różnica jest taka że taka klasa statyczna nie może implementować interfejsów i dziedziczyć z klas abstrakcyjnych
Inaczej sytuacja wygląda np w Scali gdzie język dostarcza object
który jest singletonem wbudowanym w język. object
jest jedyną możliwością na tworzenie w Scali metod statycznych łącznie z main
em.
Jest jeszcze drugi wzorzec o otórym pisał Uncle Bob, ale teraz nie umiem sobie przypomnieć jego nazwy rozwiązujący podobne problemy co singleton, ale teraz nie umiem przypomnieć sobie jego nazwy i musiał bym iśc poszukać w książkach. Idea jest taka że zawsze tworzysz nowy obiekt, ale współdzielisz wszystkie dane bo używasz tylko pół statycznych.
BTW singleton jest często też uważany za antywzorzec, bo powoduje problemy z testowaniem jak ktoś stworzy zbyt skomplikowane singletony
UPDATE znalazłem. Zwinne wytwarzanie oprogramowania. Najlepsze zasady, wzorce i praktyki. Rozdział 16. Wzorce projektowe Singleton i Monostate (191)
Obiekt zawsze można podmienić na inny, o ile interfejs jest taki sam. Jak w kodzie masz wywołania statycznych metod to już niewiele się da zrobić. To z jednej strony potencjalnie utrudnia testowanie (trzeba cudów jak powermock żeby podmienić sobie statica) a z drugiej strony utrudnia rozszerzanie kodu. Np. chciałbyś dodać jakieś cache nad niektórymi metodami. W przypadku obiektu nie ma problemu -> tworzysz nową klasę o tym samym interfejsie, delegujesz wywołania a co chcesz to sobie cachujesz, a potem zamieniasz gdzieśtam new ABC()
na new CachingABC(new ABC())
. Jeśli leciałeś tam staticami to już takie trywialne nie jest.
Statyczne metody są dobre jako utilsy, typu StringUtils z metodą emptyOrBlank albo inne FileUtils. Singletonów nie używa się za bardzo w klasyczny sposób, są one ogarniane przez kontenery IoC.
Singleton, to sposób na posiadanie wyłącznie jednej instancji jakiejś klasy. Można to osiągnąć na różne sposoby.
Klasa statyczna, zakładając, że piszemy o Javie nie ma nic wspólnego ze statycznością. Oznacza się w ten sposób klasę wewnętrzną, która nie ma dostępu do pól klasy zewnętrznej, w związku z tym może być utworzona nawet jeżeli klasa "główna" nie istnieje.
Czyli można tak:
public class SomeClass {
private int a = 5;
private InnerClass innerClass = new InnerClass();
public class InnerClass{
public InnerClass() {
SomeClass.this.a++;
}
}
}
//gdzieś:
new SomeClass();
//ale nie
new SomeClass.InnerClass(); //błąd
A można zrobić tak:
public class SomeClass {
private int a = 5;
private InnerClass innerClass = new InnerClass();
public static class InnerClass{
public InnerClass() {
SomeClass.this.a++; //błąd, nie można się odwołać z klasy statycznej to klasy zewnętrznej
}
}
}
//gdzieś:
new SomeClass();
//też zadziała
new SomeClass.InnerClass();
O klasycznej implementacji Singleton w Javie raczej zapomnij, pisze o czymś w tym stylu:
public class Singleton {
private static volatile Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}