Singleton Design Pattern

A singleton is an object class designed such that only one instance of that class will ever exist. This can be useful to minimize resources required (e.g., database connections) or ensure consistent data throughout an application (e.g., user preferences).

With the advent of automatic reference counting (ARC) in Objective-C, a lot of memory management has changed (for the better). The transition from manual reference counting to ARC is generally straightforward (there is even a refactoring tool in Xcode to speed the process), but some changes require a bit more work (and understanding). If you have implemented a singleton class, for example, you will see a number of errors in the ARC refactor preview.

Manual Reference Counting

I will begin with the manual reference counting approach. The general structure here is outlined in the Apple Documentation as well, but has not been updated (to the best of my knowledge) for ARC.

Listing: SomeFactory.h

@interface SomeFactory : NSObject

@property (nonatomic, retain) NSMutableArray * collection;

+ (SomeFactory *)defaultFactory;

@end

The theory here is to override any method that might result in the allocation of a new object of the singleton class. The normal memory management methods (retain, release, and retainCount) are overridden since there should always be a retain count of 1 for the Singleton object. The NSUIntegerMax value returned by the retainCount() method is designed to provide a hint that a singleton is being used.

Listing: SomeFactory.m

#import "SomeFactory.h"

static SomeFactory *defaultFactory = nil;

@implementation SomeFactory

@synthesize collection;

+ (LibraryFactory *)defaultFactory
{
   if (! defaultFactory)
   {
      defaultFactory = [[super allocWithZone:NULL] init];
   }
   return defaultFactory;
}

+ (id)allocWithZone:(NSZone *)zone
{
   return [self defaultFactory];
}

- (id)init
{
   if (defaultFactory) return defaultFactory;
   
   [super init];
   
   collection = [[NSMutableArray alloc] init];
   
   return self;
}

- (id)retain
{
   return self;
}

- (oneway void)release
{
   
}

- (NSUInteger)retainCount
{
   return NSUIntegerMax;
}

@end

In summary, you create a static instance and always return that static instance. If no instance yet exists, create it.

Automatic Reference Counting (ARC)

Under ARC, you neither implement nor call retain, release, autorelease, or retainCount. For autorelease, under some circumstances, you might create an @autoreleasepool structure. After removing forbidden methods, as well as making your singleton thread safe, you have the following.

Listing: SomeFactory.h

@interface SomeFactory : NSObject

@property (nonatomic, strong) NSMutableArray * collection;

+ (SomeFactory *)defaultFactory;

@end

Listing: SomeFactory.m

#import "SomeFactory.h"

static SomeFactory *defaultFactory = nil;

@implementation SomeFactory

@synthesize collection;

+ (SomeFactory *)defaultFactory
{
   @synchronized([SomeFactory class]) {
      if (! defaultFactory) {
         defaultFactory = [[SomeFactory alloc] init];
      }
   }
   return defaultFactory;
}

- (id)init
{
    if (self = [super init]) {
        collection = [[NSMutableArray alloc] init];
    }
    return self;
}

@end

Fluent Interfaces

A term first introduced by Martin Fowler and Eric Evans, a fluent interface is one in which a class is self-referencial wherever possible, resulting in cleaner code. Wherever possible, the Istarel Workshop Application Framework utilizes fluent interfaces.

Making your own code fluent can be astonishingly easy: simply return the current object in any method where you are modifying the state or behavior of the object.

Partial Listing: /bnr/rsrc/model/default/DefaultStudent.php

<?php

class DefaultStudent extends ORMObject
{
    ...

    function setFirstName($first_name)
    {
        $this->setValueForProperty('first_name', $first_name);
        return $this;
    }

    ...
}


?>

Using that technique, I can now write very elegant code. Notice that in the example below, I made a design choice to visually separate the save() method.

Partial Listing: /path/to/imaginary/script

<?php

$student = new Student;
$student->setFirstName('Mark')
        ->setLastName('Fenoglio')
        ->setCompany('Istarel Workshop');
$student->save();

?>

Iterator Design Pattern

The Iterator design pattern is used to elegantly retrieve the members of a collection. In PHP 5, that means implementing the Iterator interface defined in the Standard PHP Library (SPL).

In the Istarel Workshop Application Framework, two of the foundation classes are IWArray and IWDictionary, both of which are subclasses of the abstract class IWIterator. It is IWIterator that implements the Iterator interface.

Partial Listing: /fw/IWIterator.php

<?php

abstract class IWIterator implements Iterator
{
   protected $array = array();
   
   ...
   
   // methods required for the Iterator interface
   function current() { return current($this->array); }
   function next()    { return next($this->array);    }
   function key()     { return key($this->array);     }
   function valid()   { return current($this->array); }
   function rewind()  { return reset($this->array);   }
   
   ...
}

?>

Now, any time I work with either an IWArray or IWDictionary object, I can use a foreach statement to iterate across the elements in the collection.

Pseudo Listing: /adhoc/iterator.php

<?php

// Retrieve data in the form of an array
$select = new ORMSelect('category');
$categories = ORMFactory::instanceArray('category');  // returns an IWArray object

foreach ($categories as $category)
{
   // do something interesting
}

?>