7

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

  • public cluster class only provides interface without actual implementation, other classes implement it for different cases;

  • it has some similarities with Abstract Factory pattern: when we call method +classNameWith... it depending on arguments can choose the most appropriate subclass and return it.

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?

Mikhail
  • 4,271
  • 3
  • 27
  • 39
  • 2
    You might be interested in perusing the [GNUStep version of NSNumber.m](https://github.com/gnustep/gnustep-base/blob/master/Source/NSNumber.m). – jscs Jul 27 '13 at 23:29
  • Josh Caswell, thanks for the great link! – Mikhail Jul 28 '13 at 09:10
  • I assume that you have already read [Concepts in Objective-C Programming: Class Clusters](https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html)? – David Rönnqvist Dec 10 '13 at 10:14

2 Answers2

5

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];
Wain
  • 118,658
  • 15
  • 128
  • 151
  • 1
    Moreover, the +alloc method can be overridden just like any other method. The class cluster alloc would probably return a static instance, instead of new objects being created and released every time you request a new instance. – Bored Astronaut Jul 28 '13 at 00:20
  • Bored Astronaut, yes i also thought that they override alloc method, because otherwise there will be some overhead for destruction of the allocated objects. – Mikhail Jul 28 '13 at 09:09
-2

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
Naloiko Eugene
  • 2,453
  • 1
  • 28
  • 18
  • As the OP points out. The two patterns are *similar* but not the same – David Rönnqvist Dec 10 '13 at 08:32
  • So this is the Abstract Factory implementation. But in general they are very similar http://stackoverflow.com/a/2459385/1847511 – Naloiko Eugene Dec 10 '13 at 09:00
  • Can you please explain the difference in few words? – Naloiko Eugene Dec 10 '13 at 09:05
  • The factory in a class cluster is an abstract class that produces concrete subclasses of itself. You only need to know that you are using an `NSNumber`, you don't have to know that behind the scenes you got back an instance of `NSSignedIntegerNumber` but you can still get the specific behaviour of that class. It's much more implicit since all you are doing is calling an `init` method on NSNumber and getting back a class that as is a kind of NSNumber. – David Rönnqvist Dec 10 '13 at 10:23
  • You can read more about it in [Concepts in Objective-C Programming: Class Clusters](https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/ClassClusters/ClassClusters.html). – David Rönnqvist Dec 10 '13 at 10:24