Objective-C - Template methods pattern?

aryaxt picture aryaxt · Nov 16, 2011 · Viewed 8.2k times · Source

So I've been reading about template methods on Objective-C and I am trying to understand what's so special about them. From my understanding any method in a Base class can be over-ridden and super can be called? So is a template method anything more than overriding a method in the base class?

If I'm wrong, can you please explain what a template-method-pattern is, and can you provide an example?

Answer

Guven picture Guven · Nov 16, 2011

Yes, the template pattern is a bit more than just overriding a method in the base class.

Template pattern can be used when an outline of an algorithm is concretely defined, however the steps of the algorithm are left abstract. That means that the steps can be implemented in different ways. But, the general outline of the algorithm is not expected to change.

An example that I have just created on the fly:

class Life {

   public method goThroughTheDay(){
     goToWork();
     eatLunch();
     comeBackHome();
     programABitMore();
   }
   abstract method goToWork();
   abstract method eatLunch();
   abstract method comeBackHome();
   abstract method programABitMore();
}

class GoodLife extends Life {
   //override all the abstract methods here
}

//The client application
Life life = new GoodLife();
life.goThroughTheDay();

Basically, the way a day is expected to run down is concretely defined in the Life class. However, the details of the process are taken care by the subclass (ie. GoodLife). GoodLife class will implement steps very differently than a possible ToughLife class.

There are some variations to this pattern; for example some of the steps can also be concretely defined. In the example, the eatLunch() can be concretely defined in the Life class; meaning that the subclasses are not expected to change this behaviour.

The pattern makes a lot of sense if you have a relatively complex algorithm that could be implemented in different ways.

======================================

I somehow missed the part with Objective-C in my answer. Here is how it would look in Objective-C:

@interface Life : NSObject

- (void) goThroughTheDay;

- (void) goToWork; // Abstract
- (void) eatLunch; // Abstract
- (void) comeBackHome; // Abstract
- (void) programABitMore; // Abstract

@end

@implementation Life

- (void) goThroughTheDay {

    [self goToWork];
    [self eatLunch];
    [self comeBackHome];
    [self programABitMore];
}

- (void) goToWork { [self doesNotRecognizeSelector:_cmd]; }
- (void) eatLunch { [self doesNotRecognizeSelector:_cmd]; }
- (void) comeBackHome { [self doesNotRecognizeSelector:_cmd]; }
- (void) programABitMore { [self doesNotRecognizeSelector:_cmd]; }

@end

@interface GoodLife : Life

@end

@implementation GoodLife

- (void) goToWork { NSLog(@"Good Work"); }
- (void) eatLunch { NSLog(@"Good Lunch"); }
- (void) comeBackHome { NSLog(@"Good Comeback"); }
- (void) programABitMore { NSLog(@"Good Programming"); }

@end

Objective-C doesn't have built-in support for abstract classes, so I worked around it using the doesNotRecognizeSelector: method. A lot more details about the abstract classes & Objective-C can be found here.