Class Clusters(Abstract Factory)

http://developer.apple.com/library/ios/#documentation/General/Conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html

The Class Clusters pattern presents a simple interface to a complex underlying implementation. The division of an interface between primitive and derived methods makes creating subclasses easier. Your subclass must override inherited primitives, but having done so can be sure that all derived methods that it inherits will operate properly.

The division of an interface between primitive and derived methods makes creating subclasses easier. Your subclass must override inherited primitives, but having done so can be sure that all derived methods that it inherits will operate properly.

A class’s primitive methods form the basis for its interface. For example, take the NSArray class, which declares the interface to objects that manage arrays of objects. In concept, an array stores a number of data items, each of which is accessible by index. NSArray expresses this abstract notion through its two primitive methods,count and objectAtIndex:. With these methods as a base, other methods—derived methods—can be implemented;


This pattern is usually used to shield application developers from the details of performance and storage optimizations provided by frameworks.The pattern provides a public class for use in application code, but when applications attempt to allocate instances of the public class, the framework actually provides instances of private subclasses of the public class. Frameworks use information supplied at runtime to select the appropriate private subclass on a case-by-case basis. The Class Clusters pattern is sometimes called the “Abstract Factory” pattern because the public class is abstract.This means instances of the public class itself are never created, and the public class produces instances
of other classes.

Cocoa’s implementation of class clusters relies on the Two-Stage Creation pattern.

main()
{
// First allocate
NSString *newInstance = [NSString alloc];
NSLog(@"After +alloc\npointer value:%p description:%@", newInstance,
[newInstance description]);
// Now initialize
newInstance = [newInstance initWithString:@"silly string"];
NSLog(@"After -initWithString:\npointer value:%p description:%@",
newInstance, [newInstance description]);
}

Note:

It is critical to store the value returned from the initializer because, as shown in the preceding example, the returned value may be a different object than the one that received the initializer message.The following code is an error:

// First allocate
NSString *newInstance = [NSString alloc];
// Error: newInstance is initialized but the resulting object is lost
[newInstance initWithString:@"silly string"];

Sample

abstract class

#import <Cocoa/Cocoa.h>
@interface MYClassCluster : NSObject
// initializers
- (id)initForType:(MYType)type;
- (id)initWithData:(NSData *)data;
// primitive methods here
// derived methods here
@end
#import "MYClassCluster.h"
@implementation MYClassCluster
- (id)initForType:(MYType)type
{
[self release];
self = nil;
if (/* should use MySubclassA */)
{
self = [[MYSubclassA alloc] initForType:data];
}
else if (/* should use MySubclassB */)
{
self = [[MYSubclassB alloc] initForType:data];
}
return self;
}
- (id)initWithData:(NSData *)data
{
[self release];
self = nil;
if (/* should use MySubclassA */)
{
self = [[MYSubclassA alloc] initWithData:data];
}
else if (/* should use MySubclassB */)
{
self = [[MYSubclassB alloc] initWithData:data];
}
return self;
}
// primitive methods here — all of them should raise exceptions!
// derived methods here
@end

 

 

posted on 2012-07-09 20:28  grep  阅读(260)  评论(0编辑  收藏  举报