Что такое "шаблон метода шаблона" в какао с объектом C? (Сравнение языков мышления)

Вот шаблон шаблонного метода, Java и C++ могут легко реализовать его с помощью виртуальной функции. Как насчет Object C для реализации этого шаблона? Любой пример касания какао (iOS)?

3 ответа

Решение

Как уже отмечал Джер, все методы Objective-C по сути являются виртуальными. Это особенность языка, которая не совсем совпадает с другими С-подобными языками. Тем не менее, основы шаблона шаблона все еще могут быть достигнуты в Objective-C, "вручную" заставляя подклассы реализовывать определенные функции. Например (используя соглашение в вашей связанной статье в Википедии):

@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

Приведенный выше код заставляет подклассы Game переопределить "виртуальные" методы, создав исключение в тот момент, когда вызывается одна из реализаций базового класса. По сути, это перемещает тест из стадии компилятора (как это было бы в C++ или Java) в стадию времени выполнения (где подобные вещи часто выполняются в Objective-C).

Если вы действительно хотите применить правило, что подклассам не разрешено переопределять playOneGame: метод, вы можете попытаться (*) проверить правильность реализации из init метод:

@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

(*) Обратите внимание, что этот код не дает 100% надежной защиты от подклассов, которые повторно реализуют playOneGame:, поскольку сама природа Objective-C позволит подклассу переопределять instanceMethodForSelector: чтобы получить правильный результат.

В Objective-C все методы сродни C++ virtual методы.

В Objective-C шаблонный шаблон используется, когда у вас есть скелет алгоритма, но он может быть реализован различными способами. Шаблонный метод определяет шаги для выполнения алгоритма и может обеспечить реализацию по умолчанию, которая может быть общей для всех или некоторых из подклассов.

Давайте рассмотрим пример, но сначала посмотрим на картинку

введите описание изображения здесь

 @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

В этом примере dowork() является абстрактной функцией, которая должна быть реализована всеми подклассами, и этот шаблон широко используется в Какао-фреймворках.

Надеюсь, что это поможет вам понять "Шаблон шаблона".

Другие вопросы по тегам