Qu'est-ce qu'un soi-disant «cluster de classes» en Objective-C?

91

Je lisais que NSArray est une telle chose. Cela semble lourd. J'ai 7 livres vraiment gros sur mon bureau sur Objective-C, Cocoa et C. Aucun d'eux ne mentionne le cluster de classes du tout, du moins je ne le trouve pas dans l'index à la fin des livres. Alors qu'est-ce que c'est?

openfrog
la source
Oups, la prochaine fois, je penserai à ajouter un lien pour ce terme. Si vous aviez commenté la réponse à votre question précédente, j'y aurais répondu.
Georg Fritzsche
2
FWIW: récemment (décembre 2013), Apple a recommandé d'utiliser les clusters de classes comme un moyen de gérer la rétrocompatibilité avec iOS 6 tout en utilisant iOS 7. C'était sur Apple Tech Talks 2013 / Berlin dans la session «Architecting Modern Apps, Part 2». Apple a déclaré qu'il publierait des vidéos des sessions peu de temps après le dernier événement (17 décembre). Alors peut-être que cela aidera à comprendre les clusters de classes dans le contexte réel des changements iOS 6/7.
brainray

Réponses:

42

A partir de docs d'Apple ... . En bref, c'est un modèle de conception utilisé dans le framework Foundation, ce qui explique probablement pourquoi il n'est pas mentionné dans les livres ObjC.

Un cluster de classes est une architecture qui regroupe un certain nombre de sous-classes privées et concrètes sous une superclasse publique et abstraite. Le regroupement de classes de cette manière fournit une interface simplifiée à l'utilisateur, qui ne voit que l'architecture visible publiquement.

écho
la source
1
roflmao. Merci. va google la prochaine fois. pensé que si ce n'est pas dans mes gros livres, cela ne peut être que sur vos têtes;)
openfrog
1
La seule chose qui manque à ce lien est une explication sur la meilleure façon de modifier l'implémentation pour ARC.
Hyperbole
193

Je ne sais pas ce qu'il y a dans le CDP auquel Steve a fait référence, mais fondamentalement, le cluster de classes Objective-C est une construction qui prend en charge l'implémentation du modèle abstrait Factory .

L' idée est simple : vous souhaitez fournir une interface Factory (Cluster) qui, avec une description minimale, fabrique et renvoie une instance concrète spécifique d'un objet Factory qui satisfait le comportement de la famille de clusters décrite par l'interface Factory (Cluster).

Un exemple concret simple : Cet exemple fournit une usine de rire qui produit des classes concrètes de types de rire spécifiques (par exemple Guffaw, Giggle). Faites attention à la méthode Laugh initWithLaughter:.

Dans Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

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

Dans 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
Frank C.
la source
24
Bien que les autres réponses aient été bonnes en fournissant des liens vers des documents et des livres, j'aime cela parce que cela rend agréable et simple de voir comment faire cela. Merci
jamone
Cet exemple est bon mais dans un modèle Factory typique, les sous-classes sont publiques. Dans un cluster de classes, les sous-classes sont privées. developer.apple.com/library/ios/documentation/general/…
maxpower
1
@ AdriàNavarro Ils ne sont pas visibles de l'extérieur puisqu'ils sont déclarés dans le .m-file.
hfossli
4
(1) Est-il sûr de se libérer dans une initméthode et de retourner quelque chose d'autre? Y a-t-il des exemples de code d'Apple où ils font cela? (2) En outre, vous créez probablement une instance avec un code tel que [[Laugh alloc] initWithLaughter:kLaughWithGiggle]. Remarquez comment Laughest alloué inutilement, car il sera libéré immédiatement après cet appel. Pourquoi faire de cette façon quand vous pouvez créer une méthode de classe telle que celle [Laugh laughWithLaughter:kLaughWithGiggle]qui vous donne tous les avantages des sous-classes privées, tout en évitant les problèmes 1 et 2 ci-dessus?
Senseful
1
@Senseful Vous avez raison. Dans la vraie vie, +allocrenvoie une classe d'usine singleton qui implémente les différentes -initWith:méthodes. Les -initWith:méthodes de la classe d'usine sont alors responsables de l'allocation et de l'initialisation d'une sous-classe concrète basée sur les paramètres de méthode donnés, si nécessaire, ou dans certains cas, peuvent ne rien allouer du tout (comme -[NSString initWithString:]). Vous pouvez l' essayer en examinant à la valeur de retour +[NSString alloc], +[NSArray alloc]etc.
Darren
25

De la programmation en objectif c par Stephen Kochan à la page 498 du glossaire, cluster:

Une classe abstraite qui regroupe un ensemble de sous-classes concrètes privées, fournissant une interface simplifiée à l'utilisateur via la classe abstraite.

t011phr33
la source
5
+1 Pour citer une réponse d'un livre Objective-C, en particulier compte tenu de la question d'origine C'est aussi un bon livre.
Quinn Taylor
(+1) pour l'excellente définition. Le problème que j'ai en appelant cela un modèle "Factory" est qu'un tel nom se concentre uniquement sur la création d'objets, pas sur les interactions sous le capot des sous-classes privées gérées par la superclasse abstraite. En effet, même appeler cette superclasse "abstraite" pourrait être trompeur car elle dépend en fait (en interne) de ses propres sous-classes, et n'est donc pas une classe abstraite normale qui ne sait généralement rien de ses sous-classes.
devios1
18

Les clusters de classes fournissent une interface publique unique à un groupe d'implémentations de sous-classes privées et concrètes. Un programmeur objective-c utilise souvent des clusters de classes et s'en rend rarement compte - et c'est tout l'intérêt d'un cluster de classes. Le travail d'un cluster de classes est de cacher la complexité des détails d'implémentation derrière une interface publique.

La plupart des classes Foundation sont des clusters de classes, tels que NSString, NSArray, NSDictionary et NSNumber. Lorsque vous appelez [NSString stringWithFormat:]le cluster de classes, cela vous donne une classe concrète qui implémente l' NSStringinterface. Il pourrait être un NSConcreteString, NSCFString, NSFooBarString, etc. Ce qui le cluster de classe vous donne est basé sur le constructeur ou initialiseur vous appelez et les arguments.

Pour cette raison, les clusters de classes sont l'un des concepts les plus puissants de la programmation Objective-C.

  • Très facile à mettre en œuvre
  • Facile à changer l'implémentation sous-jacente sans changer le code qui l'appelle.
  • Facile à fournir différentes implémentations concrètes au moment de l'exécution (c'est-à-dire des ressources de test ou des objets factices)
  • En raison de ce qui précède, facile à tester et à refactoriser

Si vous venez d'autres langues, vous connaissez peut-être les modèles Gang of Four. Les clusters de classes ont des éléments à la fois de l'usine abstraite et des motifs de façade.

La documentation publique d'Apple couvre assez largement les clusters de classes (et comment les implémenter et les étendre). Malheureusement, j'ai trouvé que pour de nombreux développeurs iOS, cela et d'autres modèles spécifiques à Cocoa sont un angle mort.

Compétences principales de Cocoa: cluster de classes

Guide des fondamentaux du cacao: Clusters de classes

Des exemples d'implémentation de vos propres clusters de classes sont disponibles sur GitHub

apaiser
la source
7

Le cluster de classes NSArray n'est pas "lourd", c'est un moyen pour n'importe quel nombre d'implémentations d'une classe de tableau à utiliser sans que votre code connaisse ou se soucie de l'implémentation particulière. Sous le capot, il existe des sous-classes concrètes de NSArray qui conviennent à différents cas d'utilisation, tels que des tableaux volumineux et épars ou des tableaux contenant un nombre spécifique d'éléments connus au moment de la compilation.

NSArray, NSString et NSNumber sont les clusters de classes que vous rencontrerez le plus souvent.

NSResponder
la source
6
Ironiquement, en pratique, une seule classe concrète par cluster est jamais utilisée - NSCF {Array | String | Number} - et les changements d'implémentation sont internes à cette classe. C'est pour autant que je sache, de toute façon. Même les instances NSArray et NSMutableArray affichent la même classe.
Chuck
1
@Chuck - comment cela peut-il être le cas? Si un NSMutableArray et NSArray se rapportaient comme étant la même classe, ne [myArray isKindOfClass:[NSMutableArray class]]renverrait pas YES même si ce n'est pas le cas?
Robert
1
@Robert: Et c'était effectivement le cas au moment de mon commentaire. De nos jours, Apple a remplacé NSCFArray par __NSArrayM et __NSArrayI, donc je pense que ce n'est plus le cas, mais je ne me sentirais toujours pas à l'aise avec cela, car ils pourraient toujours le changer à nouveau.
Chuck