Учебники

Objective-C Композитные объекты

Мы можем создать подкласс в кластере классов, который определяет класс, который встраивает в него объект. Эти объекты класса являются составными объектами. Так что вам может быть интересно, что такое кластер классов. Итак, сначала мы увидим, что такое кластер классов.

Кластеры классов

Кластеры классов – это шаблон проектирования, который основополагающая среда широко использует. Кластеры классов объединяют несколько частных конкретных подклассов в открытый абстрактный суперкласс. Группирование классов таким образом упрощает общедоступную архитектуру объектно-ориентированной среды, не уменьшая ее функциональное богатство. Кластеры классов основаны на абстрактном шаблоне проектирования фабрики .

Чтобы упростить задачу, вместо создания нескольких классов для похожих функций мы создадим один класс, который позаботится о его обработке на основе значения ввода.

Например, в NSNumber у нас есть много кластеров классов, таких как char, int, bool и так далее. Мы группируем их все в один класс, который заботится об обработке подобных операций в одном классе. NSNumber фактически оборачивает значение этих примитивных типов в объекты.

Что такое составной объект?

Встраивая объект частного кластера в объект нашего собственного дизайна, мы создаем составной объект. Этот составной объект может полагаться на кластерный объект для его основной функциональности, перехватывая только те сообщения, которые составной объект хочет обработать определенным образом. Эта архитектура уменьшает объем кода, который мы должны написать, и позволяет вам использовать протестированный код, предоставляемый Foundation Framework.

Это объясняется на следующем рисунке.

Objective-C Композитные объекты

Составной объект должен объявить себя подклассом абстрактного суперкласса кластера. Как подкласс, он должен переопределять примитивные методы суперкласса. Он также может переопределять производные методы, но это не обязательно, потому что производные методы работают через примитивные.

Метод count класса NSArray является примером; реализация метода объекта, который он переопределяет, может быть настолько простой, как:

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

В приведенном выше примере встроенный объект на самом деле имеет тип NSArray.

Пример составного объекта

Теперь, чтобы увидеть полный пример, давайте посмотрим на пример из документации Apple, которая приведена ниже.

Live Demo

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

Теперь, когда мы скомпилируем и запустим программу, мы получим следующий результат.

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

В приведенном выше примере мы видим, что проверка одной функции массива не позволяет добавлять нулевые объекты, что приведет к сбою в обычном сценарии. Но наш проверяющий массив позаботится об этом. Точно так же каждый метод в проверяющем массиве добавляет проверяющие процессы помимо обычной последовательности операций.