摘要
架构师应该是所有程序员的终极梦想,但对于如何成为一个合格的架构师,却总是茫然无措,无从下手,相信大多数人跟我一样,曾经也或百度或谷歌过无数次:MVC是什么,MVVM是什么,数据流是什么,然而却没有一次让我醍醐灌顶、豁然开朗。我一直在带着这个疑问去找寻我心中的答案,这篇文章用来记录目前我所认识到的架构的含义,也希望能给有幸读到这篇文章的人以一丝启发和感悟。
前言
犹记得在刚接触iOS开发那会,自认为会写几个页面就能改变世界了,写代码只在乎功能实现,那时候也知道MVC,但要我具体说说啥是MVC,说不清楚。那时候公司也不注重这些,只为完成业务需求,忽视了技术的重要性。
后来在真正学习使用了一些新架构之后,我对架构的理解不一样了,我不再极力推崇某一架构,也不再为了架构而架构,而是去思考这个架构核心是什么,从何而来,为何存在。这是我这篇文章真正想表达的。
架构,百度百科给出的解释是:架构,又名软件架构,是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。它说架构是一种设计。但我自己的理解是,架构是我们代码优化到一定程度之后,自然而然形成的一种思维方式和编码形式,架构从何而来,从我们每次优化代码后的思考而来,架构为何存在,因为思考之后,留下来了好的思维方式和编码形式。为什么这么说,下面就从最简单的代码优化开始。 1、一个极简单的功能,点击按钮,切换背景色。这份代码初学者都能写出来吧。

@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.setTitle("编辑", for: .normal)
// Do any additional setup after loading the view.
}
@IBAction func buttonTouch(_ sender: UIButton) {
if sender.title(for: .normal) == "完成" {
self.view.backgroundColor = UIColor.green
sender.setTitle("编辑", for: .normal)
} else if sender.title(for: .normal) == "编辑" {
self.view.backgroundColor = UIColor.red
sender.setTitle("完成", for: .normal)
}
}
2、上面那个是直接在storeboard编辑的,现在提一个需求,这个界面跟另一个界面很类似,项目中要共用,那我们就会把View拎出来,新建一个EditView,然后把这个View放到storeboard上,最后呈现的效果是一样的,但是实现了View和Controller的分离。
@IBOutlet weak var button: UIButton!
func setup() {
button.setTitle("编辑", for: .normal)
}
@IBAction func buttonTouch(_ sender: UIButton) {
if sender.title(for: .normal) == "完成" {
self.backgroundColor = UIColor.green
sender.setTitle("编辑", for: .normal)
} else if sender.title(for: .normal) == "编辑" {
self.backgroundColor = UIColor.red
sender.setTitle("完成", for: .normal)
}
}
3、然后View上面会有一些其它元素,我们先添加两个label,代码也很简单

func setup() {
button.setTitle("编辑", for: .normal)
titleLabel.text = "page1_title"
subtitleLabel.text = "page1_subtitle"
}
4、但界面中的元素是由用的人来管理数据的,你写死了别人怎么用呢,另一个界面的titleLabel并不是呈现“page1_title”,所以应该定一个Model,这个Model是你这个View的Model,别人用的时候只需要传一个ViewModel就可以了。
struct ViewModel {
var titleStr: String?
var subtitleStr: String?
}
var viewModel: ViewModel? {
didSet {
titleLabel.text = viewModel?.titleStr
subtitleLabel.text = viewModel?.subtitleStr
}
}
5、接下来,点击button后,要求这两个label文案改变,代码也很简单,EditView添加如下代码
enum ButtonType: Int {
case edit = 0
case done
}
var buttonCallback: ((ButtonType) -> Void)?
var curButtonType: ButtonType = .edit
@IBAction func buttonTouch(_ sender: UIButton) {
if sender.title(for: .normal) == "完成" {
self.backgroundColor = UIColor.green
sender.setTitle("编辑", for: .normal)
curButtonType = .edit
} else if sender.title(for: .normal) == "编辑" {
self.backgroundColor = UIColor.red
sender.setTitle("完成", for: .normal)
curButtonType = .done
}
buttonCallback?(curButtonType)
}
ViewController添加如下代码
contentView.buttonCallback = {[weak self] state in
guard let `self` = self else { return }
if state == .done {
let model = EditView.ViewModel(titleStr: "done_title", subtitleStr: "done_subtitle")
self.contentView.viewModel = model
} else if state == .edit {
let model = EditView.ViewModel(titleStr: "edit_title", subtitleStr: "edit_subtitle")
self.contentView.viewModel = model
}
}
6、写到这里,我们停下来,回过头去看一下,我们从来没有强调过用什么架构,但架构却已经成型了。这是MVC,这也是MVVM,这也是单向数据流。什么意思呢,我们现在有Model、View、Controller,我们的Model是ViewModel,我们改变View的途径只有一条,就是改变ViewModel。这不就是最最基础版的MVC+MVVM+单向数据流架构吗。这只是从代码扩展性和通用性来考虑,就已经达到的架构程度,所以架构不是一种思想吗?不是一种思维方式吗?架构是无止境的,需要我们一直思考,而不是局限于某一框架,框架带给我们便利的同时,也给我们带来了约束。
最后用猫神的一句话,这句话我深有感触,“能够使用简单的架构来搭建复杂的工程,制作出让其他开发者可以轻松理解的软件,避免高额的后续维护成本,让软件可持续发展并长期活跃,应该是每个开发者在构建软件是必须考虑的事情。”