前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

MVP

作者头像
大话swift
发布2019-07-04 11:14:42
6610
发布2019-07-04 11:14:42
举报
文章被收录于专栏:大话swift大话swift

简介

MVP 全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。

特点

作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

实例

1 分别定义出对应的protocol

protocol IView {

}

protocol IModel {

}

protocol IPresenter {

var mView: View? { get set }

var mModel: Model? {get set}

associatedtype View:IView

associatedtype Model:IModel

func bindView( _ iView:View)

func unBind()

}

2 初始化进行通用操作的基类

class BasePresenter<T:IView, M:IModel>: IPresenter{

var mModel: M?

var mView: T?

func bindView(_ iView: T) {

mView = iView

}

func unBind() {

}

typealias View = T

typealias Model = M

}

class BaseView:IView{}

class BaseModel: IModel {

}

3 根据需要基于基类进行扩展

class AModel:IModel{

func doCallback( back:()->Void){

print("model do it to pass to view")

back()

}

}

protocol AView: IView {

func doIt()

}

class MyPresenter: BasePresenter<MyViewController, AModel>{

func doIt(){

print("presenter do it to call model")

if self.mModel == nil {

self.mModel = AModel()

}

mModel?.doCallback {

mView?.doIt()

}

}

}

实际使用

class MyViewController : UIViewController, AView{

func doIt() {

print("view do it")

}

var mPresenter: MyPresenter?

override func loadView() {

mPresenter = MyPresenter()

defer {

mPresenter?.unBind()

mPresenter = nil

}

mPresenter?.bindView(self)

print("start call presenter")

mPresenter?.doIt()

let view = UIView()

view.backgroundColor = .white

let label = UILabel()

label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)

label.text = "Hello World!"

label.textColor = .black

view.addSubview(label)

self.view = view

}

}

结果

改进

MVP中我们把个个分开没有形成一个整体,我们完全可以把MVP哥哥部分统一的进行一个整体的集合,通过声明Contract将其整合到一起,将P的初始化和基本操作绑定等交给contract,通过contract与UIViewController的交互

protocol Contract{

associatedtype Model

associatedtype View

associatedtype Presenter

var mModel:Model?{get set}

var mView: View? {get set}

var mPresenter: Presenter?{get set}

func doViewBindToPresenter()->Bool

func doViewUnBindtFromPresenter()

}

然后声明一个基类来完成mvp通用的逻辑处理

class BaseContract<M:IModel, V:IView,P:BasePresenter<V, M>>: Contract {

var mModel: M?

var mView: V?

var mPresenter: P?

typealias Model = M

typealias View = V

typealias Presenter = P

func doViewUnBindtFromPresenter() {

mPresenter?.unBind()

}

func doViewBindToPresenter() -> Bool {

if mView == nil || mPresenter == nil{

return false

}

mPresenter?.bindView(mView!)

return true

}

init( v:V, p:(V)->P) {

mView = v

mPresenter = p(mView!)

}

}

最后根据实际的需要进行contract的扩展

class AContract:BaseContract<AModel, MyViewController , BasePresenter<MyViewController, AModel>>{

}

让我们看看怎么使用

override func loadView() {

var a = AContract.init(v: self) { (vc:MyViewController) -> BasePresenter<MyViewController, AModel> in

var p = MyPresenter.init()

p.bindView(vc)

p.doIt()

return p

}

// mPresenter = MyPresenter()

// defer {

// mPresenter?.unBind()

// mPresenter = nil

// }

// mPresenter?.bindView(self)

// print("start call presenter")

// mPresenter?.doIt()

let view = UIView()

view.backgroundColor = .white

let label = UILabel()

label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)

label.text = "Hello World!"

label.textColor = .black

view.addSubview(label)

self.view = view

}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大话swift 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 特点
  • 实例
    • 1 分别定义出对应的protocol
      • 2 初始化进行通用操作的基类
        • 3 根据需要基于基类进行扩展
          • 实际使用
            • 结果
            • 改进
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档