2013-07-27 16 views
7

Czytałem trochę informacji o strukturze klasy klastrów i zrozumiałe dalej:Objective-C i klasy Cluster wzór

  • publicznej klasy klaster zapewnia tylko interfejs bez faktycznej realizacji, inne klasy wdrożyć go w różnych przypadkach;

  • ma pewne podobieństwa do wzorca Abstrakcyjna Fabryka: kiedy wywołujemy metodę +classNameWith..., w zależności od argumentów można wybrać najbardziej odpowiednią podklasę i zwrócić ją.

Na przykład, +[NSNumber numberWithDouble:1.0] powróci wdrożenie do przechowywania wartości podwójnych.

Ale czego nie rozumiem: jak działa -init... metod klasy klastrów publicznym: [[NSNumber alloc] initWithDouble:1.0], a po wywołaniu alloc już przydziela wystąpienie z NSNumber, nie jest podklasą.

Czy ktoś może wyjaśnić, jak faktycznie działa alloc-init metody publicznej klasy klastra, a kiedy konkretna podklasa jest tworzona i zwracana?

+2

Możesz być zainteresowany przeglądaniem [GNUStep wersji NSNumber.m] (https://github.com/gnustep/gnustep-base/blob/master/Source/NSNumber.m). –

+0

Josh Caswell, dzięki za świetny link! – Mikhail

+0

Zakładam, że przeczytałeś już [Koncepcje w Objective-C Programming: Class Clusters] (https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html)? –

Odpowiedz

5

Zasadniczo przydzielona instancja może zostać odrzucona i zastąpiona inną instancją. Technicznie rzecz biorąc, to nie jest specyficzne dla klasy klastrów i dlatego podczas rozmowy super w jakikolwiek sposób init trzeba ustawić wynik jako self:

self = [super init]; 
+1

Co więcej, metoda + alloc może być nadpisana, tak jak każda inna metoda. Przydział klastrów klas prawdopodobnie zwróci statyczną instancję, a nie nowe obiekty tworzone i zwalniane za każdym razem, gdy zażądasz nowej instancji. –

+0

Znudzony astronauta, tak też uważałem, że zastępują one metodę alokacji, ponieważ w przeciwnym razie będzie jakiś narzut na niszczenie przydzielonych obiektów. – Mikhail

-2

Oto Streszczenie realizacja fabrycznym Cel C.

// Usage 
    BrandingFactory * factory = [BrandingFactory factory:Sierra]; 

    UIView * view = [factory brandedView]; 

    UIButton * button = [factory brandedMainButton]; 

    UIToolbar * toolbar = [factory brandedToolbar]; 
____________________________________________ 
// BrandingFactory.h 
// AbstractFactory 

#import <Foundation/Foundation.h> 

typedef enum ouputTypes { 
    Acme, 
    Sierra 
} OutputTypes; 

@interface BrandingFactory : NSObject 
{ 

} 

+ (BrandingFactory *) factory: (OutputTypes)type; 

- (UIView *) brandedView; 
- (UIButton *) brandedMainButton; 
- (UIToolbar *) brandedToolbar; 

@end 

___________________________________________________ 

// BrandingFactory.m 
// AbstractFactory 

#import "BrandingFactory.h" 
#import "AcmeBrandingFactory.h" 
#import "SierraBrandingFactory.h" 


@implementation BrandingFactory 

+ (BrandingFactory *) factory:(OutputTypes)type 
{ 
    if (type == Sierra) { 
     return [[[SierraBrandingFactory alloc] init] autorelease]; 
    } 
    else if (type == Acme) 
    { 
     return [[[AcmeBrandingFactory alloc] init] autorelease]; 
    } 
    return nil; 

} 

- (UIView *) brandedView 
{ 
    return nil; 
} 

- (UIButton *) brandedMainButton 
{ 
    return nil; 
} 

- (UIToolbar *) brandedToolbar 
{ 
    return nil; 
} 

@end 

________________________________________ 

// SierraBrandingFactory.h 
// AbstractFactory 

#import <Foundation/Foundation.h> 
#import "BrandingFactory.h" 


@interface SierraBrandingFactory : BrandingFactory 
{ 

} 

- (UIView*) brandedView; 
- (UIButton*) brandedMainButton; 
- (UIToolbar*) brandedToolbar; 

@end 


// SierraBrandingFactory.m 
// AbstractFactory 

#import "SierraBrandingFactory.h" 
#import "SierraView.h" 
#import "SierraMainButton.h" 
#import "SierraToolbar.h" 

@implementation SierraBrandingFactory 

- (UIView*) brandedView 
{ 
    // returns a custom view for Sierra 
    return [[[SierraView alloc] init] autorelease]; 
} 

- (UIButton*) brandedMainButton 
{ 
    // returns a custom main button for Sierra 
    return [[[SierraMainButton alloc] init] autorelease]; 
} 

- (UIToolbar*) brandedToolbar 
{ 
    // returns a custom toolbar for Sierra 
    return [[[SierraToolbar alloc] init] autorelease]; 
} 

@end 

________________________________________ 
// AcmeBrandingFactory.h 
// AbstractFactory 


#import <Foundation/Foundation.h> 
#import "BrandingFactory.h" 


@interface AcmeBrandingFactory : BrandingFactory 
{ 

} 

- (UIView *) brandedView; 
- (UIButton *) brandedMainButton; 
- (UIToolbar *) brandedToolbar; 

@end 


// AcmeBrandingFactory.m 
// AbstractFactory 

#import "AcmeBrandingFactory.h" 
#import "AcmeView.h" 
#import "AcmeMainButton.h" 
#import "AcmeToolbar.h" 


@implementation AcmeBrandingFactory 

- (UIView *) brandedView 
{ 
    // returns a custom view for Acme 
    return [[[AcmeView alloc] init] autorelease]; 
} 

- (UIButton *) brandedMainButton 
{ 
    // returns a custom main button for Acme 
    return [[[AcmeMainButton alloc] init] autorelease]; 
} 

- (UIToolbar *) brandedToolbar 
{ 
    // returns a custom toolbar for Acme 
    return [[[AcmeToolbar alloc] init] autorelease]; 
} 

@end 
+0

Jak wskazuje PO. Te dwa wzory są * podobne *, ale nie takie same –

+0

To jest implementacja abstrakcyjnej fabryki. Ale ogólnie są bardzo podobne http://stackoverflow.com/a/2459385/1847511 –

+0

Czy możesz wyjaśnić różnicę w kilku słowach? –