設計模式系列文章
《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];
}
從代碼中我們可以看出,模板模式和策略模式在用法上還是有區別的。