Objective-C-Verbundobjekte
Wir können eine Unterklasse innerhalb eines Klassenclusters erstellen, die eine Klasse definiert, in die ein Objekt eingebettet ist. Diese Klassenobjekte sind zusammengesetzte Objekte. Sie fragen sich vielleicht, was ein Klassencluster ist. Wir werden also zuerst sehen, was ein Klassencluster ist.
Klassencluster
Klassencluster sind ein Entwurfsmuster, das das Foundation Framework umfassend nutzt. Klassencluster gruppieren eine Reihe privater konkreter Unterklassen unter einer öffentlichen abstrakten Oberklasse. Die Gruppierung von Klassen auf diese Weise vereinfacht die öffentlich sichtbare Architektur eines objektorientierten Frameworks, ohne dessen Funktionsreichtum zu verringern. Klassencluster basieren auf demabstract factory Entwurfsmuster.
Um es einfach zu machen, erstellen wir nicht mehrere Klassen für ähnliche Funktionen, sondern eine einzelne Klasse, deren Handhabung auf der Grundlage des Eingabewerts erfolgt.
In NSNumber gibt es beispielsweise viele Klassencluster wie char, int, bool usw. Wir gruppieren sie alle zu einer einzigen Klasse, die sich um die Abwicklung ähnlicher Vorgänge in einer einzigen Klasse kümmert. NSNumber verpackt den Wert dieser primitiven Typen tatsächlich in Objekte.
Was ist ein zusammengesetztes Objekt?
Durch Einbetten eines privaten Clusterobjekts in ein Objekt unseres eigenen Designs erstellen wir ein zusammengesetztes Objekt. Dieses zusammengesetzte Objekt kann sich für seine grundlegende Funktionalität auf das Clusterobjekt verlassen und nur Nachrichten abfangen, die das zusammengesetzte Objekt auf eine bestimmte Weise verarbeiten möchte. Diese Architektur reduziert die Menge an Code, die wir schreiben müssen, und ermöglicht es Ihnen, den getesteten Code des Foundation Framework zu nutzen.
Dies wird in der folgenden Abbildung erläutert.
Das zusammengesetzte Objekt muss sich selbst als Unterklasse der abstrakten Oberklasse des Clusters deklarieren. Als Unterklasse muss sie die primitiven Methoden der Oberklasse überschreiben. Es kann auch abgeleitete Methoden überschreiben, dies ist jedoch nicht erforderlich, da die abgeleiteten Methoden die primitiven Methoden verarbeiten.
Die Zählmethode der NSArray-Klasse ist ein Beispiel. Die Implementierung einer Methode, die das intervenierende Objekt überschreibt, kann so einfach sein wie:
- (unsigned)count {
return [embeddedObject count];
}
Im obigen Beispiel ist das eingebettete Objekt tatsächlich vom Typ NSArray.
Ein zusammengesetztes Objektbeispiel
Um ein vollständiges Beispiel zu sehen, schauen wir uns das Beispiel aus der Apple-Dokumentation an, die unten angegeben ist.
#import <Foundation/Foundation.h>
@interface ValidatingArray : NSMutableArray {
NSMutableArray *embeddedArray;
}
+ validatingArray;
- init;
- (unsigned)count;
- objectAtIndex:(unsigned)index;
- (void)addObject:object;
- (void)replaceObjectAtIndex:(unsigned)index withObject:object;
- (void)removeLastObject;
- (void)insertObject:object atIndex:(unsigned)index;
- (void)removeObjectAtIndex:(unsigned)index;
@end
@implementation ValidatingArray
- init {
self = [super init];
if (self) {
embeddedArray = [[NSMutableArray allocWithZone:[self zone]] init];
}
return self;
}
+ validatingArray {
return [[self alloc] init] ;
}
- (unsigned)count {
return [embeddedArray count];
}
- objectAtIndex:(unsigned)index {
return [embeddedArray objectAtIndex:index];
}
- (void)addObject:(id)object {
if (object != nil) {
[embeddedArray addObject:object];
}
}
- (void)replaceObjectAtIndex:(unsigned)index withObject:(id)object; {
if (index <[embeddedArray count] && object != nil) {
[embeddedArray replaceObjectAtIndex:index withObject:object];
}
}
- (void)removeLastObject; {
if ([embeddedArray count] > 0) {
[embeddedArray removeLastObject];
}
}
- (void)insertObject:(id)object atIndex:(unsigned)index; {
if (object != nil) {
[embeddedArray insertObject:object atIndex:index];
}
}
- (void)removeObjectAtIndex:(unsigned)index; {
if (index <[embeddedArray count]) {
[embeddedArray removeObjectAtIndex:index];
}
}
@end
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
ValidatingArray *validatingArray = [ValidatingArray validatingArray];
[validatingArray addObject:@"Object1"];
[validatingArray addObject:@"Object2"];
[validatingArray addObject:[NSNull null]];
[validatingArray removeObjectAtIndex:2];
NSString *aString = [validatingArray objectAtIndex:1];
NSLog(@"The value at Index 1 is %@",aString);
[pool drain];
return 0;
}
Wenn wir nun das Programm kompilieren und ausführen, erhalten wir das folgende Ergebnis.
2013-09-28 22:03:54.294 demo[6247] The value at Index 1 is Object2
Im obigen Beispiel können wir sehen, dass das Überprüfen der einen Funktion des Arrays das Hinzufügen von Nullobjekten nicht zulässt, was im normalen Szenario zum Absturz führt. Aber unser Validierungsarray kümmert sich darum. In ähnlicher Weise fügt jede Methode zum Validieren des Arrays Validierungsprozesse hinzu, abgesehen von der normalen Abfolge von Operationen.