轻量级TableViewController(MVC深究)
从前了解到MVC,学习到这个架构,以为已经可以了,直到这段时间看到这些优秀的文章,才发现自己是如此看小它,是多么误解它,甚至这么不了解它,所以记录这篇文章以总结对此的理解~
我记得有不少大神这么说的,“如果你单页的代码行数超过150行,那么就是需要滚动页面查看代码了,这个时候你的代码就需要优化了,如果单页代码行数超过250行,那么你的代码需要滚动多次才能查看完代码,这个时候你的代码就需要重写了,优秀整洁的代码标准是100行以内,甚至最好是50行以内,那样的话,你的代码就很不错了”,当然,这段总结性语句不是一定是对的,只是见仁见智,不过这里面就能很好说明,我们的代码,我们的项目应该具有可维护性,低耦合,高复用性,现在提出的各种架构,类似MVP,MVVM,VIPER,就是出于对这些性能追求而提出的。
即使从前做过针对MVC学习的项目,我也认为学习它,应该从类似UITableViewController,或者UICollectionViewController等这些类来学习更好。就用UITableViewController来举例深入了解MVC
一开始写过这个类的人都明白,这个类每次写出来的代码行都是上百,甚至有时候上几百的,导致它成为项目中最大的文件。还包含不不少的不必要的代码,是它不需要履行的责任都包含在里面,所以这样的Controllers的代码救护是复用率最低,可维护性差,一个项目下来,会发现整个项目变得很脆,很容易糊一碰一修改就会bug或者改头换尾的。所以,许许多多大神对此投入研究提出不少架构,为此做瘦身,提高性能和代码质量。
苹果官方这有这么一段关于ViewController和MVC的说明:
大概就是表明了ViewController是应该定义为去协调model和view的一个中间类,当view发生了改变,应该由这个类告诉model,而model处理的数据,也应该由这个类反馈给view,,从而实现view上的改变,这个也是苹果提出的,也是MVC发扬的由来。(官方MVC文档介绍(1)官方MVC介绍文档(2))
关系图如下:
说到这里应该了解到什么是MVC了,也就是Model-ViewController-View。(这里还有一个关于MVC等架构图示的总结)
但是怎么实现?从这里开始,我就觉得应该从UITableViewController开始入手了,它会是我们学习和实现MVC的一个很好的例子,同时现在大多数的应用都或多或少,甚至整个App都是这个类组成的。(关于UITableViewController这是一个学习这个类的一篇很好的文章)。
为什么我提出UITableVIewController是一个学习MVC的一个很好实例?是因为它本来就是一个MVC,很好的MVC例子,甚至从它身上学习MVC你会觉得有一种焕然大悟的感觉。
在UItableVeiwController中有那么一个协议总是会用到的——Data Source
这上面是一个例子,同时是我们使用UITableViewController经常使用的方法,一看,他们在我们的TableViewController中多占地方,而且上面也提到,Controller应该只负责协调model和view之间的沟通,而不是负责数据处理,因此如果我们把它放出来到一个单独的类里面,你会觉得如何?
那就是,整个UITableVeiwController瞬间少了不少行数~这个类就明显瘦了一圈,同时这个Model还能提取出来用到不同的类中,例如其他的UItableVeiwController和UICollectionController中,这样就是复用,这样就可以减少对相似类的创建,进而提升整个项目代码的质量。
至于这里面怎么实现创建cell,在这篇文章也有提及一点,那就是取决于个人习惯,可以用delegate,属性,也可以使用block,而我个人比较建议学着使用一些block,但不要滥用block。
从这个例子中,可以总结出,尽可能,或者说一定要把业务逻辑,数据处理,以及网络请求等所有关于数据的都移到Model,这就要涉及,到底数据是什么,我想说,在这里,数据不仅仅是说后台那一堆符号,或者一些逻辑运算,甚至在view上面要显示的name,secure,count等都是我们所说要归纳到Model中的数据。如果你想基本分离,实现Model和controller低耦合的话,我建议你可以用一个store类作为一个数据仓库,同时store负责提供API给Controller进行获值和回调,下图就是我提供给你的一个图示:
这是关于Model和ViewController的一个图示同时我也建议这么做,这样做的好处是Data的改变不会给整个项目带来很多的麻烦,同时这样子就是一种低耦合,高复用性的表现
而在UITableViewController里,TableViewCell就是我们在这个模型中的view,可能有人看到这里会想,对啊,是哦,这是个view啊,即使那些无意识自己创建cell这个类,也不一定有意识到这个本身就是一个view。
在我们创建ViewController的时候,本身就不建议在其中构建负载的view,反而建议使用Interface Bulider或者代码封装到一个UIView子类中。这样子,你可以做到一个更加轻量级的ViewController,
我再次以一个图示总结一下上面我提及的:
这个就是所谓MVC的完整图示。
可能不少人在创建Data Source和Cell这两个类的时候,会以传入indexPath这个参数来进行对Cell的创建,就像这样:
(虚线仅表示其之间是间接传值的)
可是我告诉你,最好不要这样,当我们有多个TableViewController和UICollectionController的时候,你会因此创建很多个相似的类的,我们应该让它拥有可复用性,这也适用在Cell上,让Cell可以做到一对多,同时,尽可能减少项目相似文件和相似代码的产生是一个好的程序员必备的责任,也是好的项目,高质量的代码必须有的。
在这里,我们可以观察一下这个Data Source,就会发现,其实他们都是围绕一个数组组成的,所以,其实我们可以以数组作为API外供,这样子Data Source就不会如上图那样,过于依赖indexPath这个参数,至于Cell的复用,我建议看看这篇文章,最好先自己想一下在看。
这里面的一个观点,我必须强调一下,也是我认为好的思想,那就是View的状态应该在其内部控制,而不要在别的地方实现,就像你自己不应该依靠其他人那样。
同时文章推荐了几个文章和讨论,是关于建议使用view的类目,使得该类的Data和view分离,使得他们分离更加清晰,还有就是提出了一种方案,对于UITableViewController,可以添加一个subVeiwController(未完待续)
版权声明:本文为博主原创文章,未经博主授权不得转载。