Objective-C - Шаблон методов шаблонов?
Итак, я читал о шаблонных методах в Objective-C и пытаюсь понять, что в них такого особенного. Насколько я понимаю, любой метод в базовом классе может быть переопределен, и супер может быть вызван? Так является ли метод шаблона чем-то большим, чем переопределение метода в базовом классе?
Если я ошибаюсь, не могли бы вы объяснить, что такое шаблон-метод-шаблон, и можете ли вы привести пример?
3 ответа
Да, шаблон шаблона немного больше, чем просто переопределение метода в базовом классе.
Шаблон шаблона может использоваться, когда схема алгоритма определена конкретно, однако шаги алгоритма остаются абстрактными. Это означает, что шаги могут быть реализованы по-разному. Но общая схема алгоритма не должна меняться.
Пример, который я только что создал на лету:
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();
По сути, то, как должен проходить день, конкретно определено в классе Life. Однако, детали процесса заботятся подклассом (то есть. GoodLife). Класс GoodLife будет реализовывать шаги совершенно иначе, чем возможный класс ToughLife.
Есть несколько вариаций этого паттерна; например, некоторые из шагов также могут быть конкретно определены. В этом примере eatLunch() может быть конкретно определен в классе Life; Это означает, что подклассы не должны изменять это поведение.
Шаблон имеет большой смысл, если у вас есть относительно сложный алгоритм, который может быть реализован различными способами.
======================================
Я как-то пропустил часть с Objective-C в моем ответе. Вот как это будет выглядеть в 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 не имеет встроенной поддержки абстрактных классов, поэтому я обошел его, используя doesNotRecognizeSelector:
метод. Гораздо больше подробностей об абстрактных классах и Objective-C можно найти здесь.
Я подумал, что должен дать более конкретный ответ на Objective-C. Вы можете прочитать о методе шаблона, который используется в Какао на страницах Шаблонов дизайна какао яблок. Примером этого является drawRect:
шаблонный метод. Как и другие методы шаблона, вы никогда не вызываете методы шаблона непосредственно самостоятельно. Это называется setNeedsDisplay
, Смысл этого состоит в том, чтобы позволить каркасу оптимизировать чертеж. Если вы позвонили drawRect:
непосредственно вы можете сделать ненужные перерисовки много раз.
На самом деле вам, вероятно, следует попытаться сделать каждый метод, который вы хотите переопределить в подклассе, шаблоном. Это уменьшает проблему знания того, следует ли вам вызывать реализацию базового класса при переопределении, и облегчает отладку. Вы можете просто поместить точку останова в базовый класс вместо всех переопределенных методов в подклассах.
Насколько я понимаю, любой метод в базовом классе может быть переопределен, и супер может быть вызван? Так является ли метод шаблона чем-то большим, чем переопределение метода в базовом классе?
Да, это гораздо больше, чем просто переопределение метода базового класса. Шаблонные методы - это способ реализации алгоритма, в котором некоторые шаги зависят от подкласса. Например, рассмотрим метод в Base, который имеет три основных шага: f1, f2 и f3. Каждый шаг содержит ряд утверждений. Здесь f1 и f3 одинаковы во всех подклассах, но f2 зависит от подкласса. Так что же здесь делать? Вы можете переопределить весь метод в операторах копирования подклассов f1 и f3, но это пустая трата. Таким образом, вы предоставляете только f2 в подклассе. Таким образом, вы определяете алгоритм (выполняете f1, затем выполняете f2, затем выполняете f3) в базовом классе, но предоставляете переопределенные хуки для подклассов (f2). Обратите внимание, что шаблонный метод в базовом классе является окончательным, поэтому подкласс не может изменить алгоритм, например, он не может изменить порядок f1, f2 и f3, ни один из подклассов не может пропустить шаги f1, f3.
Короче говоря, шаблон Template Methods не просто переопределяет, а использует наследование для обработки определенных ситуаций. Это не специфично для Obj-C, и я не могу предоставить вам ничего конкретного для Obj-C. Чтобы получить общее представление об этом шаблоне, я рекомендую следующее:
И есть также множество учебников / статей в Интернете. Основная идея не зависит от Obj-C.