闲话iOS的MVC设计模式
模式是经验知识的复制应用。MVC设计模式在不同的开发平台有不同阐述和应用。目前在网路上可以搜索出java版本、c++版本、c#版本的,也有ios版本的。我这里也发布这篇关于MVC设计模式的文章,用我的缘走你的路。
写在前面的话
若然不用设计模式,难道就不能开发设计程序了吗?不然。那么设计模式给我们带来什么呢?如果你不学习别人总结出来的设计模式,就能轻松、快捷、真正地解决问题,而且还乐意再来一次,我相信你不需要别人的设计模式了。如果🈶某些问题,让你很挠头,让你不敢再回首,不妨借助别人总结出来的设计模式,来提高一下你的解决方案。
在设计作品中,如果为了使用设计模式而应用设计模式,我认为有点炫技的嫌疑了,大可不必。在iOS APP开发过程中,一般都会涉及到数据处理和UI呈现。如果计算数据的同时还要处理UI的话,会有很多弊端:1. 容易分散精力。2. 不利于复用。3. 重绘画面的时候容易导致重复计算。为了解决这些弊端,我们需要解耦,MVC设计模式就是对症的药。
iOS的MVC设计模式
什么是MVC(Model - View - Controller)设计模式?先看下面的图。(很抱歉,第一次提交后该图没有显示出来。更正之。)
这首先是个分类方面的认识。如,一个程序页面当中有什么东西呢?容易看出来的有数据内容,比如某些文字描述,某些图片内容,还有数据相关的呈现方式,如文字的颜色,背景颜色,图片的大小,位置等。还有别的吗?恐怕一个静态的页面很难勾起这个答案:规则、逻辑、道。这些就是隐藏在程序页面背后的、数据与呈现方式之间的程序逻辑、决策。
程序页面包含:
1. 数据
2. 呈现方式
3. 数据与呈现方式之间的关系。
举个例子,我有四张牌要放到桌面上。要怎样放?呈扇形排布还是呈一行排布,或者成一列排布?四张牌就是数据;扇形排布就是呈现方式;桌面就是我们的程序页面。后面这个“怎样”,就是程序页面背后隐藏的决策逻辑了。
我们可以把这三者叫三个不同的职责。这三个职责可以应用在不同的思维层面上,比如系统架构上,软件架构设计上,程序设计上。只要我们从这三个角度来考虑,就是应用了MVC设计模式了。当然在程序代码层面,iOS的库中在类的命名和职责上都做的很清楚了,如UITableViewController,UITableView,UITableViewCell,NSArray,NSNumber等。我们也可以在设计自己类时,起个好名字,每个类专注且仅专注于其中一个职责。
MVC设计模式就是这样思维模式下的一个产物。包含以下内容:
1. Model <=> 数据
2. View <=> 呈现方式
3. 控制器(Controller)<=> 数据与呈现方式之间的关系
4. 以上三者的交互关系。什么关系?
1. Model 不与 View直接通话,如图中Model和View之间的两黄实线。
2. Model 与 Controller 通话,如图中Model和Controller中两灰色虚实线、当中的绿色箭头、Model上橙色的KVO。
3. View与 controller 通话,如图中Controller和View之间两灰色虚实线、当中的Outlet绿色箭头、黄色的delegate和data source。
4. View上action 与 controller 上的target。
5. Model上KVO发送端与controller上的黄色接受端。
具体步骤:
第一轮:
设计Model时,先只关注数据所具有的属性。
设计View时,先只关注任意一个view的呈现方式,不要考虑view中呈现的数据,需要时从controller中可以获取就行了。
设计Controller时,要关注怎么从Model中获取数据,要关注怎么通知view,以呈现新的数据。与View的通信可以通过用protocol定义消息,view通过delegate来告诉Controller其事件处理过程中的细节,View通过Data Source来询问需要呈现的数据。
第二轮:
设计Model时,可以考虑数据来源的多种方式,数据的变化如何通知到Controller,等等。咱主动一点,不能让Controller拉一下,才动一下。这时,可以加入KVO设计模式或者NSNotification了。这两者都可以达到这样的效果:一旦数据(Model)变动,监听者(这里设为Controller)就收到消息,从而处理该消息。
设计View时,可以考虑如何主动将用户对数据的操作通知到Controller。如增加手势处理等。
设计Controller时,可以考虑是否忽略数据的变化对View的影响。若然要考虑变化,则其频度、缓存等策略又该怎样呢?
直到第N轮达到该设计可以发布的标准。
例子:我们可以用上面放牌的例子。通过仿照UITableViewController,把每张牌设计类似TableViewCell的类,整个桌面设计成一个类似TableView的类,另外看不到逻辑设计成类似TableViewController的类,每张牌的内容设计成某个继承于NSObject的类,包含有名字、图片等属性。有了这个框架,可以向桌面放任何数目的牌,任何不同的牌,可以按照任一不同的方式排列这些牌,等等。可复用性、可扩展性、低耦合等质量属性就具备了。如要展示一下的页面:
闲话完毕。感谢各位读者,希望能给你带来灵感。