2013-08-16 18 views
21

To całkiem proste pytanie. Ignorowanie konsekwencji nadmiernego użycia wzorca singleton. Próbuję znaleźć wiarygodne tupot singletonu w Objective-C. Mam natknąć się następująco:Static Class vs Singleton

@implementation SomeSingleTonClass 

static SomeSingleTonClass* singleInstance; 

+ (SomeSingleTonClass*)getInstance 
{ 
    static dispatch_once_t dispatchOnceToken; 

    dispatch_once(&dispatchOnceToken, ^{ 
     singleInstance = [[SomeSingleTonClass alloc] init]; 
    }); 

    return singleInstance; 
} 

- (void)someMethodOnTheInstance 
{ 
    NSLog(@"DO SOMET WORK") 
} 

@end 

to jestem dość zadowolony, ale to prowadzi do wielu następująco:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

Moje pytanie brzmi, dlaczego jest to lepsze niż klasy czysto statycznym.

@implementation SomeStaticClass 

static NSString* someStaticStateVariable; 

- (id)init 
{ 
    //Don't allow init to initialize any memory state 
    //Perhaps throw an exception to let some other programmer know 
    //not to do this 
    return nil; 
} 

+ (void)someStaticMethod 
{ 
    NSLog(@"Do Some Work"); 
} 

Wszystko, co naprawdę zyskujesz, to łagodnie czystsze metody wywoływania metod. Zasadniczo zamienić się w ten sposób:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance]; 

Z tego

[SomeStaticClass someStaticMethod]; 

To drobne uproszczenie na pewno, i zawsze można przechowywać wewnątrz instancji klasy. To jest bardziej intelektualna ciekawość, jaki bóg Objective-C wkurza mnie za pomocą klas statycznych zamiast singletonów? Jestem pewien, że nie mogę być pierwszą osobą, która to wymyśli, ale obiecuję, że najpierw zrobiłem duplikat wyszukiwania. Kilka odpowiedzi, które znalazłem, miałem wrażenie, że były oparte na starszych wersjach kakao, ponieważ nawet omawiane wzorce singletonowe wydawały się mieć problemy z wątkami.

+0

Myślę, że masz rację, ale to pytanie jest nieco zawiłe (choć odpowiedź jest solidna!). Mam zamiar opuścić moje, ale biorąc pod uwagę odpowiedzi w tym wątku, nie muszę czekać na awanse na odpowiedź Drummera. Jest prawidłowe. Dzięki! – ChrisCM

+0

Co to jest klasa statyczna? – Monolo

+0

Klasa statyczna (prawdopodobnie jest to lepsza nazwa) jest klasą, która opiera się na metodach klasy i statycznych zmiennych klasowych, a nie instancjonowanych metodach obiektów i instancji. To sprawia, że ​​jest to wygodny singleton. Zwłaszcza jeśli zakodujesz metodę init, aby rzucić wyjątek! – ChrisCM

Odpowiedz

1

Nie wtrącasz bogów Celu-C z taką klasą. W rzeczywistości Apple zaleca używanie tego wzorca w niektórych przypadkach (myślę, że wspomnieli o tym w jednym z filmów z sesji ARC, gdzie omawiali typowe wzorce projektowe i jak je zaimplementować za pomocą ARC).

W innych przypadkach, gdy możesz mieć wiele instancji klasy, ale chcesz mieć domyślną, musisz oczywiście zastosować metodę współdzielonej instancji.

+0

Zasadniczo poprawny. Zobacz także odpowiedź w link "duplikat" Martin przewidywał reperkusje każdego z nich. Wydawałoby się, że żadne podejście nie jest lepsze lub gorsze, po prostu inne. – ChrisCM

+2

Jedną z rzeczy, której nikt nie wskazał, jest to, że nietrywialny singleton (w przeciwieństwie do klasy statycznej) może zrobić o wiele więcej rzeczy, ponieważ jest to uzasadniona instancja. Zarejestruj się, aby otrzymywać powiadomienia, obserwuj wartości klucza, używaj jako źródła danych itp. –

+0

Kiedy mówisz "ten wzór", o jakim rozmiarze mówisz? lol. Włożył dwa różne wzory w słupek. – TheJeff

3

Znalazłem wygodne połączenie obu. Używam standardowego Singleton podobną do Twój pierwszy, że wyniki w:

[[MyClass defaultInstance] doSomething]; 

Ale chcę, aby móc tworzyć inne wystąpienia tej samej klasy:

MyClass *secondInstance = [[MyClass alloc] init]; 
[secondInstance doSomething]; 

gdy chcę bardziej zwięzły dostępu wywołać metody na singleton przykład zdefiniować metody klasy następująco:

// class method to call a method on the singleton instance 
+ (void)doSomething 
{ 
    [[MyClass defaultInstance] doSomething]; 
} 

Więc z tym, mogę użyć:

[MyClass doSomething]; 
1

Pierwszy przykład wydaje się niepotrzebnie tworzyć pojedynczą instancję klasy. Mówię niepotrzebnie, ponieważ z innych komentarzy wynika, że ​​klasa nie deklaruje żadnych właściwości ani zmiennych instancji. Biorąc pod uwagę, że podstawowym celem obiektu jest zapewnienie przechowywania dla stanu, obiekt bez zmiennych instancji rzadko jest przydatny.

Twój drugi przykład pokazuje klasę, która nigdy nie zostanie utworzona. Ponownie, podstawowym celem klasy w Objective-C jest działanie jako fabryka instancji, więc klasa, która nigdy nie jest tworzona, nie jest naprawdę użyteczna ani potrzebna.

Zamiast tego można po prostu podać zestaw funkcji C. Funkcje C nie muszą być w ogóle związane z klasą.Więc rozważyć robi coś takiego:

static NSString* someStaticStateVariable; 

void someFunction(void) 
{ 
    NSLog(@"Do Some Work"); 
} 

Funkcje te mogą być w oddzielnej pary .h/.m lub mogą być włączone w .h/.m dla istniejącej klasy, jeśli ma to sens, aby to zrobić (ogólnie, jeśli funkcje są ściśle związane z obawami tej klasy).

+0

Demonstracje klasy miały na celu zademonstrowanie wzorców projektowych, które brałem pod uwagę, a nie użycie, które rozważałem. Oczywiście oczekuję, że moje zajęcia będą miały o wiele więcej stanu niż przedstawiłem w moich uproszczonych przykładach, ze względu na pytanie o przepełnienie stosu. – ChrisCM

+0

@ChrisCM Wydaje się, że mówisz, że twoje instancje będą miały stan, ale w twoim drugim przykładzie, zastąpisz 'init', aby wyłączyć tworzenie instancji, więc oczywiście nie ma możliwości posiadania obiektów ze stanem. Nie można dodać stanu do klasy, więc pozostały tylko zmienne globalne. Ponownie, nie potrzebujesz klas i metod, aby używać zmiennych globalnych, więc dlaczego nie używać tylko funkcji C? – jlehr

+0

Domyślam się, że ostatecznie nie odpowiada na pytanie. Oba rozwiązania mają potencjalnie tę samą wadę, która zachowuje stan w statycznych zmiennych globalnych. To jest to "dlaczego/dlaczego nie?" że jestem ciekawy, a nie jak. Tak więc, w odpowiedzi na pytanie, dlaczego nie korzystać z prostych funkcji C? Ponieważ kojarzenie czegoś z klasą jest z natury przydatne do lepszego zrozumienia kodu. [MyDatabaseClass someFunction] mówi mi o wiele więcej o tym, co się dzieje, niż someFunction(). – ChrisCM

16

Klasa statyczna: Używane, gdy chcesz zgrupować metody użytkowe, które są niezależne od stanu.

Singleton: Używany, gdy istnieje wiele metod współużytkujących stan.