美文网首页
MVP Architecture

MVP Architecture

作者: 涅风槃云 | 来源:发表于2017-08-21 04:42 被阅读0次

MVP is an architectural pattern, a derivation of the Model-View-Controller. It's represented by three distinct components: Model, View and the Presenter. It was engineered to facilitate automated unit testing and improve the separation of concerns in presentation logic.

Example:

// MARK: Dog.swift

import Foundation

enum Breed:String {

      case bulldog = "BullDog"

      case doberman = "Doberman"

      case labrador = "Labrador"

}

structDog {

        let name:String

        let breed:String

        let age:Int

}

// DoggyPresenter.swift

import Fundation

class DoggyPresenter {

       // MARK: - private

       fileprivate let dogService: DogService

       weak fileprivate var dogView: DoggyView?

       init(dogService: DogService) {

            self.dogService = dogService

       }

      func attachView(_ attach: Bool, view: DoggyView?) {

             if attach {

                    dogView = nil

              } else {

                   if let view = view {

                           dogView = view

                   }

              }

      }


     // MARK: get dogs

      func getDogs() {

              self.dogView?.startLoading()

              dogService.deliverDoggies {  [weak self]  doggies in 

                   self?.dogView?.stopLoading()

                    if doggies.count == 0 {

                         self?.dogView?.setEmpty()

                   } else {

                           self?.dogView?.setDoggies(doggies.map {

                                   return DoggyViewData(name : "\($0.name) \($0.breed)", age : "\($0.age)")

                            })

                   }

                }

     }

}

struct DoggyViewData {

      let name : String

     let age : Int

}

// MARK: - DoggyServices.swift

import Foundation

typealias Result = ([Dog]) -> Void

class DoggyServices {

         func deliverDoggies(_ result: @escaping Result) {

                let firstDoggy = Dog(name: "", breed: Breed.bulldog.rawValue, age: 1)

              let secondDoggy = Dog(name : "", breed: Breed.doberman.rawValue, age: 5)

              let thirdDoggy = Dog(name: "", breed: Breed.labrador.rawValue, age: 7)

              let delay = DispatchTime.now() + Double(Int64(Double(NSEC_PER_SEC)*2)) / Doubel(NSEC_PER_SEC)

             DispatchQueue.main.asyncAfter(deadline: delay) {

                       return result([firstDoggy, secondDoggy, thirdDoggy])

              }

         }

}

// MARK: -- DoggyListViewController

import UIKit

class DoggyListViewController : UIViewController, UITableViewDataSource {

        @IBOutlet weak var emptyView: View?

        @IBOutlet weak var tableView: UITableView?

       @IBOutlet weak var spinner: UIActivityIndicatorView?

        fileprivate dogPresenter = DoggyPresenter(dogService: DoggyService())      

       fileprivate var dogsToDisplay = [DoggyViewData]()

      override func viewDidLoad() {

           super.viewDidLoad()

           tableView?.dataSource = self

          spinner?.hidesWhenStopped = true

          dogPresenter.attachView(true, view: self)

          dogPresenter.getDogs()    

        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            return dogsToDisplay.count

      }      

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

          let cell = UITableViewCell(style:.subtitle, reuseIdentifier:"Cell")

          let userViewData = dogsToDisplay[indexPath.row]

           cell.textLabel?.text = userViewData.name

           cell.detailTextLabel?.text = userViewData.age

          return cell

}    

extension DoggyListViewController: DoggyView {

        func startLoading() {

             spinner?.startAnimating()

        }

       func finishLoading() {

              spinner?.stopAnimating()

        }

      func setDoggies(_ doggies: [DogViewData]) {

             dogsToDisplay = doggies

             tableView?.isHidden = false 

             emptyView?.isHidden = true

            tableView?.reloadData()

         }

       func setEmpty() {

              tableView?.isHidden = true

              emptyView?.isHidden = false

        }

}

// DoggyView.swift

import Fundation

protocol DoggyView: NSObjectProtocol {

          func startLoading()

           func finishLoading()

          func setDoggy(_ doggies: [DoggyViewData])

           func setEmpty()

}

// MARK: --   Attention 

Model is an interface responsible for the domain data ( to be displayed or otherwise acted upon in the GUI )

View is responsible for the presentation layer ( GUI )

Presenter is the "middle-man" between Model and View. It reacts to the user's actions performed on the View, retrieves data from the Model, and formats it for display in the View.

Component duties:

1. Model 

communicate with DB layer ;

 Raising appropriate actions;

2. View

Renders data;

Receives events;

Very basic validation logic;

3. Presenter

Performs queries to the model;

Formats the data from the model;

Sends formatted data to the view;

Complex validation logic;

// MARK: Difference between MVC and MVP

1. View in MVC is tightly coupled with the Controller, the View part of the MVP consists of both UIViews and UIViewController.

2. MVP view is as dumb as possible and contains almost no logic(like in MVVM), MVC View has some businesss logic and can query the Model.

3. MVP View handles user gestures and delegates interaction to the Presenter, in MVC the Controller handles gestures and commands Mpdel.

4.  MVP pattern highly supports Unit Testing. MVC has limited support.

5. MVP Controller has lots of UIKit dependencies, MVP Presenter has none.

// MARK: Pros

1. MVP makes UIViewController a part of the View components it's dumb, passive and ... less massive;

2. Most of the business logic is incapsulated due to the dumb Views, this gives an excellent testability.Mock objects can be introduced to test the domain part.

3. Separated entities are easier to keep in head, responsibilities are clearly divided.

相关文章

网友评论

      本文标题:MVP Architecture

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