Abstract Factory Design Pattern Objective C

Abstract Factory Design Pattern Objective C

Written By: Debasis Das (9-June-2015)

Abstract Factory Design Pattern Objective C

The Abstract Factory Design Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.

Class Cluster design pattern is also called as Abstract Factory Design Pattern.

Class Clusters provide a simple interface to a complex underlying implementation.

The Pattern provides a public class for use in the application code. When application code tries to create an instance of the public class, an instance of the private subclass is created.

Class closet groups a number of private concrete subclasses under a public abstract superclass. The abstract superclass declares methods for creating instance of its private subclasses.

Following are examples of Class Clusters in the Foundation Framework

  • NSString & NSMutableString
  • NSData & NSMutableData
  • NSDictionary & NSMutableDictionary etc

Creating Instances of the private concrete subclasses

The abstract superclass in a class cluster declares methods for creating instances of its private subclasses. It is the responsibility of the abstract superclass to help decide what concrete subclass must be instantiated based on a runtime parameter.

Note: Developers are not responsible for releasing the objects returned by factory methods, thus the designer of the Class Clusters should take care of memory management.

Class Clusters with Multiple Public Super Classes

NSArray and NSMutableArray are examples of two abstract public class that declare the interface for the cluster.

Creating a true subclass of the Class Cluster

  • Be a subclass of the clusters abstract superclass
  • Declare its own storage
  • Override all initializers
  • Override  superclass’s primitive methods (Any method that accesses the object’s instance variables)

Sample Code of Abstract Factory Design Pattern / Class Cluster Design Pattern

//  KSStorage.h
//  FactoryDesignPattern
//  Created by Debasis Das on 6/9/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.

#import <Foundation/Foundation.h>

//Here we are creating an enum with only two possible values 
typedef NS_ENUM(NSInteger, DataType) {
    FileStorageDataType,
    DatabaseStorageDataType,
};

//We are defining a Protocol with 2 required methods that must be implemented by any class which wants to handle data storage
@protocol KSStorageProtocol 
@required
    -(void)saveData;
    -(id)initWithData:(NSData *)data;
@end

@interface KSStorage : NSObject <KSStorageProtocol>
-(id)initWithData:(NSData *)data type:(DataType)dataType;
@end
//  KSStorage.m
//  FactoryDesignPattern
//  Created by Debasis Das on 6/9/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.

#import "KSStorage.h"

//Here we will declare and implement 2 Private Subclasses of KSStorageClass called as FileStorage and DatabaseStorage. These 2 classes will not be visible to classes outside and cannot be imported.

@interface FileStorage : KSStorage
@property (nonatomic,strong) NSURL  *storageURL; //The FileStorage uses a URL to write the data into
@property (nonatomic,strong) NSData *data;

@end

@interface DatabaseStorage : KSStorage
@property (nonatomic,strong) NSDictionary  *dbConnectionInformationDictionary;
@property (nonatomic,strong) NSData *data;

@end

@implementation KSStorage
//Based on the DataType it is decided if FileStorage or DatabaseStorage class should be instantiated
-(id)initWithData:(NSData *)data type:(DataType)dataType{
    self = nil;
    if (dataType == FileStorageDataType){
        self = [[FileStorage alloc] initWithData:data];
    }
    else if (dataType == DatabaseStorageDataType){
        self = [[DatabaseStorage alloc] initWithData:data];
    }
    return self;
}

//Ensuring below that the saveData and initWithData method must be implemented by the private subclasses
-(void)saveData{
    [NSException raise:NSInternalInconsistencyException
                format:@"You have not implemented %@ in %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])];
}

-(id)initWithData:(NSData *)data{
    [NSException raise:NSInternalInconsistencyException
                format:@"You have not implemented %@ in %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])];
    return nil;
}

@end


@implementation FileStorage

-(id)initWithData:(NSData *)data{
    self.data = data;
    self.storageURL = [NSURL URLWithString:@"file:///Users/debasisdas/Knowstack/SampleData.txt"];
    return self;
}

-(void)saveData{
    NSLog(@"data is %@",self.data);
    NSLog(@"Now store it to stated URL %@",self.storageURL);
}
@end


@implementation DatabaseStorage

-(id)initWithData:(NSData *)data{
    self.data = data;
    self.dbConnectionInformationDictionary = @{@"connection":@"xyz.domain.com",@"port":@"8080",@"password":@"*******"};
    return self;
}

-(void)saveData
{
    NSLog(@"data is %@",self.data);
    NSLog(@"Now store it to stated URL %@",self.dbConnectionInformationDictionary);

}
@end

Abstract Factory Design Pattern – Sample Testing Code

    NSString *sampleString = @"This is a sample string";
    NSData *data = [sampleString dataUsingEncoding:NSUTF8StringEncoding];
    KSStorage *storage1 = [[KSStorage alloc] initWithData:data type:FileStorageDataType];
    NSLog(@"storage1 %@",storage1);
    if ([storage1 respondsToSelector:@selector(saveData)]){
        [storage1 saveData];
    }

    KSStorage *storage2 = [[KSStorage alloc] initWithData:data type:DatabaseStorageDataType];
    NSLog(@"storage2 %@",storage2);
    if ([storage2 respondsToSelector:@selector(saveData)]){
        [storage2 saveData];
    }

Output


2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] storage1 <FileStorage: 0x6080000220a0 >
2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] data is <54686973 20697320 61207361 6d706c65 20737472 696e67 >
2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] Now store it to stated URL file:///Users/debasisdas/Knowstack/SampleData.txt
2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] storage2 <DatabaseStorage: 0x6080000220c0 >
2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] data is <54686973 20697320 61207361 6d706c65 20737472 696e67 >
2015-06-09 21:55:14.552 FactoryDesignPattern[49079:2652330] Now store it to stated database {
    connection = "xyz.domain.com";
    password = "*******";
    port = 8080;
}

Download the sample code from here Abstract Factory Design Pattern – Objective C Sample Code

Posted in Cocoa, Design Pattern, Objective C Tagged with: , , , , ,
One comment on “Abstract Factory Design Pattern Objective C
  1. Debasis Das says:

    sorry about the delay in responding.

    first alloc is for allocating the KSStorage class and based on the passed type an internal storage is created.
    To use the KSStorage Class we are creating an object of KSStorage and when we pass a storage type to it, it internally decides which private class to initialize
    The above sample code is just fine

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Recent Posts


Hit Counter provided by technology news