这种样式的mvvm模式编码是没有意义的吗?

时间:2018-10-16 12:03:26

标签: swift xcode model-view-controller mvvm

我已经用MVC模式开发了自己的项目,并试图转换为MVVM模式,但有时我认为它变得越来越糟,毫无意义。

这是我的代码的一部分。我有控制器,模型和一个如下视图模型:

struct FAQ: Mappable {        
    var id: String?
    var question: String?
    var answer: String?
    var datalist: [FAQ]?
    //var datalist: [Any]?

    mutating func mapping(map: Map) {
        id <- map["id"]
        question <- map["question"]
        answer <- map["answer"]
        datalist <- map["data"]
    }
}

class learningViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var faqLable: UILabel!
    @IBOutlet weak var learningLable: UILabel!
    @IBOutlet weak var uiviewHeader: UIView!
    @IBOutlet weak var barRight: UILabel!
    @IBOutlet weak var barLeft: UILabel!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var backImage: UIImageView!

    var learningRequestSession: URLSessionDataTask?
    let address = Domains.address
    var objectData = faqViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        objectData.faqFunc {
            self.setup()
        }
        setup()

    }

    override func viewWillAppear(_ animated: Bool) {
        tableView.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectData.objectData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "faqCell", for: indexPath) as! customViewCellTableViewCell

        //cell.faqIcon.image = UIImage(named: "question")
        cell.faqTitle.text = objectData.objectData[indexPath.row].question
        cell.faqBody.text = objectData.objectData[indexPath.row].answer

        return cell            
    }
...
}

这是视图模型类:

class faqViewModel {
    var objectData = [FAQ]()

    init(faq: [FAQ]) {
        self.objectData = faq
    }

    init() {}

    func faqFunc(complition: @escaping () -> () ) {        
        let url = URL(string: "\(address)faq/getdata")
        print(url!)

        URLSession.shared.dataTask(with: url!) { (data, response, err) in
            if let content = data {
                do {
                    let json = try! JSONSerialization.jsonObject(with: content, options: .mutableContainers) as Any

                    let mapper = Mapper<FAQ>().map(JSONObject: json)

                    self.objectData = (mapper?.datalist.map({ $0}))!
                } catch {
                    print(err)
                }
            }
        }.resume()
    }
}

faqFunc函数以前是MVC模式中的控制器类。

我已按照这种模式将其移至视图模型。所以我觉得我做错了,或者MVC更好...!

2 个答案:

答案 0 :(得分:2)

Dave DeLongs blog中对MVC的某些问题进行了很好的描述。

我同意他的观点,认为MVC在某些情况下可能会导致:

  1. M 辅助 V iew C 控制面板(查看逻辑,业务逻辑和网络通常放置在*ViewController中有时会极大增长的课程。

  2. 违反封装规定(例如,通过segue将数据传递到ViewController等)

  3. 可测试性。 MVC通常需要编写集成测试,这些测试很难维护,并且需要非常了解UIKit

MVVM

值得一提的是,MVVM本质上是一款花哨的MVC。

MVVM旨在解决MVC模式的某些缺陷。它改进了separation of concerns,使逻辑更加清晰。没有更多的大型视图控制器(正确使用)。恕我直言,MVVM的最大好处是可测试性。现在我们有了ViewModel这个对象,其中包含所有与视图相关的数据。因此,编写测试不再需要集成测试。但是使用MVVM通常会连接到某种反应式编程。本身具有隐患和陡峭的学习曲线。

MVVM专业人士

  1. 更好的可测性
  2. 更好地分离关注点
  3. 摆脱大量的View Controllers
  4. 有点符合CocoaTouch MVC范例

我想还有更多

MVVM缺点

  1. 使用反应性框架需要“思维定势”的改变,因此,学习曲线会变得陡峭
  2. 很容易获得模型并与视图不同步
  3. 易于在观察逻辑中犯错误

更多

结论

MVVM是一个不错的工具,如果使用得当,它可以修复MVC的某些缺陷并带来生产效益。 MVVM需要一些努力和最佳实践学习。但是,在深入研究之前,我建议阅读Dave DeLongs blog series "A better MVC"并记住,MVC是Apple的本机模式,通过实施它,可以在更新SDK时避免大的意外。

PS 。我是正确 MVVM使用的忠实拥护者,但有时使用不当会使我感到恐惧。

答案 1 :(得分:1)

视图模型是一种用于视图的微型模型。因此,您可以将视图属性绑定到该属性并管理每个属性的更改:

视图已更改->视图模型更新

视图模型已更改->视图更新

您编写的faqViewModel类是一种APIRequestLoader,不属于视图模型。有关更多信息,建议您对Clean Swift ArchitectureSwift Viper Architecture进行一些研究,如果您想了解有关如何将网络请求与应用程序其他部分分离的更多信息,This WWDC 2018 session是观看的好选择。