Objective-C複合物件


在Objective-C中,可以在類叢集中建立子類,該類集合定義了一個嵌入在其中的類。 這些類物件是複合物件。你可能想知道什麼是類叢集,下面首先了解什麼是類叢集。

1. 類叢集

類叢集是基礎框架廣泛使用的設計模式。 類叢集在公共抽象超類下組合了許多私有具體子類。 以這種方式對類進行分組簡化了物件導向框架的公開可見體系結構,而不會降低其功能豐富性。 類叢集基於抽象工廠設計模式。

為了簡單起見,建立了一個基於輸入值處理它的單個類,而不是為類似的函式建立多個類。

例如,在NSNumber中有許多類的叢集,如charintbool等。將它們全部組合到一個類中,該類負責處理單個類中的類似操作。 NSNumber實際上將這些原始型別的值包裝到物件中。

2. 什麼是複合物件?

通過在設計的物件中嵌入私有叢集物件,建立一個複合物件。 此複合物件可以依賴於叢集物件的基本功能,僅攔截複合物件希望以某種特定方式處理的訊息。 此體系結構減少了必須編寫的程式碼量,並允許利用Foundation Framework提供的測試程式碼。

如下圖中解釋 -

複合物件必須宣告自己是叢集的抽象超類的子類。 作為子類,它必須覆蓋超類的原始方法。 它也可以覆蓋派生方法,但這不是必需的,因為派生方法通過原始方法工作。

NSArray類的count方法就是一個例子; 介入物件的覆蓋方法的實現可以實現簡單如下 -

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

在上面的例子中,嵌入物件實際上是NSArray型別。

複合物件範例

現在,為了看到一個完整的範例,請看下面給出的Apple文件中的範例。

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

執行上面範例程式碼,得到以下結果:

2018-11-28 22:03:54.124 main[3247] The value at Index 1 is Object2

在上面的例子中,可以看到驗證陣列的一個函式不允許新增會導致正常情況下崩潰的空物件。 但驗證陣列負責處理它。 類似地,驗證陣列中的每個方法都新增了除正常操作序列之外的驗證過程。