iOS Design Patterns Part4: MVVM

demo

iOS Design Patterns Part4: MVVM_第1张图片

   在这节课你会学到 MVVM设计模式的运用,让我们先简单回顾一下 MVC-N,以及它的不足。

   在之前的demo中我们提到了三种一般的目录:model、view、controller。其中,点击事件由controller处理,通过networking client 加载数据,同样应该由controllers处理,把模型数据转化为界面视图显示还是由controllers完成。只不过controllers不是最好的做模型数据处理的地方。

   幸好另一种设计模式可以处理这些:MVVM( model view view model )隆重登场~
   你可能已经猜到了MVVM拆开的话是:models, views, 和 view models.

iOS Design Patterns Part4: MVVM_第2张图片

   well,view model是个什么鬼?他对我们可爱的controllers做了什么?

   让我们深入了解下MVVM:ControllersMVVM设计模式仍然存在,但他不再是主要的重点, view models才是。

   controller不再直接拥有models,而是拥有 view models,而view models 会持有models

   view models作为model的一个中间人而发挥着重要的作用:处理把模型数据转化为界面视图显示

iOS Design Patterns Part4: MVVM_第3张图片
关于MVVM的图解

   接下来,在Demo中,你会:
   创建一个 product view models,重构现有的controllers,让我们开始给controllers瘦身吧!

   用模拟器运行Demo,选择 Home Services—>点击第一个产品图片,然后你会看到一个关于商品的描述的界面。一般来说,这个地方需要做许多数据处理,同时,这里有一个很明显的bug:图片显示的商品不对,让我们打开Xcode查看一下发生了什么:

   在导航区域选择Cleaning Services—>Controllers—>product details view controller—>view did load(),我们会在方法中看到许多数据处理的代码。但是在MVVM设计模式下,数据处理不应该在 product view controller,应该在 view model中处理

   我们要新建一个组来放view models,新建一个 product view model文件放进去,我们已经说过view model会直接拥有model,所以把 product 作为 product view model的一个属性,同时在初始化中设置一下:

import UIKit
public final class ProductViewModel{
    public let product: Product
    public init(product: Product){
        self.product = product
    }
}

   然后我们在assistant editor 打开product details view controller(按住Option,然后点击product details view controller

   在product details view controller你会看到outlet对每个View一对一的映射:description label, image view, price label,这样做的话在在view did load()方法设置起来会很容易

   让我们继续添加text, image URL,
price text、title
作为属性,同时把他们添加到初始化方法

   这里有个小问题:price需要使用number formatter转换一下,所以我们需要把number formatter也作为viewmodel的一个属性

   因为这个属性外部不会调用所以我们创建一个lazy static property

  internal static let numberFormatter: NumberFormatter = {
    let numberFormatter = NumberFormatter()
    numberFormatter.locale = Locale(identifier: "en_US")
    numberFormatter.numberStyle = .currency
    return numberFormatter
  }()
iOS Design Patterns Part4: MVVM_第4张图片

   ok,现在我们可以使用这个view model了,我们去 product sales view controller中把product modelproduct view model替换掉。

   首先我们要把product属性换成product view model,然后修改 view did load()方法。

  public var productViewModel: ProductViewModel!
public override func viewDidLoad() {
    super.viewDidLoad()
    
    descriptionLabel.text = productViewModel.descriptionText
    imageView.rw_setImage(url: productViewModel.imageURL)
    priceLabel.text = productViewModel.priceText
  }
iOS Design Patterns Part4: MVVM_第5张图片

   最后update ProductsViewControllerprepare(for segue:)方法

    viewController.productViewModel = ProductViewModel(product: product)

   重新运行,再点进product details view controller来看,一切运行完美,图片显示错误的bug也被修复了。

   Product details view controller看起来瘦身了一些,但是 products view controller并没有,所以需要你在challenge去实现.

   需要提醒的是有很多方法都可以实现MVVM,并且程序员们对MVVM也有各式各样的想法,例如:在Demo中,我们的controllers仍然有很多逻辑。另一些程序员更倾向于把所有的逻辑处理移到view models里,条条大路通罗马,事实上这样做也可以。

   关键在于创建 view models来处理数据转换,如果你觉得把逻辑处理移到 view models很好,you can do it~只是需要注意不要把 view models弄的太大。

   拜拜。

你可能感兴趣的:(iOS Design Patterns Part4: MVVM)