Che cos'è esattamente un cosiddetto "Cluster di classi" in Objective-C?


91

Stavo leggendo che NSArray è proprio una cosa del genere. Sembra pesante. Ho 7 libri davvero grossi qui sulla mia scrivania su Objective-C, Cocoa e C. Nessuno di loro menziona affatto Class Cluster, almeno non riesco a trovarlo nell'Indice in fondo ai libri. Allora cos'è quello?


Oops, la prossima volta penserò di aggiungere un link per quel termine. Se avessi commentato la risposta alla tua domanda precedente, avrei risposto lì.
Georg Fritzsche

2
FWIW: recentemente (dicembre 2013) Apple ha consigliato di utilizzare Class Cluster come un modo per gestire la compatibilità con le versioni precedenti di iOS 6 durante l'utilizzo di iOS 7. Questo era su Apple Tech Talks 2013 / Berlino nella sessione "Architecting Modern Apps, Part 2". Apple ha detto che pubblicherà i video delle sessioni poco dopo l'ultimo evento (17 dicembre). Quindi forse questo aiuterà a capire i cluster di classi nel contesto effettivo delle modifiche di iOS 6/7.
brainray

Risposte:


42

Dalla documentazione di Apple ... . In breve, è un modello di progettazione utilizzato nel framework Foundation, motivo per cui probabilmente non è menzionato nei libri di ObjC.

Un cluster di classi è un'architettura che raggruppa una serie di sottoclassi private e concrete in una superclasse pubblica e astratta. Il raggruppamento delle classi in questo modo fornisce un'interfaccia semplificata all'utente, che vede solo l'architettura pubblicamente visibile.


1
roflmao. Grazie. la prossima volta andrò su google. pensato che se non è nei miei libri grassi, può essere solo sulle tue teste;)
openfrog

1
L'unica cosa che manca a questo collegamento è una spiegazione su come modificare al meglio l'implementazione per ARC.
Iperbole

193

Non so cosa ci sia nella CDP a cui ha fatto riferimento Steve, ma fondamentalmente il cluster di classi Objective-C è un costrutto che supporta l'implementazione del pattern Factory astratto .

Il idea è semplice : si desidera fornire un'interfaccia Factory (Cluster) che, con una descrizione minima, produca e restituisca una specifica istanza concreta di un Factory Object che soddisfi il comportamento della famiglia di cluster descritta dall'interfaccia Factory (Cluster).

Un semplice esempio concreto : questo esempio fornisce una fabbrica della risata che produce classi concrete di tipi di risate specifici (ad esempio Guffaw, Giggle). Presta attenzione al metodo Laugh initWithLaughter:.

In Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

@interface Laugh: NSObject {}
- (Laugh *) initWithLaughter:(NSUInteger) laughterType;
- (void) laugh;
@end

In Laugh.m:

@interface Guffaws:Laugh {}
- (void) laugh;
@end

@interface Giggles:Laugh {}
- (void) laugh;
@end

@implementation Laugh
- (Laugh *) initWithLaughter:(NSUInteger) laugherType {
    id instanceReturn=nil;
    ; // Removed for ARC [self release]
    if ( laughterType == kLaughWithGuffaw )
        instanceReturn = [[Guffaws alloc]init];
    else if( laughterType == kLaughWithGiggle )
        instanceReturn = [[Giggles alloc]init];
    else
        ; // deal with this
    return instanceReturn;
}

- (void) laugh {
    NSLog(@"Humbug");
}
@end

@implementation Guffaws
    - (void) laugh {
        NSLog(@"OH HA HA HOWAH HA HA HA");
    }
@end

@implementation Giggles
    - (void) laugh {
        NSLog(@"Tee hee");
    }
@end

24
Mentre le altre risposte erano buone fornendo collegamenti a documenti e libri, mi piace perché rende piacevole e semplice vedere come farlo effettivamente. Grazie
jamone

Questo esempio è buono ma in un tipico pattern Factory le sottoclassi sono pubbliche. In un cluster di classi le sottoclassi sono private. developer.apple.com/library/ios/documentation/general/…
maxpower

1
@ AdriàNavarro Non sono visibili all'esterno poiché dichiarati nel .m-file.
hfossli

4
(1) Quanto è sicuro liberarsi in un initmetodo e restituire qualcos'altro? Esistono esempi di codice di Apple in cui lo fanno? (2) Inoltre, presumibilmente stai creando un'istanza con codice come [[Laugh alloc] initWithLaughter:kLaughWithGiggle]. Notare come Laughviene allocato inutilmente, poiché verrà rilasciato immediatamente dopo questa chiamata. Perché farlo in questo modo quando puoi creare un metodo di classe come quello [Laugh laughWithLaughter:kLaughWithGiggle]che ti offre tutti i vantaggi delle sottoclassi private, evitando i problemi 1 e 2 sopra?
Senseful

1
@Senseful Hai ragione. Nella vita reale, +allocrestituisce una classe factory singleton che implementa i vari -initWith:metodi. I -initWith:metodi della classe factory sono quindi responsabili dell'allocazione e dell'inizializzazione di una sottoclasse concreta in base ai parametri del metodo forniti, se necessario, o in alcuni casi potrebbero non allocare nulla (come -[NSString initWithString:]). Si può provare ispezionando al valore di ritorno di +[NSString alloc], +[NSArray alloc]ecc
Darren

25

Dalla programmazione nell'obiettivo c di Stephen Kochan a pagina 498 nel glossario, cluster:

Una classe astratta che raggruppa un insieme di sottoclassi concrete private, fornendo un'interfaccia semplificata all'utente attraverso la classe astratta.


5
+1 Per la citazione di una risposta da un libro Objective-C, in particolare data la domanda originale. Anche questo è un buon libro.
Quinn Taylor

(+1) per l'ottima definizione. Il problema che ho nel chiamare questo modello "Factory" è che un nome del genere si concentra solo sulla creazione di oggetti, non sulle interazioni nascoste delle sottoclassi private gestite dalla superclasse astratta. In effetti, anche chiamare questa superclasse "astratta" potrebbe essere fuorviante in quanto è in realtà abbastanza (internamente) dipendente dalle sue sottoclassi, e quindi non è una normale classe astratta che generalmente non sa nulla delle sue sottoclassi.
devios1

18

I cluster di classi forniscono un'unica interfaccia pubblica a un gruppo di implementazioni di sottoclassi concrete e private. Un programmatore obiettivo-c usa i cluster di classi spesso e raramente se ne rende conto - e questo è il punto centrale di un cluster di classi. Il compito di un cluster di classi è nascondere la complessità dei dettagli di implementazione dietro un'interfaccia pubblica.

Molte delle classi Foundation sono cluster di classi, come NSString, NSArray, NSDictionary e NSNumber. Quando chiami [NSString stringWithFormat:]il cluster di classe ti dà qualche classe concreta che implementa l' NSStringinterfaccia. Potrebbe essere un NSConcreteString, NSCFString,NSFooBarString , ecc, che il cluster di classe dà si basa sul costruttore o di inizializzazione che si sta chiamando e gli argomenti.

Per questo motivo, i cluster di classi sono uno dei concetti più potenti nella programmazione Objective-C.

  • Molto facile da implementare
  • Facile cambiare l'implementazione sottostante senza modificare il codice che lo chiama.
  • Facile da fornire diverse implementazioni concrete in fase di esecuzione (cioè risorse di test o oggetti fittizi)
  • A causa di quanto sopra, facile da testare e refactoring

Se vieni da altre lingue potresti avere familiarità con i modelli Gang of Four. I cluster di classe hanno elementi sia della fabbrica astratta che dei modelli di facciata.

La documentazione pubblica di Apple copre i cluster di classi (e come implementarli ed estenderli) in modo abbastanza esteso. Sfortunatamente, ho scoperto che per molti sviluppatori iOS questo e altri modelli specifici di Cocoa sono un punto cieco.

Competenze fondamentali del cacao: cluster di classe

Cocoa Fundamentals Guide: Class Clusters

Esempi di come implementare i propri cluster di classi sono disponibili su GitHub


7

Il cluster di classi NSArray non è "pesante", è un modo per utilizzare un numero qualsiasi di implementazioni di una classe di array senza che il tuo codice sappia o si preoccupi della particolare implementazione. Dietro le quinte, ci sono sottoclassi concrete di NSArray che sono appropriate per diversi casi d'uso, come array grandi e sparsi o array contenenti un numero specifico di elementi noti in fase di compilazione.

NSArray, NSString e NSNumber sono i cluster di classi che incontrerai più spesso.


6
Ironia della sorte, in pratica, viene più utilizzata solo una classe concreta per cluster - NSCF {Array | String | Number} - e le modifiche all'implementazione sono interne a quella classe. Questo è per quanto ne so, comunque. Anche le istanze NSArray e NSMutableArray mostrano la stessa classe.
Chuck

1
@ Chuck - come può essere questo il caso? Se NSMutableArray e NSArray si segnalassero come la stessa classe non [myArray isKindOfClass:[NSMutableArray class]]restituirebbero YES anche se non dovrebbe?
Robert,

1
@Robert: E in effetti era così al momento del mio commento. Al giorno d'oggi Apple ha sostituito NSCFArray con __NSArrayM e __NSArrayI, quindi penso che non sia più così, ma ancora non mi sentirei a mio agio a dipendere da ciò, poiché potrebbero sempre cambiarlo di nuovo.
Chuck
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.