在 Objective-C 中,什么是所谓的“类集群”?

我读到过 NSArray 就是这样一个东西。听起来很沉重。我桌上有7本很厚的关于 Objective-C,Cocoa 和 C 的书,没有一本提到类集群,至少我在书后面的索引里找不到。那是什么?

28161 次浏览

From Apple's docs.... In short it's a design pattern used in the Foundation framework, which is probably why it's not mentioned in ObjC books.

A class cluster is an architecture that groups a number of private, concrete subclasses under a public, abstract superclass. The grouping of classes in this way provides a simplified interface to the user, who sees only the publicly visible architecture.

The NSArray class cluster isn't "heavyweight", it's a way for any number of implementations of an array class to be used without your code knowing or caring about the particular implementation. Under the hood, there are concrete subclasses of NSArray that are appropriate to different use cases, such as large, sparse arrays, or arrays containing a specific number of elements that are known at compile time.

NSArray, NSString, and NSNumber are the class clusters you'll most often encounter.

From programming in objective c by Stephen Kochan on page 498 in the glossary, cluster:

An abstract class that groups a set of private concrete subclasses, providing a simplified interface to the user through the abstract class.

I don't know what is in the CDP that Steve referenced but basically the Objective-C Class Cluster is a construct that supports implementing the abstract Factory pattern.

The idea is simple: You want to provide a Factory (Cluster) interface that, with minimal description, manufactures and returns a specific concrete instance of a Factory Object that satisfies the behavior of the cluster family described by the Factory (Cluster) interface.

A simple concrete example: This example provides a Laugh factory that produces concrete classes of specific laughter types (e.g. Guffaw, Giggle). Pay attention to the Laugh initWithLaughter: method.

In Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2


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

In 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

Class clusters provide a single public interface to a group of concrete, private subclass implementations. An objective-c programmer uses class clusters often and rarely realizes it - and this is the whole point of a class cluster. A class cluster's job is to hide the complexity of implementation detail behind a public interface.

Many of the Foundation classes are class clusters, such as NSString, NSArray, NSDictionary, and NSNumber. When you call [NSString stringWithFormat:] the class cluster is giving you some concrete class that implements the NSString interface. It could be an NSConcreteString, NSCFString, NSFooBarString, etc. Which the class cluster gives you is based on the constructor or initializer you are calling and the arguments.

Because of this, class clusters are one of the most empowering concepts in Objective-C programming.

  • Very easy to implement
  • Easy to change the underlying implementation without changing the code that calls it.
  • Easy to provide different concrete implementations at runtime (i.e. test resources or mock objects)
  • Because of the above, easy to test and refactor

If you are coming from other languages you may be familiar with the Gang of Four patterns. Class clusters have elements of both the abstract factory and the facade patterns.

Apple's public documentation covers class clusters (and how to implement and extend them) quite extensively. Unfortunately, I have found that for many iOS developers this and other Cocoa-specific patterns are a blind spot.

Cocoa Core Competencies: Class cluster

Cocoa Fundamentals Guide: Class Clusters

Examples of how to implement your own class clusters are available on GitHub