MVCについて、何を読んでも、なかなか理解できなく、丁寧に説明されても理解できなかった私がやっと納得できた考え方をここに書きたいと思います。一番参考にさせて頂いたURL(これが最強のMVC(iOS))です。
注意
これはあくまで考え方であり、全てをこのようにする必要はなく、このMVCを元に考え、この考えでうまく行かないとこ、自分だったらここに書いた方がいいなと思うときはこの考え方を押し付けるなそうです。と私は読んでいて思いました。しかしこれは間違っているのかな??とも不安に思いますが、私はあくまでなぜその書き方にするのがいいのかを考えてこの考え方で納得しました。
MVCとはViewとModelを分割して……?????
正直ここから理解できなかったです。なぜなら私の頭がかたいから。
カチコチだからです。分割??? ViewとModel???
どこからをViewとしてどこからをModelとしてどこからを……。
そして色々読んだり、書いて見たりして、あ、こう考えればいいと思いました!
Viewのクラスがすること……
部品(View,Button,label,WebView,indicatorView……とりあえず部品と言われるもの)をインスタンス化して、addするところ、frameを設定するところ。と後は装飾(色変えたり、角丸のおしゃれをすること)
例えば以下のCodeがあったとすると
var myButton = UIButton()
myButton = UIButton(frame: CGRect(x: 250.0, y: 580.0, width:80.0 , height: 80.0))
myButton.addTarget(self, action: #selector(buttonTap(sender:)), for: .touchUpInside)
myButton.backgroundColor = UIColor.red
myButton.layer.cornerRadius = 40
view.addSubview(myButton)
myButton.addTarget(self, action: #selector(buttonTap(sender:)), for: .touchUpInside)
の部分はVIewには書かないです。
ではここの部分はどこに書くのか?????ここで、次のお題、
ViewControllerのクラスがすること……
主にここはViewのactionとなる部分をViewControllerに書くことだと思いました。なのでさっきのcodeなら、
myButton.addTarget(self, action: #selector(buttonTap(sender:)), for: .touchUpInside)
ちなみにaction??と自分で納得してここでまた陥りました。tableViewのdelegateのcell tap検知するところはじゃぁここでいいのか?あれだってaction…では情報の連携などどのようにすればいいのかとお手本にしている"これが最強のMVC(iOS)"のcodeを読まさせていただいたらtableViewのactionのみしっかりViewControllerに書かれていました。まだModelの話をしていませんが、Modelにアクションの際に必要となるデータを取り出す用の関数(メソッド)を書いてうまく取り出していました。
なのでここはactionを書くところです。action……。ここで私は陥ります。アクションってどこまで、ここで私は、約束ごとを決めることにしました。
1,ViewContorollerでしかできないこと。(遷移、アラート表示。)
2,最低限※Viewを更新、ViewのtabeleViewのhiddenを変えるのみ、アクションを起こしたという事だけ
ですからactionを起こしてtableViewのデーターを取得して、セットしてとなるとViewControllerはactionを起こしたというところまでそこからはmodelの中で操作。
ViewModelのクラスがすること……
ViewContorollerはアクションをしたらmodelに何かしらのメッセージを送りViewの情報の更新などの処理をするところで、以下のような感じで会話をしながら行われているのではないかと思っています。
ViewContorollerさん…Viewからアクションきたよ!!
ViewModelさん…アクションきたのか、じゃ、僕のここでまず情報を更新して、で僕自身のデータを整えて、
ViewContorollerさん…viewmodelがちゃんとお仕事したらしいではViewを更新しないと更新!!
Viewさん…わお!!更新
みたいな流れかと感じています。
半ば強引ですが、大まかな流れを私はこのように理解しました。
codeなどに関しては、これが最強のMVCのブログがとても参考になると思います。
Viewからactionがきた!
Contolloerはactionの記述が書かれていてそれが起こったらmodelに伝える。
modeleはお仕事したことをViewContolloerに伝えて
ViewContolloerはViewを更新!!
ViewContorollerさん…Viewからアクションきたよ!!
ViewModelさん…アクションきたのか、じゃ、僕のここでまず情報を更新して、で僕自身のデータを整えて、
ViewContorollerさん…viewmodelがちゃんとお仕事したらしいではViewを更新しないと更新!!
Viewさん…わお!!更新
この考え方でとりあえず、納得したのだが、これでよかったのか?と不安ですが、このように考えることで整理ができる(書くところの役割分担ができる。)役割分担ができると、あ!次これしたい!と思った時に、自分がこの3つのうちのどこに書いているか考えそこを探してcodeを訂正できるのできる。これ3つが同じところだとその中から探さないといけないので大変という。
そのほかにViewに新しいViewの追加はViewにインスタン化してframe設定してaddしておしゃれで終れる。actionはあくまでViewContolloreに書くのでviewにaddしたいときはviewにaddしていけばいい。
よってView,ViewContollore,ViewModelの役割分担ができる。
これができると、もし開発者が3人いたらクラスごとにいじれるからgitのマージの時もコンフリクトしにくいとか、
とりあえず、利点があるからきっと大丈夫と願って。