二十三、模板方法模式

2017-07-28  本文已影响0人  LeeLeCoder

1. 何为模板方法模式

其基本思想是在抽象类的一个方法中定义“标准”算法,在这个方法中调用的基本操作由子类重载实现,这个方法被称为“模版”(因为方法定义的算法缺少一些特有的操作)。图1-1显示了抽象类与具体子类之间的关系---抽象类定义模版,字类重载基本操作以提供独特操作供模版方法调用。

图1-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. 何时使用模版方法

在以下情形,应该考虑使用模版方法:

钩子操作给出了默认行为,字类可以对其扩展。默认行为通常什么都不做,子类可以重载这个方法,为模板算法提供附加的操作。

模版方法模式中的控制结构流程是倒转的,因为父类的模版方法调用其字类的操作,而不是子类调用父类的操作。这与“好莱坞原则”类似:别给我们打电话,我们会打给你。

模版方法会调用5种类型的操作:

3. 代码实现

(1)父类定义模版:

#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

(2)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

(3)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

(4)客户端调用

// 选择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];
}
上一篇下一篇

猜你喜欢

热点阅读