美文网首页
二十三、模板方法模式

二十三、模板方法模式

作者: LeeLeCoder | 来源:发表于2017-07-28 17:16 被阅读0次

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

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

    • 需要一次性实现算法的不变部分,并将可变的行为留给字类来实现。
    • 子类的共同行为应该被提取出来放到公共类中,以避免代码重复。现有代码的差别应该被分离为新的操作,然后用一个调用这些新操作的模版方法来替换这些不同的代码。
    • 需要控制字类的扩展。可以定义一个在特定点调用“钩子”(hook)操作的模版方法,子类可以通过对钩子操作的实现在这些点扩展功能。

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

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

    模版方法会调用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];
    }
    

    相关文章

      网友评论

          本文标题:二十三、模板方法模式

          本文链接:https://www.haomeiwen.com/subject/qufkcxtx.html