1.问题引入:在答题时,对于同样的试题,答题者会有不同的答案,试题是不变的,变得是答案,遇到这样的可以使用模版方法来解决
定义 :定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用
-
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
-
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是Opdyke和Johnson所描述过的“重分解以一般化”的一个很好的例子。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
-
控制子类扩展。模板方法只在特定点调用“hook”操作,这样就只允许在这些点进行扩展。
2.UML类图
3.实现
1、定义模版基类(试卷 不可变部分) UML中用的是抽象类,oc中没有抽象类,这里用基类代替, - (NSString *)answer1;- (NSString *)answer2;可看作是抽象方法
#import <Foundation/Foundation.h>
@interface TextPaper : NSObject
- (void)testQuestion1;
- (NSString *)answer1;
- (void)testQuestion2;
- (NSString *)answer2;
@end
#import "TextPaper.h"
@implementation TextPaper
-(void)testQuestion1{
NSLog(@"问题:杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ]:a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维");
NSLog(@"答案:%@", [self answer1]);
}
-(NSString *)answer1{
return nil;
}
-(void)testQuestion2{
NSLog(@"问题:杨过、程英、陆无双铲除了情花,造成[ ]:a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");
NSLog(@"答案:%@", [self answer2]);
}
-(NSString *)answer2{
return nil;
}
2、定义子类继承基类 (答案 可变部分)
#import "TextPaper.h"
@interface TextPaperA : TextPaper
@end
#import "TextPaperA.h"
@implementation TextPaperA
-(NSString *)answer1{
return @"b";
}
-(NSString *)answer2{
return @"c";
}
@end
#import "TextPaper.h"
@interface TextPaperB : TextPaper
@end
#import "TextPaperB.h"
@implementation TextPaperB
-(NSString *)answer1{
return @"a";
}
-(NSString *)answer2{
return @"d";
}
@end
3.调用
TextPaper *paperA = [[TextPaperA alloc]init];
[paperA testQuestion1];
[paperA testQuestion2];
TextPaper *paperB = [[TextPaperB alloc]init];
[paperB testQuestion1];
[paperB testQuestion2];
4.输出
5.模版方法模式和策略模式的区别
Strategy模式的应用场景是:
1. 多个类的分别只是在于行为不同
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据
Template Method模式的应用场景是:
1. 你想将相同的算法放在一个类中,将算法变化的部分放在子类中实现
2. 子类公共的算法应该放在一个公共的类中,避免代码重复
个人体会 :要面向接口的编程,而不是面向实现的编程。 不变的封装固定,变的做为接口