我用系统的思想来编程
最近在考项目管理的课程,学到了系统工程这一门课,有一些感触和领悟,特在此记录一下。
这些想法和下边叙述的内容都是我个人在编程方面的一些想法,由于不善写作,可能例子会比较少。有兴趣的朋友,可以在评论区留言,我们做进一步的交流。
先说说我得出的结论:当我们使用系统的思想去处理程序,有很多令我疑惑的问题就迎刃而解了,我会围绕这个思想一步一步的解释,为什么系统的思想能够解决困惑我的问题。
记得我刚开始学iOS那会,我们写的最多的代码就是tableView,我们从最简单也最有问题的地方开始。我看到过很多初学者在写cell的时候,直接在控制器中给cell添加各种各样的控件,这会有很大的问题,当别人想复用这个cell的时候该是多么的痛苦。
显而易见,上边说的就是最低级的方式,甚至连MVC的概念也没用到,好了,接下来我们用一个模型来封装cell。这应该是当下iOS编程中使用最多的方式,cell和模型有很强的耦合关系。这种情况下的cell,往往使用一个独立的文件创建,在初始化方法中创建控件,在模型的setter方法中配置控制。这里的配置就包含了赋值操作和根据模型中的属性控制显示方式的操作。
这么做符合mvc的概念,控制器和view之间通过模型作为连接的管道,同时也减少了view复用的代价。但这样仍然有很多问题,知道了问题的所在,我们的架构才能够进化:
根据业务的复杂程度,我们在模型的setter方法中,要处理的业务也会各不相同。原理上,界面如何显示跟模型有极大的关系。虽然这种方式能够正确显示数据,但无法缓存frame。我会在后边讲到,为什么这种通过setter赋值的方式很不符合编程中的语义要求。
假如说cell中有一些控件是有点击事件的,这些事件中需要发送网络请求。有的人喜欢通过代理的方式把事件传递到控制器中,这么做的优点是能够得到控制器这个对象,因此就能够轻易的使用控制器的属性,比如说添加加载控件到控制器的view上,或者使用控制器中的某个参数,但往往有点击事件,就有数据更新,
依赖于模型setter方法的弊端就显现了出来,你必须要先修改模型后,再去刷新tableview,此时此刻,我们就称之为这个模型被污染了。
一种好的设计方案是,界面的显示有一套模型,数据源是另一套模型,这种方案,我们马上就会讲到。
我见过那种把事件的逻辑直接写到view中的,这样做省却了代理传值的麻烦,且view基本上能保持功能的完整性。当我们在别的地方复用该view的时候,不需要在控制器中写重复的代码。缺点是无法获取控制器属性,即使能够获取控制器,也只有再把控制器属性暴露在.h中才能使用,这就破坏了编程中的封装性。
如果你的代码中很少使用类似于readonly这样的权限属性,那么你就应该去学学这方面的知识,这不是一个属性的事情,而是一种编程思想的问题。
说到这里,我们已经明白,使用模型的setter这种方式开发是一种常见行为,但是弊端也很明显,它并不能成为一个拿得出手的技巧。我们接下来说说view model这一概念,我们简称为vm。vm可以算是model和view的一个中间过程,其实,编程的本质还是处理数据。在vm中我们通过model可以配置出view所需要的任何属性,因此view得到解放,它不必关系这一过程是怎样的,只需要拿到vm中的属性直接显示就行。
同理,vm还缓存了view中各个控件的frame信息。有的人可能会把vm叫做frame模型,这是不合理的,提供frame只是一个小小的功能,提供view直接显示的信息才是它的核心功能。
举个简单的例子,有一个cell,上边有3个label,我在使用vm的时候,根据模型计算出这3个label的attText,然后使用yylabel显示数据,同时,在vm中计算label的frame,因此cell中的代码就很干净,简单。这时候,vm就接管了cell的显示任务,模型作为核心数据,不会被污染。
vm仍然有它的问题,跟新数据算是一个问题,时间的传递它也并没有很好的解决。
上边的两种设计虽然有问题,但仍然需要使用,后来,我冒出来一种manager的想法。manager拥有提供和处理数据的能力,它很想一个超强大脑,能够为view或者控制器提供任何想要的数据和功能。
想想一下,一个表单,有很多项需要填写,manger可以提供一份默认值,可以保存编辑后的值,可以验证数据是否合法,可以获取参数字典等等,它都可以做到,因为这些数据就在它内部保存着,没有谁比他更清楚这些东西。这在语义上是比较符合要求的,如果我们把这些复杂的需求保存在一个模型中,那么模型还是模型吗?
这个manager,我介绍的很简单,能够领悟到这一层的同学,不用说应该也明白。
他特别重要
manager能够很好的处理数据和业务,如果让他处理更多的任务,那么他就会变得臃肿不堪,这不是我们想看到的。因此我们需要再一次进化,我领悟到另外一种编程思想,也是本篇文章的核心思想
系统是一个具有一定功能的,相互间具有有机联系的,有多种要素或构成部分组成的一个整体
系统是一个整体,他让我拨开迷雾,大家仔细想想,其实控制器本身就是一个系统,苹果把他叫做controller也不是没有原因的。在控制器这个系统中,他内部所有的组成部分都是有机联系的,既相互独立又相互联系,他们共同的目的就是完成该控制器界面的显示任务。这就是最典型的一个系统
之前,我经常把控制器想象成一台机器,view是该机器上的零件,view的manager是该零件的管理者,基于这样的思想,写出的代码中,view的地位大于manager的地位,manager为view服务。现在看来,这种思想是有局限性的。
控制器是一个系统,能够完成一定功能的view和manager他们应该也是一个系统,他们的关系既相互独立又紧密相连。
系统是有输入和输出的,写输入和输出,是我最近编程中要研究的地方。
到此为止,代码的复用其实就是系统的复用,事件和数据的操作就是系统的输入输出。一个控制器可以添加多个子系统,子系统根据输入配置view,然后添加到控制器的view上,大致是这样一个过程。
两个以上的元素组成才叫系统,一个元素我们使用manager的思想。因此,一个tableview完全可以是一个系统的输出,一个cell完全可以使用单一功能的manager进行关系,把事件抛给响应的系统进行处理。
这篇文章用时1小时20分,一气呵成,蛋疼的是没有任何代码示例,也算是我自己编程思想进化的一个里程碑吧。果断时间我用这个系统的思想写点例子之后再重新发文。