美文网首页
iOS-设计模式-模板方法模式

iOS-设计模式-模板方法模式

作者: charleswang | 来源:发表于2018-08-16 10:44 被阅读124次

    介绍

    • 1.定义了一个模板结构,将具体的内容延迟到子类中去执行
    • 2.子类可以不改变算法结构,可以重新定义算法的某些特定步骤

    主要作用

    在不改变模板结构的前提下再子类中重新定义模板中的内容

    模板方法模式是基于“继承”的
    

    解决问题

    • 提高代码的复用性
      • 将相同部分代码放在抽象的父类中,而将不同的代码放入不同的子类中
    • 实现了反向控制
      • 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制&复合“开闭原则”

    模板方法模式->案例

    实现一个播放器:

    • 角色一:模板类->TemplateAVPlayer
    • 角色二:实现类->DefaultAVPlayer

    首先要确定TemplateAVPlayer模板方法,根据播放流程创建模板方法:

    • 1.创建播放器
    • 2.准备播放器(设置基本参数)
    • 3.添加监听器
    • 4.开始播放

    抽象模板方法类TemplateAVPlayer

    class TemplateAVPlayer: NSObject {
        
        public var delegate:AVPlayerDelegate?
    
        //定义模版方法->提供给外部
        final func play(controller:UIViewController, frame:CGRect, url:String){
            self.create(url: url)
            self.prepare(controller: controller, frame: frame)
            self.observer()
            self.paly()
        }
        
        //模版方法
        func create(url:String) {
            
        }
        
        //模版方法
        func prepare(controller:UIViewController, frame:CGRect) {
            
        }
        
        //模版方法
        func observer() {
            
        }
        
        //模版方法
        func paly() {
            
        }
        
        func pause() {
            
        }
        
        func stop() {
            
        }
        
        
    }
    
    

    具体的模板方法类->DefaultAVPlayer

    class DefaultAVPlayer: TemplateAVPlayer {
        
        private var player:AVPlayer?
        private var playerItem:AVPlayerItem?
    
        override func create(url: String) {
            //1、创建播放器
            self.playerItem = AVPlayerItem(url: URL(fileURLWithPath: url))
            self.player = AVPlayer(playerItem: self.playerItem)
        }
        
        override func prepare(controller: UIViewController, frame: CGRect) {
            //2.1 创建图层
            let playerLayer = AVPlayerLayer(player: self.player)
            playerLayer.frame = frame
            controller.view.layer.addSublayer(playerLayer)
        }
        
        override func observer() {
            //2.2 设置监听
            NotificationCenter.default.addObserver(self, selector: #selector(stop), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
            //2.3 添加监听
            self.playerItem?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
        }
        
        override func paly() {
            self.player?.play()
        }
        
        //语法
        @objc override func stop() {
            
        }
        
        //播放器状态改变
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            print("回调了...")
            if keyPath == "status" {
                //设置监听->外部处理
                self.delegate?.playerCall(status: self.playerItem?.status)
                if self.playerItem?.status == AVPlayerItemStatus.failed {
                    print("加载错误")
                } else if self.playerItem?.status == AVPlayerItemStatus.unknown {
                    print("未知错误")
                } else {
                    print("播放正常...")
                }
            }
        }
        
        //析构函数
        deinit {
            //释放资源
            NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
            self.playerItem?.removeObserver(self, forKeyPath: "status")
        }
        
    }
    
    

    客户端调用:

            let path = Bundle.main.path(forResource: "Test", ofType: ".mov")
            let player = DefaultAVPlayer()
            player.delegate = self
            player.play(controller: self, frame: self.view.frame, url: path!)
    

    这样使用模板方法模式处理,优化了代码的结构,这样的扩展性更强,只需要继承DefaultAVPlayer,实现模板方法,就可以实现具体的扩展

    其实模板方法模式在iOS中也有很多的应用例如UIViewController其实就是模板方法模式->生命周期固定、第三方的下拉刷新组件(详情请看下一篇MJRefresh的解析)

    相关文章

      网友评论

          本文标题:iOS-设计模式-模板方法模式

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