Question

Here is template method pattern , Java and C++ can implement it easily with virtual function. How about Object C to implement this pattern ? Any example in cocoa touch (iOS) ?

Was it helpful?

Solution

As jer has already pointed out, all Objective-C methods are essentially virtual. It is a feature of the language which does not quite mesh with other C-like languages. That being said, the basics of the template method pattern can still be achieved in Objective-C, by "manually" forcing subclasses to implement certain functions. For example (using the convention in your linked Wikipedia article):

@interface Game
{
    int playersCount;
}
- (void)playOneGame:(int)numPlayers;
// "virtual" methods: 
- (void)initializeGame;
- (void)makePlay:(int)player;
- (BOOL)endOfGame;
- (void)printWinner;
@end

@implementation Game
- (void)initializeGame         { NSAssert(FALSE); }
- (void)makePlay:(int player)  { NSAssert(FALSE); }
- (BOOL)endOfGame              { NSAssert(FALSE); return 0; }
- (void)printWinner            { NSAssert(FALSE); }
- (void)playOneGame:(int)numPlayers
{
    //..
}
@end

The above code forces subclasses of Game to override the "virtual" methods by throwing an exception the moment one of the base class implementations is called. In effect, this moves the test from the compiler stage (as it would be in C++ or Java) and into the runtime stage (where similar things are often done in Objective-C).

If you really want to enforce the rule that subclasses are not allowed to override the playOneGame: method, you can attempt(*) to verify the correct implementation from within the init method:

@implementation Game
...
- (void)init
{
    if ((self = [super init]) == nil) { return nil; }

    IMP my_imp = [Game instanceMethodForSelector:@selector(playOneGame:)];
    IMP imp = [[self class] instanceMethodForSelector:@selector(playOneGame:)];
    NSAssert(imp == my_imp);

    return self;
}
...
@end

(*) Note that this code does not result in a 100% rock-solid defense against subclasses which re-implement playOneGame:, since the very nature of Objective-C would allow the subclass to override instanceMethodForSelector: in order to produce the correct result.

OTHER TIPS

In Objective-C all methods are akin to C++ virtual methods.

In Objective-C Template Method Pattern is Used When you have a Skeleton of an Algorithm but it can be Implemented in different ways. Template method defines the steps to execute an algorithm and it can provide default implementation that might be common for all or some of the subclasses.

Let's take an example but First Look at the Picture

enter image description here

 @interface Worker : NSObject

- (void) doDailyRoutine;
- (void) doWork; // Abstract
- (void) comeBackHome; 
- (void) getsomeSleep;
@end

@implementation Worker

- (void) doDailyRoutine {
  [self doWork];
  [self comeBackHome];
  [self getsomeSleep];
  }

 - (void) doWork { [self doesNotRecognizeSelector:_cmd]; }
 - (void) comeBackHome { [self doesNotRecognizeSelector:_cmd]; }
 - (void) getsomeSleep { [self doesNotRecognizeSelector:_cmd]; }
 // [self doesNotRecognizeSelector:_cmd] it will force to call the subclass          Implementation
@end

@interface Plumber : Worker
@end

@implementation Plumber

- (void) doWork { NSLog(@“Plumber Work"); }

@end
@interface Electrician : Worker

@end

@implementation Electrician

- (void) doWork { NSLog(@“Electrician Work"); }

@end
@interface Cleaner : Worker

@end

@implementation Cleaner

- (void) doWork { NSLog(@“Cleaner Work"); }

@end

In this example dowork() is an Abstract function which should be implemented by all the subclasses and this pattern is largely used in Cocoa Frameworks.

Hope it will help you to Understand the "Template Method Pattern".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top