美文网首页
iOS-老生常谈MVC、MVP、MVVM

iOS-老生常谈MVC、MVP、MVVM

作者: Simple_Code | 来源:发表于2020-04-17 21:05 被阅读0次

    MVC(apple版)

    image.png

    视图(View):用户界面.
    控制器(controller):业务逻辑
    模型(Model): 数据

    C层主要代码:

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            let cellID: String = "CellID"
            var cell: UITableViewCell?
            cell = tableView.dequeueReusableCell(withIdentifier: cellID)
            if cell == nil {
                cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellID)
            }
            
            var model = MVCModel()
            model = dataArray[indexPath.row]
            
            cell?.textLabel?.text = model.title
            cell?.detailTextLabel?.text = model.detail! + String(indexPath.row)
            return cell!
        }
    

    V使用的事系统自带的UITableViewCell
    M层代码:

    struct MVCModel: Convertible {
        var title: String?
        var detail: String?
    
        static func arrayModel() -> [MVCModel] {
            let array: [[String: Any]] = [
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
            ]
            return array.kj.modelArray(MVCModel.self)
        }
    }
    

    实现效果


    image.png

    结论
    如上代码可以看出VM是完全独立的、所有的逻辑处理都在C

    优点:View、Model可以重复利用,可以独立使用
    缺点:Controller的代码过于臃肿

    MVC(变种)

    image.png

    C层主要代码

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            let cellID: String = "CellID"
            var cell: MVCCell?
            cell = tableView.dequeueReusableCell(withIdentifier: cellID) as? MVCCell
            if cell == nil {
                cell = MVCCell(style: .subtitle, reuseIdentifier: cellID)
            }
            
            var model = MVCModel()
            model = dataArray[indexPath.row]
            
            cell?.model = model
            
            return cell!
        }
    

    V层主要代码:

        var model: MVCModel? {
            didSet {
                guard let tempModel = model else {
                    return
                }
    
                titleLabel.text = tempModel.title! + "变种"
                detailLabel.text = tempModel.detail! + "变种"
            }
        }
    

    M层代码:

    struct MVCModel: Convertible {
        var title: String?
        var detail: String?
    
        static func arrayModel() -> [MVCModel] {
            let array: [[String: Any]] = [
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
                ["title":"MVC",
                "detail":"detail"],
            ]
            return array.kj.modelArray(MVCModel.self)
        }
    }
    

    实现效果:


    image.png

    结论:
    如上代码可以看出V是拥有M的、数据复制逻辑处理都在V

    优点:对Controller进行瘦身,将View内部的细节封装起来了,外界不知道View内部的具体实现
    缺点:View依赖于Model

    MVP

    image.png

    C层代码

    class MVPViewController: UIViewController {
    
        var presenter: MVPPresenter?
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            
            presenter = MVPPresenter(vc: self)
        }
    
    }
    

    P层代码

    class MVPPresenter: NSObject {
        var viewController: UIViewController?
        
        init(vc : UIViewController) {
            super.init()
            viewController = vc
            setUp()
        }
        
        func setUp() {
            
            // 创建View
            let mView = MVPView()
            viewController?.view.addSubview(mView)
            mView.snp.makeConstraints { (make) in
                make.left.top.right.equalToSuperview()
                make.height.equalTo(600)
            }
            
            // 赋值数据
            mView.titleLabel.text = MVPModel.model().title
            mView.imageView.image = UIImage(named: MVPModel.model().image!)
        }
    }
    

    V层代码

    class MVPView: UIView {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            addSubView()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
      
        lazy var imageView: UIImageView = {
            let imageView = UIImageView()
            return imageView
        }()
        lazy var titleLabel: UILabel = {
            let label = UILabel()
            label.text = "MVC变种"
            label.textColor = UIColor.HEX(hex: 0x000000)
            label.font = UIFont.boldSystemFont(ofSize: 24)
            label.numberOfLines = 1
            return label
        }()
    }
    
    extension MVPView {
        func addSubView()  {
            addSubview(imageView)
            addSubview(titleLabel)
            
            imageView.snp.makeConstraints { (make) in
                make.centerX.centerY.equalToSuperview()
                make.width.equalTo(200)
                make.height.equalTo(100)
            }
            titleLabel.snp.makeConstraints { (make) in
                make.centerX.equalToSuperview()
                make.centerY.equalTo(imageView.snp.bottom).offset(20)
            }
        }
    }
    
    

    M层代码

    struct MVPModel: Convertible {
        var title: String?
        var image: String?
    
        static func model() -> MVPModel {
            let dict: [String: Any] = ["title":"龙妈",
                                       "image":"long.jpg"]
                
            return dict.kj.model(MVPModel.self)
        }
    }
    

    MVVM

    image.png

    C层代码

    import UIKit
    
    class MVVMViewController: UIViewController {
        var viewModel: MVVMViewModel?
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            viewModel = MVVMViewModel(vc: self)
            
        }
        
    }
    

    MV层代码

    import UIKit
    
    class MVVMViewModel: NSObject {
        var viewController: UIViewController?
        
         @objc dynamic var title: String?
         @objc dynamic var image: String?
        
        init(vc : UIViewController) {
            super.init()
            viewController = vc
            setUp()
        }
        
        func setUp() {
           
            // 创建View
            let mView = MVVMView()
            viewController?.view.addSubview(mView)
            mView.snp.makeConstraints { (make) in
                make.left.top.right.equalToSuperview()
                make.height.equalTo(600)
            }
           
            
            // 赋值数据
            mView.viewModel = self
            title = MVVMModel.model().title
            image = MVVMModel.model().image
    
        }
        
    }
    

    V层代码

    import UIKit
    
    class MVVMView: UIView {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            addSubView()
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
      var viewModel: MVVMViewModel? {
          didSet {
            
            self.kvoController.observe(viewModel, keyPath: "title", options: .new) { (observe, object, change) in
                let newValue = change["new"] as? String
                self.titleLabel.text = newValue
            }
            self.kvoController.observe(viewModel, keyPath: "image", options: .new) { (observe, object, change) in
                
                let newValue = change["new"] as? String
                self.imageView.image = UIImage(named: newValue!)
            }
           
          }
      }
        lazy var imageView: UIImageView = {
            let imageView = UIImageView()
            return imageView
        }()
        lazy var titleLabel: UILabel = {
            let label = UILabel()
            label.textColor = UIColor.HEX(hex: 0x000000)
            label.font = UIFont.boldSystemFont(ofSize: 24)
            label.numberOfLines = 1
            return label
        }()
    }
    
    extension MVVMView {
        func addSubView()  {
            addSubview(imageView)
            addSubview(titleLabel)
            
            imageView.snp.makeConstraints { (make) in
                make.centerX.centerY.equalToSuperview()
                make.width.equalTo(200)
                make.height.equalTo(100)
            }
            titleLabel.snp.makeConstraints { (make) in
                make.centerX.equalToSuperview()
                make.centerY.equalTo(imageView.snp.bottom).offset(20)
            }
        }
        
     }
    
    
    

    M层代码

    struct MVVMModel: Convertible {
        var title: String?
        var image: String?
    
        static func model() -> MVVMModel {
            let dict: [String: Any] = ["title":"龙妈",
                                       "image":"long.jpg"]
                
            return dict.kj.model(MVVMModel.self)
        }
    }
    

    有点:MVVM解决了Controller的代码过于臃肿的问题、并且V和M完全解耦。

    相关文章

      网友评论

          本文标题:iOS-老生常谈MVC、MVP、MVVM

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