Mikhail
Mikhail

Reputation: 4311

Objective-C and Class Cluster pattern

I have read some information about Class Cluster pattern, and understood next:

For example, +[NSNumber numberWithDouble:1.0], will return implementation for storing double values.

But what i didn't understand: how works -init... methods of public cluster class: [[NSNumber alloc] initWithDouble:1.0], as after calling alloc it already allocates instance of NSNumber, not it's subclass.

So, can somebody explain how actually works alloc-init methods of public cluster class, and when concrete subclass instantiated and returned?

Upvotes: 7

Views: 1462

Answers (2)

Naloiko Eugene
Naloiko Eugene

Reputation: 2626

Here is the Abstract factory implementation for Objective C.

// Usage
    BrandingFactory * factory = [BrandingFactory factory:Sierra];

    UIView * view = [factory brandedView];

    UIButton * button = [factory brandedMainButton];

    UIToolbar * toolbar = [factory brandedToolbar];
____________________________________________
//  BrandingFactory.h
//  AbstractFactory

#import <Foundation/Foundation.h>

typedef enum ouputTypes {
    Acme,
    Sierra
} OutputTypes;

@interface BrandingFactory : NSObject 
{

}

+ (BrandingFactory *) factory: (OutputTypes)type;

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end

___________________________________________________

//  BrandingFactory.m
//  AbstractFactory

#import "BrandingFactory.h"
#import "AcmeBrandingFactory.h"
#import "SierraBrandingFactory.h"


@implementation BrandingFactory

+ (BrandingFactory *) factory:(OutputTypes)type
{
    if (type == Sierra) {
        return [[[SierraBrandingFactory alloc] init] autorelease];
    }
    else if (type == Acme)
    {
        return [[[AcmeBrandingFactory alloc] init] autorelease];
    }
    return nil;

}

- (UIView *) brandedView
{
    return nil;
}

- (UIButton *) brandedMainButton
{
    return nil;
}

- (UIToolbar *) brandedToolbar
{
    return nil;
}

@end

________________________________________

//  SierraBrandingFactory.h
//  AbstractFactory

#import <Foundation/Foundation.h>
#import "BrandingFactory.h"


@interface SierraBrandingFactory : BrandingFactory
{

}

- (UIView*) brandedView;
- (UIButton*) brandedMainButton;
- (UIToolbar*) brandedToolbar;

@end


//  SierraBrandingFactory.m
//  AbstractFactory

#import "SierraBrandingFactory.h"
#import "SierraView.h"
#import "SierraMainButton.h"
#import "SierraToolbar.h"

@implementation SierraBrandingFactory

- (UIView*) brandedView
{
    // returns a custom view for Sierra
    return [[[SierraView alloc] init] autorelease];
}

- (UIButton*) brandedMainButton
{
    // returns a custom main button for Sierra
    return [[[SierraMainButton alloc] init] autorelease];
}

- (UIToolbar*) brandedToolbar
{
    // returns a custom toolbar for Sierra
    return [[[SierraToolbar alloc] init] autorelease];
}

@end

________________________________________
//  AcmeBrandingFactory.h
//  AbstractFactory


#import <Foundation/Foundation.h>
#import "BrandingFactory.h"


@interface AcmeBrandingFactory : BrandingFactory
{

}

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end


//  AcmeBrandingFactory.m
//  AbstractFactory

#import "AcmeBrandingFactory.h"
#import "AcmeView.h"
#import "AcmeMainButton.h"
#import "AcmeToolbar.h"


@implementation AcmeBrandingFactory

- (UIView *) brandedView
{
    // returns a custom view for Acme
    return [[[AcmeView alloc] init] autorelease];
}

- (UIButton *) brandedMainButton
{
    // returns a custom main button for Acme
    return [[[AcmeMainButton alloc] init] autorelease];
}

- (UIToolbar *) brandedToolbar
{
    // returns a custom toolbar for Acme
    return [[[AcmeToolbar alloc] init] autorelease];
}

@end

Upvotes: -2

Wain
Wain

Reputation: 119021

Basically, the instance you have allocated could be thrown away and replaced with a different instance. Technically, this isn't specific to class clusters and that is why when you call super in any init method you need to set the result as self:

self = [super init];

Upvotes: 5

Related Questions