読者です 読者をやめる 読者になる 読者になる

mmag

ハマったことメモなど

MVPアーキテクチャってこうですかわかりません

世の中にはMVCやMVVMやMVPといったアーキテクチャがたくさん考えられています。そういうものに基いてアプリケーションを開発していくと、コードが整理されてメンテナンス性が上がったりテストしやすくて幸せなわけですが、本当に自分の書いているコードはこのアーキテクチャに則っていると言えるのか、という疑問が湧いてくるわけです。僕は今iOSアプリ開発歴を1週間で、アーキテクチャにMVPを選んでいるのですが、本当にこれってMVPなんですかという疑念によってコードが書けねぇわ書けねぇわもうやんやん。

というわけで、自分の中で整理するとともに識者の方にアドバイスを貰うべく、ブログにしたためようではありませんか。

読んだもの

MVPの発祥を探ろうかとも思ったのですが長い道のりになりそうだったのでStack Overflowのこの回答を読むと、

MVPではPresenterがUIに関するロジックを持っていて、VIewからのイベントはPresenterに委譲される。で、Presenterがやることやったら、interfaceを介してViewに終わったよーということを知らせると。イメージはこんな感じ

f:id:Joe_noh:20160624230157p:plain:w500

で、これを念頭に https://github.com/trinhduchung/Swift-MVP-POC を読みました。

書いたもの

trinhduchung/Swift-MVP-POCを読みながらカウンターアプリを書いてみました。

import Foundation

class Counter {
    var count: Int

    init() {
        count = 0
    }

    func countUp() {
        count += 1
    }
}
import UIKit

class HelloViewController: UIViewController {

    var presenter: HelloPresenter!
    var counter: Counter!

    @IBOutlet weak var countLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        counter = Counter()
        presenter = HelloPresenter(view: self, counter: counter)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func tapMeTapped(sender: AnyObject) {
        presenter.countUp()
    }
}

extension HelloViewController: HelloViewProtocol {
    func onCountChanged(count: Int) {
        countLabel.text = String(count)
    }
}
import Foundation

class HelloPresenter {

    var helloView: HelloViewProtocol
    var counter: Counter

    init(view: HelloViewProtocol, counter: Counter) {
        self.counter = counter
        helloView = view
        helloView.onCountChanged(counter.count)
    }

    func countUp() {
        counter.countUp()
        helloView.onCountChanged(counter.count)
    }
}

まずは意図したとおりに動いているのですが、これはMVPに則っていると言えるのか、テストしやすくなっているのか、イマイチよくわからんのです。

テーマはFB matteをベースにしてます。作者さんに感謝を込めて。