Zoeken…


Invoering

MVP is een architecturaal patroon, een afleiding van de Model – View – Controller. Het wordt weergegeven door drie verschillende componenten: Model, View en de Presenter. Het is ontworpen om geautomatiseerde unit-testen te vergemakkelijken en de scheiding van problemen in presentatielogica te verbeteren.

In voorbeelden vindt u een eenvoudig project gebouwd met het MVP-patroon in gedachten.

Opmerkingen

componenten:

voer hier de afbeeldingsbeschrijving in

  • Model is een interface die verantwoordelijk is voor de domeingegevens (die moeten worden weergegeven of anderszins opgevolgd in de GUI)
  • Weergave is verantwoordelijk voor de presentatielaag (GUI)
  • Presenter is de "middelman" tussen Model en Beeld. Het reageert op de acties van de gebruiker die worden uitgevoerd in de weergave, haalt gegevens op uit het model en maakt deze op voor weergave in de weergave

Componenttaken:

Model Visie Presentator
Communiceert met DB-laag Gegevens worden weergegeven Hiermee voert u zoekopdrachten uit naar het model
Geschikte evenementen organiseren Ontvangt evenementen Formatteert gegevens van Model
Zeer eenvoudige validatielogica Verzendt geformatteerde gegevens naar de weergave
Complexe validatielogica

Verschillen tussen MVC en MVP :

  • View in MVC is nauw gekoppeld aan de Controller, het View-gedeelte van de MVP bestaat uit zowel UIViews als UIViewController
  • MVP View is zo dom mogelijk en bevat bijna geen logica (zoals in MVVM), MVC View heeft wat bedrijfslogica en kan het model opvragen
  • MVP View verwerkt gebruikersgebaren en delegeert interactie naar de Presenter, in MVC verwerkt de Controller gebaren en opdrachten Model
  • MVP-patroon ondersteunt in hoge mate Unit Testing, MVC heeft beperkte ondersteuning
  • MVC Controller heeft veel UIKit-afhankelijkheden, MVP Presenter heeft er geen

Voors:

  • MVP maakt UIViewController een onderdeel van de View-component, het is dom, passief en ... minder massief;]
  • Het grootste deel van de bedrijfslogica is ingekapseld vanwege de domme weergaven, dit geeft een uitstekende testbaarheid. Er kunnen onechte objecten worden geïntroduceerd om het domeingedeelte te testen.
  • Gescheiden entiteiten zijn gemakkelijker in hoofd te houden, verantwoordelijkheden zijn duidelijk verdeeld.

Cons

  • Je zult meer code schrijven.
  • Barrière voor onervaren ontwikkelaars of voor degenen die nog niet met het patroon werken.

Dog.swift

import Foundation

enum Breed: String {
    case bulldog  = "Bulldog"
    case doberman = "Doberman"
    case labrador = "Labrador"
}

struct Dog {
    let name:  String
    let breed: String
    let age:   Int
}

DoggyView.swift

import Foundation

protocol DoggyView: NSObjectProtocol {
    func startLoading()
    func finishLoading()
    func setDoggies(_ doggies: [DoggyViewData])
    func setEmpty()
}

DoggyService.swift

import Foundation

typealias Result = ([Dog]) -> Void

class DoggyService {

    func deliverDoggies(_ result: @escaping Result) {
        
        let firstDoggy  = Dog(name: "Alfred", breed: Breed.labrador.rawValue, age: 1)
        let secondDoggy = Dog(name: "Vinny",  breed: Breed.doberman.rawValue, age: 5)
        let thirdDoggy  = Dog(name: "Lucky",  breed: Breed.labrador.rawValue, age: 3)

        let delay = DispatchTime.now() + Double(Int64(Double(NSEC_PER_SEC)*2)) / Double(NSEC_PER_SEC)
        
        DispatchQueue.main.asyncAfter(deadline: delay) {
            result([firstDoggy,
                    secondDoggy,
                    thirdDoggy])
        }
    }
}

DoggyPresenter.swift

import Foundation

class DoggyPresenter {

    // MARK: - Private
    fileprivate let dogService: DoggyService
    weak fileprivate var dogView: DoggyView?

    init(dogService: DoggyService){
        self.dogService = dogService
    }

    func attachView(_ attach: Bool, view: DoggyView?) {
        if attach {
            dogView = nil
        } else {
            if let view = view { dogView = view }
        }
    }

    func getDogs(){
        self.dogView?.startLoading()
    
        dogService.deliverDoggies { [weak self] doggies in
            self?.dogView?.finishLoading()
        
        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:  String
}

DoggyListViewController.swift

import UIKit

class DoggyListViewController: UIViewController, UITableViewDataSource {

    @IBOutlet weak var emptyView: UIView?
    @IBOutlet weak var tableView: UITableView?
    @IBOutlet weak var spinner:   UIActivityIndicatorView?

    fileprivate let 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()
    }

    // MARK: DataSource
    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: [DoggyViewData]) {
        dogsToDisplay = doggies
        tableView?.isHidden = false
        emptyView?.isHidden = true;
        tableView?.reloadData()
    }

    func setEmpty() {
        tableView?.isHidden = true
        emptyView?.isHidden = false;
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow