模板方法(Template Method Design Patt
2022-09-15 本文已影响0人
long弟弟
模板模式,模板方法设计模式
意图:定义一个操作中的算法
的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
这里的“算法”,可以理解为广义上的“业务逻辑”,并不是特指数据结构和算法中的“算法”。
通俗说就是把具有特定步骤算法中的某些必要的处理委托让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

角色和职责
- AbstractClass(抽象类)
定义抽象的原语操作(Primitive Operation),具体的子类将重定义它们以实现一个算法的各步骤
实现一个模板方法(Template Method),定义一个算法骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作 - ConcreteClass(具体类)
实现原语操作以完成算法中与特定子类相关的步骤
代码示例
#import <Foundation/Foundation.h>
@interface AbstractClass : NSObject
- (void)templateMethod; //模板方法
- (void)method1; //原语操作:具体的业务1
- (void)method2; //具体的业务2
- (void)method3; //具体的业务3
@end
@implementation AbstractClass
- (void)templateMethod { //算法骨架
//制定业务逻辑
[self method1];
[self method3];
[self method2];
}
- (void)method1 {
}
- (void)method2 {
}
- (void)method3 {
}
@end
@interface ConcreteClassA : AbstractClass
//子类不能重写templateMethod:方法
@end
@implementation ConcreteClassA
- (void)method1 {
NSLog(@"ConcreteClassA - method1");
}
- (void)method2 {
NSLog(@"ConcreteClassA - method2");
}
- (void)method3 {
NSLog(@"ConcreteClassA - method3");
}
@end
@interface ConcreteClassB : AbstractClass
@end
@implementation ConcreteClassB
- (void)method1 {
NSLog(@"ConcreteClassB - method1");
}
- (void)method2 {
NSLog(@"ConcreteClassB - method2");
}
- (void)method3 {
NSLog(@"ConcreteClassB - method3");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
AbstractClass *ac = [[ConcreteClassA alloc] init];
[ac templateMethod];
NSLog(@"======");
ac = [[ConcreteClassB alloc] init];
[ac templateMethod];
}
return 0;
}
/*
ConcreteClassA - method1
ConcreteClassA - method3
ConcreteClassA - method2
======
ConcreteClassB - method1
ConcreteClassB - method3
ConcreteClassB - method2
*/
协作
ConcreteClass靠AbstractClass来实现算法中不变的步骤
用处
模板方法一般应用在具有以下条件的应用中:
- 具有统一的操作步骤或操作过程
- 具有不同的操作细节
- 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
总结:在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样可以把各个具体的子类和操作步骤解耦合。
优点
- 封装不变部分,扩展可变部分
- 提取公共代码,便于维护(复用)
- 行为由父类控制,子类实现(扩展)
缺点
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大