Obiekty złożone typu Objective-C

Możemy stworzyć podklasę w klastrze klas, który definiuje klasę, która osadza w niej obiekt. Te obiekty klas są obiektami złożonymi. Więc możesz się zastanawiać, co to jest klaster klas. Więc najpierw zobaczymy, co to jest klaster klas.

Klastry klas

Klastry klas to wzorzec projektowy, z którego w szerokim zakresie korzysta struktura podstawowa. Klastry klas grupują szereg prywatnych podklas konkretnych w ramach publicznej abstrakcyjnej nadklasy. Grupowanie klas w ten sposób upraszcza publicznie widoczną architekturę struktury zorientowanej obiektowo bez zmniejszania jej funkcjonalnego bogactwa. Klastry klas są oparte naabstract factory wzór projektu.

Aby to uprościć, zamiast tworzyć wiele klas dla podobnych funkcji, tworzymy jedną klasę, która zajmie się obsługą na podstawie wartości danych wejściowych.

Na przykład w NSNumber mamy wiele klastrów klas, takich jak char, int, bool i tak dalej. Grupujemy je wszystkie w jedną klasę, która zajmuje się obsługą podobnych operacji w jednej klasie. NSNumber w rzeczywistości opakowuje wartości tych typów pierwotnych w obiekty.

Co to jest obiekt złożony?

Osadzając prywatny obiekt klastra w obiekcie naszego własnego projektu, tworzymy obiekt złożony. Ten obiekt złożony może polegać na obiekcie klastra ze względu na jego podstawową funkcjonalność, przechwytując tylko komunikaty, które obiekt złożony chce obsłużyć w określony sposób. Ta architektura zmniejsza ilość kodu, który musimy napisać i pozwala wykorzystać przetestowany kod dostarczony przez Foundation Framework.

Wyjaśniono to na poniższym rysunku.

Obiekt złożony musi zadeklarować, że jest podklasą abstrakcyjnej nadklasy klastra. Jako podklasa musi przesłonić prymitywne metody nadklasy. Może również przesłonić metody pochodne, ale nie jest to konieczne, ponieważ metody pochodne działają przez metody pierwotne.

Przykładem jest metoda count klasy NSArray; implementacja metody, którą przesłania, w interweniującym obiekcie może być tak prosta, jak -

- (unsigned)count  {
   return [embeddedObject count];
}

W powyższym przykładzie osadzony obiekt jest w rzeczywistości typu NSArray.

Przykład obiektu złożonego

Teraz, aby zobaczyć pełny przykład, spójrzmy na przykład z dokumentacji Apple, który jest podany poniżej.

#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;
}

Teraz, kiedy kompilujemy i uruchamiamy program, otrzymamy następujący wynik.

2013-09-28 22:03:54.294 demo[6247] The value at Index 1 is Object2

W powyższym przykładzie widzimy, że walidacja jednej funkcji tablicy nie pozwoliłaby na dodanie pustych obiektów, co doprowadziłoby do awarii w normalnym scenariuszu. Ale nasza tablica walidacyjna dba o to. Podobnie każda metoda walidacji tablicy dodaje procesy walidacji oprócz normalnej sekwencji operacji.