策略模式在播放器調(diào)試中的運用

需求:最近在視頻播放中撮慨,遇到了播放器來回切換調(diào)試的問題,那么接下來,會介紹一下怎么做才會使代碼更加適用于業(yè)務(wù)且改動較小的方案柏卤。

場景一

  • 只有騰訊播放SDK

方案一

直接在ViewController初始化TencentSDK省容,并實現(xiàn)對應(yīng)的播放抖拴、暫停停止腥椒、重置等功能阿宅。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tencentSDK = [TencentSDK new];
}

- (void)onActionPlay:(id)sender {
    [self.tencentSDK play];
}

- (void)onActionPause:(id)sender {
    [self.tencentSDK pause];
}

- (void)onActionStop:(id)sender {
    [self.tencentSDK stop];
}

- (void)onActionResume:(id)sender {
    [self.tencentSDK resume];
}

這種使用方式是我剛進入職場使用的一種傻瓜式方案,開發(fā)快速笼蛛,簡單明了洒放,適用于一次性開發(fā),確定播放類型滨砍,且后期不會再改動的代碼往湿。

場景二

  • 騰訊播放SDK
  • 新浪播放SDK
  • 最開始使用騰訊SDK榨为,后面由于業(yè)務(wù)需求,接入新浪SDK

方案一

ViewController里面初始化TencentSDK煌茴。因為業(yè)務(wù)更改随闺,ViewController里面初始化SinaSDK,在原來的業(yè)務(wù)邏輯里面替換代碼。

- (void)viewDidLoad {
    [super viewDidLoad];
//    self.tencentSDK = [TencentSDK new];
    self.sinaSDK = [SinaSDK new];
}

- (void)onActionPlay:(id)sender {
//    [self.tencentSDK play];
    [self.sinaSDK play];
}

- (void)onActionPause:(id)sender {
//    [self.tencentSDK pause];
    [self.sinaSDK play];
}

- (void)onActionStop:(id)sender {
//    [self.tencentSDK stop];
    [self.sinaSDK stop];
}

- (void)onActionResume:(id)sender {
//    [self.tencentSDK resume];
    [self.sinaSDK resume];
}

這種方案也可以完成我們更改播放SDK的需求蔓腐,但是一個播放界面的業(yè)務(wù)不僅僅是播放矩乐、暫停停止回论、重置等功能散罕,還會涉及到彈幕禮物傀蓉、分享等其他業(yè)務(wù)欧漱,隨著業(yè)務(wù)增多,ViewController的代碼也會隨之變大葬燎,有時候我們在執(zhí)行暫停時還會有其它操作误甚,這樣頻繁去更改代碼的行為并不友好,也增加了我們的工作量谱净,出錯機率也會隨之增大窑邦。

方案二

工作中我們在使用第三方框架時,提倡加一層中間層壕探,這樣在替換第三方框架時冈钦,可以減少業(yè)務(wù)代碼的更改,只需要中間層替換底層代碼李请,保持上層業(yè)務(wù)代碼不變瞧筛。

創(chuàng)建PlayerInter作為播放器的中間層,對之前的方案一進行更改

- (instancetype)initWithType:(NSNumber *)type {
    if (self = [super init]) {
        _type = type;
    }
    return self;
}

- (void)interPlay {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK play];
    } else {
        [self.tencentSDK play];
    }
}

- (void)interPause {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK pause];
    } else {
        [self.tencentSDK pause];
    }
}

- (void)interStop {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK stop];
    } else {
        [self.tencentSDK pause];
    }
}

- (void)interResume {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK resume];
    } else {
        [self.tencentSDK resume];
    }
}

播放器SDK懶加載导盅,根據(jù)PlayerInter初始化傳進來的type類型较幌,進行對應(yīng)的播放器使用。ViewController的代碼屬于上層業(yè)務(wù)认轨,當播放更換時绅络,只需要PlayerInter做更改月培,上層業(yè)務(wù)不需要更改嘁字。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.playerInter = [[PlayerInter alloc]initWithType:@1];
}

- (void)onActionPlay:(id)sender {
    [self.playerInter interPlay];
}

- (void)onActionPause:(id)sender {
    [self.playerInter interPause];
}

- (void)onActionStop:(id)sender {
    [self.playerInter interStop];
}

- (void)onActionResume:(id)sender {
    [self.playerInter interResume];
}

加了中間層,感覺方案上已經(jīng)盡善盡美杉畜,當播放器更換時纪蜒,只需要修改type類型即可,并且也可以做到后臺控制使用哪種播放器此叠〈啃可是作為一個居安思危的程序員,我怎么能在這個時候就紅棗枸杞茶喝起來呢?我設(shè)想如果再有一種新的播放器的話代碼會怎么樣猬错。窗看。。

  • 假設(shè)新增優(yōu)酷播放SDK

PlayerInter代碼如下

- (instancetype)initWithType:(NSNumber *)type {
    if (self = [super init]) {
        _type = type;
    }
    return self;
}

- (void)interPlay {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK play];
    } else if ([self.type isEqualToNumber:@2]) {
        [self.tencentSDK play];
    } else {
        [self.youkuSDK play];
    }
}

- (void)interPause {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK pause];
    } else if ([self.type isEqualToNumber:@2]) {
        [self.tencentSDK pause];
    } else {
        [self.youkuSDK pause];
    }
}

- (void)interStop {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK stop];
    } else if ([self.type isEqualToNumber:@2]) {
        [self.tencentSDK pause];
    } else {
        [self.youkuSDK stop];
    }
}

- (void)interResume {
    if ([self.type isEqualToNumber:@1]) {
        [self.sinaSDK resume];
    } else if ([self.type isEqualToNumber:@2]) {
        [self.tencentSDK resume];
    } else {
        [self.youkuSDK stop];
    }
}

除了頻繁的if else改動之外倦炒,ViewController的上層業(yè)務(wù)代碼沒有做出任何改變显沈,這種中間層的方案也還是可以解決我剛才設(shè)想的問題,可是作為一個有強迫癥的程序員逢唤,if else過多也覺得會增加錯誤機率拉讯,如果接下來有第四、第五個播放器呢鳖藕?

方案三

播放器功能

  • 播放
  • 暫停
  • 停止
  • 重置

每個播放器都不外乎有以上幾個功能魔慷,那么是否可以通過一種新的方法來改變之前的策略呢?

創(chuàng)建PlayProtocol協(xié)議著恩,協(xié)議有play院尔、pausestop喉誊、resume等通用method

@protocol PlayProtocol <NSObject>
- (void)play;
- (void)pause;
- (void)stop;
- (void)resume;

創(chuàng)建TencentPlayObject類召边,遵守PlayProtocol協(xié)議,在TencentPlayObject初始化TencentSDK,并實現(xiàn)PlayProtocol協(xié)議制定的方法裹驰。

- (instancetype)init {
    if (self = [super init]) {
        //初始化SDK
        _tencentSDK = [[TencentSDK alloc]init];
    }
    return self;
}

#pragma mark - PlayProtocol
- (void)play {
    [self.tencentSDK play];
}

- (void)pause {
    [self.tencentSDK pause];
}

- (void)stop {
    [self.tencentSDK stop];
}

- (void)resume {
    [self.tencentSDK resume];
}

創(chuàng)建SinaPlayObjectYouKuObject隧熙,遵守PlayProtocol,初始化相對應(yīng)的SDK,并實現(xiàn)協(xié)議方法幻林,方法同TencentPlayObject一樣贞盯。

創(chuàng)建PlayerFactory類,根據(jù)type類型沪饺,用來生產(chǎn)對應(yīng)的playObject

@implementation PlayerFactory

- (instancetype)initWithType:(NSNumber *)type {
    if (self = [super init]) {
        _type = type;
    }
    return self;
}

- (id<PlayProtocol>)productionPlayer {
    if ([self.type isEqualToNumber:@1]) {
        return self.tencentPlayer;
    } else if ([self.type isEqualToNumber:@2]) {
        return self.sinaPlayer;
    } else {
        return self.youkuPlayer;
    }
}

接下來對ViewController的代碼進行調(diào)整

@interface ViewController ()
@property (nonatomic , strong) id<PlayProtocol> player;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    PlayerFactory *factory = [[PlayerFactory alloc]initWithType:@2];
    self.player = [factory productionPlayer];
}

- (void)onActionPlay:(id)sender {
    [self.player play];
}

- (void)onActionPause:(id)sender {
    [self.player pause];
}

- (void)onActionStop:(id)sender {
    [self.player stop];
}

- (void)onActionResume:(id)sender {
    [self.player resume];
}

相比較之前的中間層方案躏敢,協(xié)議的方法更直接明了,從PlayerFactory類中可以看出整葡,只有在生產(chǎn)player的時候用到了if else判斷件余,其它只要各自遵守協(xié)議即可,代碼上更簡單流程遭居,出錯機率大大降低啼器。ViewController業(yè)務(wù)層的代碼也保持了不變的原則。如果需要刪除哪個播放器俱萍,只要對應(yīng)刪除SDKObject類即可端壳,不用像在中間層一樣在代碼中刪除,出錯機率也大大降低枪蘑。

如果在使用協(xié)議方案的同時再加一層中間層會怎樣损谦?

可以把協(xié)議比作一套算法岖免,上層業(yè)務(wù)直接與中間層關(guān)聯(lián),在中間層可以去替換不同協(xié)議照捡,就做到了算法上的改變颅湘,這種方案使程序結(jié)構(gòu)更加嚴謹,替換方案更多栗精,維護更加方便簡潔栅炒。

項目 demo
我的博客 擺渡屋

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市术羔,隨后出現(xiàn)的幾起案子赢赊,更是在濱河造成了極大的恐慌,老刑警劉巖级历,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件释移,死亡現(xiàn)場離奇詭異,居然都是意外死亡寥殖,警方通過查閱死者的電腦和手機玩讳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嚼贡,“玉大人熏纯,你說我怎么就攤上這事≡敛撸” “怎么了樟澜?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叮盘。 經(jīng)常有香客問我秩贰,道長,這世上最難降的妖魔是什么柔吼? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任毒费,我火速辦了婚禮,結(jié)果婚禮上愈魏,老公的妹妹穿的比我還像新娘觅玻。我一直安慰自己,他們只是感情好培漏,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布溪厘。 她就那樣靜靜地躺著,像睡著了一般北苟。 火紅的嫁衣襯著肌膚如雪桩匪。 梳的紋絲不亂的頭發(fā)上打瘪,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天友鼻,我揣著相機與錄音傻昙,去河邊找鬼。 笑死彩扔,一個胖子當著我的面吹牛妆档,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虫碉,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼贾惦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敦捧?” 一聲冷哼從身側(cè)響起须板,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兢卵,沒想到半個月后习瑰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡秽荤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年甜奄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窃款。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡课兄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晨继,到底是詐尸還是另有隱情烟阐,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布紊扬,位于F島的核電站曲饱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珠月。R本人自食惡果不足惜扩淀,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啤挎。 院中可真熱鬧驻谆,春花似錦、人聲如沸庆聘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伙判。三九已至象对,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宴抚,已是汗流浹背勒魔。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工甫煞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冠绢。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓抚吠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親弟胀。 傳聞我的和親對象是個殘疾皇子楷力,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 用到的組件 1、通過CocoaPods安裝 2孵户、第三方類庫安裝 3萧朝、第三方服務(wù) 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,621評論 1 180
  • 我剛剛認識C姑娘的時候,對她印象非常好夏哭。 親和力強剪勿,舌燦如花。 多年銷售行業(yè)累積出來的察言觀色方庭,雖然有些浮夸的做作...
    清風(fēng)明月7773閱讀 295評論 1 4
  • 昨晚回到家孩子們洗澡械念,我開啟了新命名增強身份感的游戲头朱。 我先對弟弟說“你是超級無敵蜘蛛俠!” 弟弟搖頭喊著“不是龄减,...
    鴿子1007閱讀 196評論 0 0
  • 這一折騰就是三年之久项钮,無論是皇室,學(xué)院希停,家族烁巫,三年來前前后后尋找,甚至皇室中更有把剛出生的嬰兒帶入皇宮宠能,直接成...
    盤陀閱讀 235評論 0 0
  • 終于把[我可能不會愛你]重看完亚隙,雖然會經(jīng)常回看這部劇可是都是選擇性地看某一集或某個特別喜歡的片段违崇,而且我老是不喜歡...
    cheerhoo閱讀 208評論 0 0