设计模式系列文章
《iOS设计模式(1)简单工厂模式》
《iOS设计模式(2)工厂模式》
《iOS设计模式(3)适配器模式》
《iOS设计模式(4)抽象工厂模式》
《iOS设计模式(5)策略模式》
《iOS设计模式(7)建造者模式》
在前面提到的例子中,我们列举了播放器的例子。我们知道一个播放器一般都是包括一些基本的功能,比如播放、暂停、停止等等。这些功能是无论哪个播放器都具备的功能,只是每个播放器基于的语言不通,开发的思想不通,所以其提供的接口和功能实现也不尽相同。其实,对于我们之前的需求来说,使用模板模式也可以达到我们的目的。
1.概念描述
模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Template Method Pattern: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
通俗来讲就是:定义一个父类,有父类定义接口规范,然后不同的行为在子类中实现。这样一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类。模板模式是一种基于继承的代码复用技术,是一种类行为型模式。模板模式应该是最简单的一种设计模式,只存在继承关系,代码也相对简单。
2.使用场景
模板模式和策略模式的不同点:
(1)策略模式的应用场景:
- 多个类的区别只是在于行为不同。
- 你需要行为的算法做很多变动。
- 客户端不知道算法使用的数据。
(2)模板模式的使用场景:
- 相同的算法放在一个类中(父类)将算法变化的部分放在子类中。
- 子类公共的算法放在一个公共类中,避免代码重复。
3.代码实现
父类定义规范
#import <Foundation/Foundation.h>
@interface LHPlayer : NSObject
/**
* Player开启视频
*
* @return 描述(只为举例需要)
*/
- (NSString *)play;
/**
* Player暂停视频
*
* @return 描述(只为举例需要)
*/
- (NSString *)pause; // 开启视频
/**
* Player停止播放
*
* @return 描述(只为举例需要)
*/
- (NSString *)stop; // 开启视频
@end
#import "LHPlayer.h"
@implementation LHPlayer
//Player开启视频
- (NSString *)play{
return nil;
}
//Player暂停视频
- (NSString *)pause{
return nil;
}
//Player停止播放
- (NSString *)stop{
return nil;
}
@end
LHAVPlayer子类中实现
#import "LHPlayer.h"
@interface LHAVPlayer : LHPlayer
@end
#import "LHAVPlayer.h"
#import "AVPlayer.h"
@interface LHAVPlayer ()
{
id<AVPlayerProtocol> player;
}
@end
@implementation LHAVPlayer
- (instancetype)init
{
self = [super init];
if (self) {
player = [[AVPlayer alloc] init];
}
return self;
}
//Player开启视频
- (NSString *)play{
return [player a_play];
}
//Player暂停视频
- (NSString *)pause{
return [player a_pause];
}
//Player停止播放
- (NSString *)stop{
return [player a_stop];
}
- (void)dealloc
{
player = nil;
}
@end
LHIJKPlayer子类中实现
#import "LHIJKPlayer.h"
#import "Ijkplayer.h"
@interface LHIJKPlayer ()
{
id<IjkplayerProtocol> player;
}
@end
@implementation LHIJKPlayer
- (instancetype)init
{
self = [super init];
if (self) {
player = [[Ijkplayer alloc] init];
}
return self;
}
//Player开启视频
- (NSString *)play{
return [player i_play];
}
//Player暂停视频
- (NSString *)pause{
return [player i_pause];
}
//Player停止播放
- (NSString *)stop{
return [player i_stop];
}
- (void)dealloc
{
player = nil;
}
@end
客户端调用
// 选择AVPlayer
- (IBAction)btnAVPlayerEvent:(UIButton *)sender {
sender.selected = YES;
_btnIjkplayer.selected = NO;
if (player) {
player = nil;
}
player = [[LHAVPlayer alloc] init];
}
// 选择Ijkplayer
- (IBAction)btnIjkplayerEvent:(UIButton *)sender {
sender.selected = YES;
_btnAVPlayer.selected = NO;
if (player) {
player = nil;
}
player = [[LHIJKPlayer alloc] init];
}
从代码中我们可以看出,模板模式和策略模式在用法上还是有区别的。