<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bob McCune &#187; Technology</title>
	<atom:link href="http://www.bobmccune.com/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bobmccune.com</link>
	<description>iOS and Java Design, Development, Training, and Mentoring</description>
	<lastBuildDate>Thu, 15 Sep 2011 06:55:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Automagic Factories in Objective-C</title>
		<link>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/</link>
		<comments>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/#comments</comments>
		<pubDate>Fri, 08 Apr 2011 14:00:39 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=374</guid>
		<description><![CDATA[The Factory pattern is a frequently used creational pattern to help abstract the creation of an object from its clients. Although there are a few specializations of this pattern I&#8217;ll focus on the most commonly used approach and then look at how we can leverage the Objective-C Runtime to make this solution more robust. Let&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p></p><p><img src="http://www.bobmccune.com/wp-content/uploads/2011/04/magic_hat.png" alt="" title="magic_hat" width="150" height="150" class="alignright size-full wp-image-377" />The <a href="http://www.oodesign.com/factory-pattern.html">Factory</a> pattern is a frequently used <a href="http://www.oodesign.com/creational-patterns/">creational pattern</a> to help abstract the creation of an object from its clients.  Although there are a few specializations of this pattern I&#8217;ll focus on the most commonly used approach and then look at how we can leverage the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html">Objective-C Runtime</a> to make this solution more robust.</p>
<p>Let&#8217;s begin by creating a simple command-line app that creates <code>Animal</code> objects and gets them to speak on command.  The various animal objects will all inherit from the <em>abstract</em> <code>Animal</code> class.<br />
<span id="more-374"></span></p>
<pre>
@interface Animal : NSObject {
}

- (void)speak;
- (NSString *)key;

@end
</pre>
<pre>
@implementation Animal

- (void)speak {
    NSAssert(NO, @"The 'speak' method must be implemented by subclass.");
}

- (NSString *)key {
    // Animal instances will be 'keyed' by their lower case class name
    // Overly simplistic, but will suffice for now
    return [NSStringFromClass([self class]) lowercaseString];
}

@end
</pre>
<p>With the abstract base class complete let&#8217;s create a couple concrete <code>Animal</code> implementations:</p>
<pre>
@implementation Cat
- (void)speak {
    NSLog(@"Meow, Meow...");
}
@end
</pre>
<pre>
@implementation Dog
- (void)speak {
    NSLog(@"Bark, Bark...");
}
@end
</pre>
<p>Our <code>Cat</code> &amp; <code>Dog</code> objects are ready to go so let&#8217;s integrate them into our app and get them to speak.</p>
<pre>
int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Animal *cat = [[Cat alloc] init];
    [cat speak];
    [cat release];

    Animal *dog = [[Dog alloc] init];
    [dog speak];
    [dog release];

    [pool drain];
    return 0;
}
</pre>
<p>Running this app will produce the following console output:</p>
<pre>
Meow, Meow...
Bark, Bark...
</pre>
<p>This works as we&#8217;d expect, but the main problem with using the <code>Cat</code> and <code>Dog</code> classes this way is <em>coupling</em>.  Even though we&#8217;ve defined our variables as abstract <code>Animal</code> types we&#8217;re still coupled to the specific subtypes.  This means we can&#8217;t modify our <code>Animal</code> types or evolve their creation without impacting our client code.  This may seem like a trivial matter in this example, but these design decisions can have major impacts on real-world applications.  Let&#8217;s avoid some of the potential ripple effects by introducing a <em>factory</em>.</p>
<h2>Creating Animals</h2>
<p>We&#8217;ll begin by moving the object creation responsibilities from our client to a new object called <code>AnimalFactory</code>.  This factory, as you may have guessed, will be responsible for creating and vending instances of <code>Animal</code>.  A simple, but common implementation of this could be defined as follows:</p>
<pre>
@implementation AnimalFactory

+ (AnimalFactory *)factory {
    return [[[[self class] alloc] init] autorelease];
}

- (Animal *)animalForKey:(NSString *)animalKey {
    Animal *animal = nil;
    if ([animalKey isEqualToString:@"dog"]) {
        animal = [[Dog alloc] init];
    } else if ([animalKey isEqualToString:@"cat"]) {
        animal = [[Cat alloc] init];
    } else {
        NSAssert(NO, @"No Animal found for key:'%@'", animalKey);
    }
    return [animal autorelease];
}

@end
</pre>
<p>The <code>AnimalFactory</code> will determine which instance to create based on the argument passed to the <code>animalForKey:</code> method.  It creates the appropriate instance and returns an <em>autoreleased</em> version of it to the client.  To use this new factory in our client we can make the following changes:</p>
<pre>
AnimalFactory *factory = [AnimalFactory factory];

[[factory animalForKey:@"cat"] speak];
[[factory animalForKey:@"dog"] speak];
</pre>
<p>If you were to run this example again you would see the same output as before, but the introduction of this factory has helped us resolve two specific limitations in our previous implementation:</p>
<ol>
<li>The client is no longer coupled to a particular instance of <code>Animal</code>.  As our requirements change the factory can return alternate instances (<code>FatCat</code>, <code>HotDog</code>, etc.) without impacting our client code.</li>
<li>The client is no longer in the business of object creation which means <em>how</em> an animal is instantiated is no longer its concern.  Additionally, by returning an autoreleased instance we don&#8217;t unnecessarily force memory management responsibilities onto the client.</li>
</ol>
<p>One outstanding problem we have is with the factory itself.  Although the client is better decoupled from the specific types and their creation, the factory itself is not.  Every time we add a new animal to the app we additionally have to make modifications to the factory.  </p>
<blockquote><p>
    <span style="foreground-color: darkGray"><em>[Informercial Guy Voice]</em></span>&nbsp;&nbsp;<strong>There&#8217;s got to be a better way!</strong>
</p></blockquote>
<h2>Enter the Objective-C Runtime</h2>
<p>
Objective-C is a dynamic language where many decisions are deferred until runtime.  This deferment allows for some of the more interesting capabilities of the language and is made possible through the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html">Objective-C Runtime</a>.  Although you can successfully use Objective-C without having much awareness of the runtime, understanding how to interact with it can open up some interesting new possibilities.  </p>
<p>
It would be nice if our <code>AnimalFactory</code> could automatically find and dispense all instances of <code>Animal</code> without us having to continuously modify the factory.  Thanks to the runtime, it can.</p>
<h2>Automagic Factories</h2>
<p>Let&#8217;s begin by creating a utility class called <code>RuntimeUtils</code> containing a method to allow us to dynamically find all instances of a particular type.  This method will be implemented as follows:</p>
<pre>
+ (NSArray *)classStringsForClassesOfType:(Class)filterType {

    int numClasses = 0, newNumClasses = objc_getClassList(NULL, 0);
    Class *classList = NULL;

    while (numClasses < newNumClasses) {
        numClasses = newNumClasses;
        classList = realloc(classList, sizeof(Class) * numClasses);
        newNumClasses = objc_getClassList(classList, numClasses);
    }

    NSMutableArray *classesArray = [NSMutableArray array];

    for (int i = 0; i < numClasses; i++) {
        Class superClass = classList[i];
        do {
            // recursively walk the inheritance hierarchy
            superClass = class_getSuperclass(superClass);
            if (superClass == filterType) {
                [classesArray addObject:NSStringFromClass(classList[i])];
                break;
            }
        } while (superClass);
    }

    free(classList);

    return classesArray;
}
</pre>
<p>This method makes use of two functions defined in <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html"><code>&lt;objc/runtime.h&gt;</code></a>:</p>
<ol>
<li><code>objc_getClassList</code> - This function returns a list of all classes registered with the app.  We'll loop through this list and then filter its results.</li>
<li><code>class_getSuperclass</code> - Returns the superclass of a class.  We recursively walk the inheritance hierarchy of each class to determine if it's a descendant of <code>Animal</code>.  If so, we add its class string to our array.
</ol>
<p>With our <code>RuntimeUtils</code> class now ready, let's go back and revisit the implementation of our factory object.</p>
<h2>Implementing the Magic</h2>
<p>We'll change the implementation of our factory class to leverage this new <code>RuntimeUtils</code> class.  We'll start by implementing the <code>init</code> method.</p>
<pre>
- (id)init {
  if ((self = [super init])) {
    NSArray *animalClassStrings = [RuntimeUtils classStringsForClassesOfType:[Animal class]];
    animals = [[NSMutableDictionary alloc] initWithCapacity:[animalClassStrings count]];
      for (id classString in animalClassStrings) {
        Class animClass = NSClassFromString(classString);
        Animal *animal = [[animClass alloc] init];
        [animals setObject:animal forKey:[animal key]];
        [animal release];
      }
    }
  return self;
}
</pre>
<p>Our <code>init</code> implementation starts by finding all the class strings for the classes extending <code>Animal</code>.  We iterate through the results creating an instance of each class and storing its pointer in the <code>animals</code> dictionary.  With the <code>init</code> method complete let's modify the <code>animalForKey:</code> method.</p>
<pre>
- (Animal *)animalForKey:(NSString *)animalKey {
    Animal *animal = [animals objectForKey:animalKey];
    NSAssert(animal, @"No animal found.  Invalid 'animalType' specified?");
    return animal;
}
</pre>
<p>We now have a greatly simplified <code>animalForKey:</code> method.  Gone are the <code>if/else</code> or <code>switch</code> statements you'd typically see in a factory method.  Instead, we have a simple, generic execution path regardless of the number of animals we add to the application.</p>
<p>To see the benefits of our revamped <code>AnimalFactory</code>, let's make a couple additions to our animal kingdom.</p>
<pre>
@implementation Monkey
- (void)speak {
    NSLog(@"Ooo, Ooo, Eee, Eee");
}
@end
</pre>
<pre>
@implementation Bird
- (void)speak {
    NSLog(@"Tweet, tweet");
}
@end
</pre>
<p>We can go back to our client code and make the following changes:</p>
<pre>
[[factory animalForKey:@"dog"] speak];
[[factory animalForKey:@"cat"] speak];
<strong>[[factory animalForKey:@"monkey"] speak];</strong>
<strong>[[factory animalForKey:@"bird"] speak];</strong>
</pre>
<p>If you run the application again you'll see the new <code>Monkey</code> and <code>Bird</code> instances were automatically registered with the factory without any additional changes!  Winning!</p>
<h2>Conclusion</h2>
<p>Although this was clearly a contrived example, it hopefully illustrates how leveraging the Objective-C Runtime can result in significantly more flexible factory objects.  Some simple modifications could be made to this approach to provide for lazy instantiation or handle more complex object creation.  In a future post I'll provide a more concrete example of how this strategy can be put to good use in a real-world application.</p>
<h2>Resources</h2>
<p><a href="http://www.bobmccune.com/wp-content/uploads/2011/04/AutomagicFactories.zip">Sample Code</a></br><br />
<a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html">Objective-C Runtime Reference</a></br><br />
<a href="http://cocoasamurai.blogspot.com/2010/01/understanding-objective-c-runtime.html">Understanding the Objective-C Runtime</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2011/04/08/automagic-factories-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>CocoaHeads: We&#039;re Off To a Great Start!</title>
		<link>http://www.bobmccune.com/2008/06/16/cocoaheads-were-off-to-a-great-start/</link>
		<comments>http://www.bobmccune.com/2008/06/16/cocoaheads-were-off-to-a-great-start/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 17:48:25 +0000</pubDate>
		<dc:creator>Bob McCune</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.bobmccune.com/?p=80</guid>
		<description><![CDATA[I would really like to thank all of you who attended the inaugural CocoaHeads meeting last Thursday. I couldn&#8217;t have been happier with the turnout and participation from everyone. It was also nice to finally meet many of you with whom I&#8217;ve traded emails over the past couple of months. We had a great mix [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I would really like to thank all of you who attended the inaugural CocoaHeads meeting last Thursday.  I couldn&#8217;t have been happier with the turnout and participation from everyone.  It was also nice to finally meet many of you with whom I&#8217;ve traded emails over the past couple of months.</p>
<p>We had a great mix of people at the first meeting ranging from experienced Cocoa, NeXT, and Mac OS developers to those experienced with other languages/platforms, but just starting out with Cocoa and CocoaTouch, to those just starting their journey into software development.  This should make for a very interesting group!</p>
<p><a href="http://anatkinson.com/">Andy Atkinson</a> started polling at the end of the meeting for what technical topics people would like to see at upcoming meetings.  I think the final ones we settled on were:</p>
<ul>
<li><span style="text-decoration:underline">Intro to iPhone Development</span></li>
<li><span style="text-decoration:underline">Overview of RubyCocoa</span></li>
<li><span style="text-decoration:underline">Unit Testing with OCUnit</span></li>
<li><span style="text-decoration:underline">NSFoundation Framework</span></li>
<li><span style="text-decoration:underline">Intro to CoreGraphics</span></li>
<li><span style="text-decoration:underline">Overview of Instruments</span></li>
</ul>
<p>Some additional ones I would personally like to see covered (even if I&#8217;m the one covering them) are overviews of <span style="text-decoration:underline">Core Data</span> and <span style="text-decoration:underline">Core Animation</span>.<br />
Let me know if there are any others that I missed and should be tracking.</p>
<p><a href="http://www.rjohnshields.com/blog/">John Shields</a> wrote up a nice summary of <a href="http://rjohnshields.com/blog/?p=50">his thoughts</a> on the meeting that you should check out.</p>
<p>I&#8217;d like to thank <a href="http://heymansoftware.com/">Bill Heyman</a> and <a href="http://damonallison.com/">Damon Allison</a> for showing us some very cool demos of what they are doing over at <a href="http://codemorphic.net/">CodeMorphic</a>.  Good luck guys and keep &#8216;em coming!  If anyone else would be interested in demoing their products or projects, just let me know and I&#8217;ll find you a slot.</p>
<p>I&#8217;d also like to thank everyone at Synergy Information Services.  Their facilities are great and they also have a larger room available should we need it.  We all also greatly appreciated the pizza and soda!</p>
<p>Vlad will be posting the <span style="text-decoration:underline">Getting Started with Cocoa</span> presentation and sample code to the website.  Keep an eye out at <a href="http://www.synfoserv.com/index.php?option=com_content&#038;view=article&#038;id=73&#038;Itemid=102">Synergy&#8217;s CocoaHeads Page</a> over the next few days if you&#8217;d like to download that content.</p>
<p>BTW, if you are interested in understanding the history of Cocoa and Mac OS X, I&#8217;d recommend checking out <a href="http://www.shawcomputing.net/">David Shaw&#8217;s website</a>.  He has a wealth of information on NeXT, Rhapsody, and Apple that many of you would find very interesting.  Great job David!</p>
<p>As I mentioned the other night I&#8217;ll be giving a presentation on Object-C 2.0 at the July meeting.  This will be a much more detailed look at ObjC which will allow us to dig into its core syntax and features.</p>
<p>I hope to see you all again at the next CocoaHeads meeting on 7/10 @ 6pm.</p>
<p>-Thanks,<br />
 Bob</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bobmccune.com/2008/06/16/cocoaheads-were-off-to-a-great-start/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

