1、傳統的MVC
可以看出另外每個實體都知道另外兩個實體,這顯然降低了可重用性當然也不是您在開發中想要的。2、蘋果的MVC
這裡View和Model的關係剪斷,但是在Controller中會變得很臃腫,Controller中程式碼量會變得很大。想想將業務邏輯、網路請求、View狀態改變還有把addSubView的程式碼也放在Controller中的,看了眼要修改的Controller是不是想死的心都有了。3、我的MVC
設計模式不是死,根據自己的需求和理解進行一些改變是必要的,再變也是萬變不離其宗,現在的專案的使用的MVC實際上就是對Controller的瘦身。上圖是取自iOS Architecture Patterns,這裡我直接說我的實現。
我的目錄是根據模組進行分解然後在模組目錄下建立MVC的資料夾,我不喜歡大的MVC檔案目錄然後吧相關的類放進對應的資料夾下的。
Model
和你所知MVC中的M是一樣的
/
// Model.swift
// Test
//
// Created by 小七 on 2017/9/19.
// Copyright © 2017年 Seven. All rights reserved.
//
import UIKit
struct Model {
var name: String?
}
複製程式碼
View
我不會在Controller中寫addSunViews這樣的程式碼, 所以這樣的程式碼全在封裝帶View中了,這裡用的Storyboard。我將storyboard放在Controller中純屬個人習慣,我個人認為這個是屬於View的
//
// TableViewCell.swift
// Test
//
// Created by 小七 on 2017/9/19.
// Copyright © 2017年 Seven. All rights reserved.
//
import UIKit
class MyTableViewCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
複製程式碼
Controller
Controller中含有Request和C->V的數值傳遞類, 在實際專案中將一部分的業務邏輯程式碼放在了ViewModel中了(這裡的ViewModel並不是MVVM中所表達的意思,只是借鑑了一些思路)
//
// ViewController.swift
// Test
//
// Created by 小七 on 2017/9/19.
// Copyright © 2017年 Seven. All rights reserved.
//
import UIKit
class ViewController: UITableViewController {
lazy private var mViewModel: ViewModel = ViewModel()
lazy private var mRequest: Request = Request()
override func viewDidLoad() {
super.viewDidLoad()
mRequest.request {[weak self] in
self?.tableView.reloadData()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mRequest.list.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as! MyTableViewCell
mViewModel.loadCellWithModel(mRequest.list[indexPath.row], view: cell)
return cell
}
}
複製程式碼
ViewModel
這裡做了資料的傳遞
//
// ViewModel.swift
// Test
//
// Created by 小七 on 2017/9/19.
// Copyright © 2017年 Seven. All rights reserved.
//
import UIKit
class ViewModel: NSObject {
func loadCellWithModel(_ model: Model, view: MyTableViewCell) {
view.label.text = model.name
}
}
複製程式碼
Request
網路請求的封裝和Model的儲存,我的Controller中是不儲存Model的
//
// Request.swift
// Test
//
// Created by 小七 on 2017/9/19.
// Copyright © 2017年 Seven. All rights reserved.
//
import UIKit
class Request: NSObject {
var list: [Model] = [Model]()
func request(result: () -> Void){
for _ in 0 ... 20 {
var m = Model()
m.name = "12345"
list.append(m)
}
result()
}
}
複製程式碼
後語
實際上MVVM和MVP可以也可以解決C過於臃腫的問題。那為什麼沒有使用流行的MVVM呢,因為MVVM的實現離不開RX和RAC,主要專案中沒有使用它們所以就沒有直接引入MVVM(這個理由確實牽強 = =!),還有建議使用的所有第三方庫最好自己進行封裝下,不然在換庫的時候會留下悔恨的淚水。
git地址go go
謝謝觀賞,這裡是我在專案中對MVC的理解,希望多多指正