Was ist das „Template -Methode -Muster“ in Kakao mit Objekt C? (Sprachvergleichs Denken)
Frage
Hier ist Template -Methodenmuster , Java und C ++ können es einfach mit virtueller Funktion implementieren. Wie wäre es mit Objekt C, um dieses Muster zu implementieren? Irgendein Beispiel in Cocoa Touch (iOS)?
Lösung
Wie Jer hat bereits darauf hingewiesen, dass alle objektiven C-Methoden im Wesentlichen virtuell sind. Es ist ein Merkmal der Sprache, das nicht ganz mit anderen C-ähnlichen Sprachen eingeht. Trotzdem können die Grundlagen des Template-Methodenmusters in Objective-C immer noch erreicht werden, indem Unterklassen "manuell" gezwungen werden, bestimmte Funktionen zu implementieren. Beispielsweise (mit der Konvention in Ihrem verknüpften Wikipedia -Artikel):
@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
Der obige Code erzwingt Unterklassen von Game
Um die "virtuellen" Methoden zu überschreiben, indem eine Ausnahme ausgelöst wird, sobald eine der Implementierungen der Basisklassen aufgerufen wird. Tatsächlich bewegt sich der Test aus der Compiler-Stufe (wie in C ++ oder Java) und in die Laufzeitstufe (wo ähnliche Dinge häufig in Objective-C durchgeführt werden).
Wenn du Ja wirklich Ich möchte die Regel durchsetzen, dass Unterklassen nicht überschreiben dürfen playOneGame:
Methode können Sie (*) versuchen, die korrekte Implementierung innerhalb des init
Methode:
@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
(*) Beachten Sie, dass dieser Code nicht zu einer 100% igen felsigen Verteidigung gegen Unterklassen führt, die erneut implementieren playOneGame:
, da die Natur von Objective-C die Unterklasse überschreiben würde instanceMethodForSelector:
Um das richtige Ergebnis zu erzielen.
Andere Tipps
In Objective-C sind alle Methoden mit C ++ vergleichbar virtual
Methoden.
In Objective-C-Template-Methoden wird Muster verwendet, wenn Sie ein Skelett eines Algorithmus haben, aber es kann auf unterschiedliche Weise implementiert werden. Die Vorlagenmethode definiert die Schritte zur Ausführung eines Algorithmus und kann eine Standardimplementierung liefern, die für alle oder einige Unterklassen üblich ist.
Schauen wir uns ein Beispiel an, aber schauen wir uns zunächst das Bild an
@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 diesem Beispiel ist Dowork () eine abstrakte Funktion, die von allen Unterklassen implementiert werden sollte, und dieses Muster wird größtenteils in Kakao -Frameworks verwendet.
Ich hoffe, es hilft Ihnen, das "Template -Method -Muster" zu verstehen.