Что такое "шаблон метода шаблона" в какао с объектом 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 шаблонный шаблон используется, когда у вас есть скелет алгоритма, но он может быть реализован различными способами. Шаблонный метод определяет шаги для выполнения алгоритма и может обеспечить реализацию по умолчанию, которая может быть общей для всех или некоторых из подклассов.
Давайте рассмотрим пример, но сначала посмотрим на картинку
@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() является абстрактной функцией, которая должна быть реализована всеми подклассами, и этот шаблон широко используется в Какао-фреймворках.
Надеюсь, что это поможет вам понять "Шаблон шаблона".