什么是MVVM

Model-View-ViewModel(MVVM)是基于MVC的变形的一种设计模式,它由Model、View、ViewModel三部分组成,三部分的职责如下:

  • Model:负责表现应用的数据,它们通常是struct或者class。官方推荐使用struct定义Model。具体详情可点击这里。
  • View:负责显示在屏幕上的可视化元素,通常是UIView的子类。
  • ViewModel:负责将Model中的数据转化为View上显示的数据。它们通常是class,这样它们就可以通过引用指针来传递。

具体逻辑如下图:

为什么要使用MVVM

当我们在项目初创时期,用MVC搭建项目是没有问题的。但是随着项目业务越来越多,越来越复杂的时候,我们会发现Controller里面的东西会非常的多,它通常会包含:Controller的生命周期函数、视图的响应事件、远程数据的获取,数据的变形,各种逻辑的判断等等。这样会导致代码阅读性下降,bug率提升。这也是为什么大家调侃MVC为Massive-View-Controller的原因。

在这个背景下就诞生了MVVM设计模式来解决Massive Controller的问题,在使用MVVM的模式时,我们可以把数据转换、数据逻辑判断放在ViewModel里,以此来减轻Controller的负担。

开始搭建MVVM

1、首先我们新建一个项目,创建一个Person.swift文件来表示用户的数据:

//定义一个包含用户名字、头像和注册时间的结构体当做用户的Model
struct Person {let name: Stringlet image: Stringlet registerTimeStamp: TimeInterval
}
复制代码

2、接下来我们创建负责转换Model的ViewModel-PersonViewModel.swift:

// name 和 image 只是简单的通过两个计算属性来接受
// 将时间戳的注册时间转换为字符串的注册时间
class PersonViewModel {let person: Personprivate var name: String {return person.name}private var image: String {return person.image}private var registerTimeStr: String {let date = Date(timeIntervalSince1970: person.registerTimeStamp)let dateFormatter = DateFormatter()dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"let strDate = dateFormatter.string(from: date)return strDate}init(_ person: Person) {self.person = person}
}
复制代码

3、创建展示用户信息的PersonView.swift:

class PersonView: UIView {let imageView = UIImageView()let nameLabel = UILabel()let registerTimeLabel = UILabel()override init(frame: CGRect) {super.init(frame: frame)backgroundColor = UIColor.brownimageView.frame = CGRect(x: (frame.width - 50)/2, y: 10, width: 50, height: 50)addSubview(imageView)nameLabel.frame = CGRect(x: 0, y: 80, width: frame.width, height: 20)nameLabel.textAlignment = .centeraddSubview(nameLabel)registerTimeLabel.frame = CGRect(x: 0, y: 110, width: frame.width, height: 16)registerTimeLabel.font = UIFont.systemFont(ofSize: 14)registerTimeLabel.textColor = UIColor.lightGrayregisterTimeLabel.textAlignment = .centeraddSubview(registerTimeLabel)}required init?(coder aDecoder: NSCoder) {fatalError("init(coder:) has not been implemented")}
}
复制代码

4、最后一步,在Controller中将它们连接起来:

class ViewController: UIViewController {let personView = PersonView(frame: CGRect(x: (UIScreen.main.bounds.size.width - 200)/2, y: (UIScreen.main.bounds.size.height - 300)/2, width: 200, height: 300))override func viewDidLoad() {super.viewDidLoad()view.backgroundColor = UIColor.whitesetupSubViews()requestData()}func setupSubViews() {view.addSubview(personView)}func requestData() {let person = Person(name: "godiscoder", image: "head_default", registerTimeStamp: 1480134638.0)let viewModel = PersonViewModel(person)personView.imageView.image = UIImage(named: viewModel.image)personView.nameLabel.text = viewModel.namepersonView.registerTimeLabel.text = viewModel.registerTimeStr}}
复制代码

好啦,到现在为止你已经实践了MVVM的设计模式,如果不出意外的话你会在你的模拟器上显示一个展示用户信息的view,如下图:

5、当然,我们可以把给view赋值的语句放在PersonViewModel,这样可以使代码更加解耦。

// 在PersonViewModel 最下方 添加
extension PersonViewModel {func configurate(_ personView: PersonView) {personView.imageView.image = UIImage(named: image)personView.nameLabel.text = namepersonView.registerTimeLabel.text = registerTimeStr}
}// 将 ViewController里的requestData()的代码更新为下面的代码func requestData() {let person = Person(name: "godiscoder", image: "head_default", registerTimeStamp: 1480134638.0)let viewModel = PersonViewModel(person)viewModel.configurate(personView)
}
复制代码

完整代码可以在这里下载。

总结

当你的项目业务比较简单的时候还是推荐使用MVC架构,当业务比较复杂的时候可以转为MVVM架构。

一看就懂的极简MVVM相关推荐

  1. 10分钟看完一本书《极简主义》

    目录 总述 1. 通常来讲,比起寻找复杂的方法去做事,我们可以按照它相反的一面去做--第一个理念"事情其实很简单" 2. 在考虑任何企业.事业或者项目时,我们需要理解我们究竟想做什 ...

  2. 给大忙人们看的 Java NIO 极简教程

    作者 | JavaEdge 来源 | JavaEdge(ID:Java-Edge) 头图 |  CSDN 下载自东方IC Java NIO 的 Buffer 用于和 NIO Channel(通道)交互 ...

  3. 一看就懂的vue简版源码概述

    本文不会拆步骤对源码进行实现,只介绍vue原理及相关核心实现思想.在之前的四篇文章中已对vue进行响应实现.需要可阅读相关文章: Vue源码探索之知识小储备 --Object.defineProper ...

  4. java nio 读取图片_给大忙人们看的 Java NIO 极简教程

    作者 | JavaEdge 来源 | JavaEdge(ID:Java-Edge) 头图 | CSDN 下载自东方IC Java NIO 的Buffer用于和NIO Channel(通道)交互.数据是 ...

  5. 合适学习人工智能的小白的一本书《极简AI入门:一本书读懂人工智能思维与应用》

    今天看了一本书<极简AI入门:一本书读懂人工智能思维与应用> 对于初学人工智能的小白来说,应该是非常容易看得懂的,书里罗列了人工智能需要学习的各个技能,可以把这本书当作学习人工智能的目录( ...

  6. 伙伴分配器的一个极简实现

    提起buddy system相信很多人不会陌生,它是一种经典的内存分配算法,大名鼎鼎的Linux底层的内存管理用的就是它.这里不探讨内核这么复杂实现,而仅仅是将该算法抽象提取出来,同时给出一份及其简洁 ...

  7. 会生活会编程——我的极简主义尝试

    前段时间看过一本书<极简主义>,有一些收货,罗列一下其中的观点,以及作用到生活中的尝试. 首先来引述原文介绍下什么是极简主义: 极简主义是一个工具,我们用它来获得人生的满足感.极简主义中没 ...

  8. MVVM架构之自动增删改的极简RecycleView的实现

    先上个源代码的链接:github.com/whenSunSet/- RecycleView是Google替代ListView的一种方案,其有着很高的解耦度,让许多开发者抛弃了以往的ListView,那 ...

  9. 极简风海报作品合集|过目不忘的海报大片,越看越过瘾

    通过对艺术.文学.电影的涵养汲取,才造就了富有内涵与别致的广告赏片. "简约不是简单,是简洁精约,言简义丰.简洁而意味丰满,这就是简约.这需要极高的概 括能力和感受能力,当然是奢侈品. 极简 ...

最新文章

  1. 《设计模式解析(第2版)》
  2. 6000字详解数据仓库建设
  3. 如何在React Native中记录日志?
  4. dalsa线扫相机调试文档_线阵相机调试文档
  5. Ruby批量下载音乐
  6. 网狐棋牌(八) 异步引擎 和 网狐棋牌(九) 服务引擎概览
  7. 程序猿都在关注的6个优质公众号
  8. eclipse导出doc文档
  9. SpringMVC自学日志05(结果跳转方式,数据处理 ,乱码问题)
  10. matlab kmeans c 代码,K-means之matlab实现
  11. PHP+MySQL存储数据出现中文乱码的问题
  12. qt 字体 qss加载字体_字体加载技术
  13. x61 linux 驱动 无线网卡,联想thinkpadx61无线网卡驱动下载-联想x61无线网卡驱动 win7官方版 - 极光下载站...
  14. PHP和原生JS实现九型人格在线测试(144题)
  15. NoClassDefFoundError: Could not initialize class org.apache.kafka.common.record.Compressio
  16. Python---PDF旋转角度
  17. jDBC连接mysql数据库的5种方式
  18. python 正则表达式的应用
  19. 【裸金属服务器学习笔记】
  20. 深度学习基础实例与总结

热门文章

  1. 69道Java Spring 面试笔试题
  2. MessagePack, Protocol Buffers和Thrift序列化框架原理和比较说明
  3. 用JavaScript玩转计算机图形学(二)基本光源
  4. 程序员面试题精选100题(23)-跳台阶问题[算法]
  5. 机器学习的数学基础(1)--Dirichlet分布
  6. 多种特征提取算法比较汇总
  7. Octave相关学习资源整理出
  8. 《大话数据结构》第9章 排序 9.1 开场白
  9. [USACO06DEC]牛的野餐Cow Picnic DFS
  10. 怎么样清除bitcoin-qt的交易记录