【问题标题】:mvvm pattern in this style of coding is meanless?mvvm 模式在这种编码风格中是没有意义的?
【发布时间】:2019-03-20 23:04:16
【问题描述】:

我已经使用 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 更好......!

【问题讨论】:

  • 什么是“无麻疹”?
  • 我的错误。无意义

标签: swift xcode model-view-controller mvvm


【解决方案1】:

视图模型是一种在视图中使用的迷你模型。因此,您将视图属性绑定到它并管理每个属性的更改:

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

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

你写的faqViewModel类是一种APIRequestLoader,不属于view-model。有关更多信息,我建议您对Clean Swift ArchitectureSwift Viper Architecture 进行一些研究,如果您想了解有关如何将网络请求与应用程序的其他部分解耦的更多信息,This WWDC 2018 session 是一个不错的选择。

【讨论】:

  • 感谢您的帮助。您是说视图模型只绑定视图?并且没有网络请求和计算,对吗?我在控制器中进行网络请求,然后使用视图模型更新视图?所以我应该以这种方式更改我的代码:将我的网络请求放在控制器中并将我的 tableView 更新移动到 View-model.right ?
  • View-model 有两个词。 View -> UI and Model -> 视图背后的模型(不是整个应用程序背后的模型!)。请记住,模型不仅仅是一个数据集。想象一下,你应该用什么来描述你的应用程序,而不用说它的外观。 (没有可触摸的按钮,没有可输入的字段等)您在此阶段所说的任何内容都将在模型中生效!不是控制器(因为 MVVM 没有控制器)。但是您可以在迷你 MVC 中分离网络层并与之交互。请不要忘记将您问题的正确答案标记为已接受的答案。
【解决方案2】:

一些 MVC 问题在 Dave DeLongs blog 中有很好的描述。

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

  1. Massive View C控制器(视图逻辑、业务逻辑和网络通常放置在 *ViewController 类中,这些类会不断增长,有时非常大。

  2. 封装违规(例如,在 segue 中将数据传递给 ViewController 等)

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

MVVM

值得一提的是,MVVM 基本上是一个花哨的 MVC。

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

MVVM 优点

  1. 更好的可测试性
  2. 更好地分离关注点
  3. 摆脱海量视图控制器
  4. 它有点适合 CocoaTouch MVC 范例

我猜还有更多

MVVM 缺点

  1. 使用反应式框架需要改变“心态”,因此学习曲线陡峭
  2. 模型和视图很容易不同步
  3. 观察逻辑容易出错

还有更多

结论

MVVM 是一个很好的工具,如果使用得当,它可以修复一些 MVC 缺陷并为生产带来好处。 MVVM 需要一些努力和最佳实践学习。但是,在深入研究之前,我建议阅读 Dave DeLongs blog series "A better MVC" 并记住,MVC 是一种原生 Apple 模式,通过实施它,您可以在 SDK 更新时保持“安全”,避免出现重大意外。

P.S.我是正确使用 MVVM 的忠实粉丝,但不正确的使用有时会吓到我。

【讨论】:

  • 感谢您的精彩提示。您是否建议大型项目使用 mvvm 模式?不是两个多文件吗?
  • 这取决于许多因素,项目规模远不是决定应用程序设计解决方案的唯一因素。在我看来,这个问题没有简单的答案。我认为应该使用他深入理解的架构。要记住的另一件事是,如果建筑不是让你的生活变得更轻松而是更糟,那它就是一个糟糕的建筑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多