浅谈MVC

2022-03-08 13:52:29 浏览数 (1)

MVC不是一个新概念,只要有一定开发经验的人基本都知道这个东东。但是之前在业界一直不温不火,直到IOS火起来,这个概念开始为人所熟识并加以运用。究其原因,个人以为是之前的人把MVC搞复杂了(例如ASP.net MVC),IT就是这样,技术越复杂就会越难被人理解接受,越不被人理解接受,自然就不会被大家推广使用。

因为之前是搞.net开发了,有过四年asp.net开发经验,虽然说不上钻得有多深,但基本各个方面也都接触到了。之前也把MVC往asp.net开发上靠过,试着去解耦各层的依赖,但是终究扯不清楚。MVC,也就是把系统设计分三层:数据模型、显示视图、逻辑控制器。

Modal:对应在asp.net2.0中,数据模型也就是各个业务实体类对象,这个很好理解,特别是用SQL Server构建好数据库视图之后,可以直接利用.net的O-R Mapping技术Linq to SQL将数据库对象映射为实体对象,非常方便快速。在最近的那个asp.net项目中,我的所有业务实体对象都是这么生成的,总共有近50个。大致分两类:一类是直接以表对象映射过来的实体模型,一类是以数据库视图对象映射过来的实体模型,相对而言,后一类更易于理解与使用,往往更贴近业务需求。

View:对应的就是设计出来的web页面,也就是各个.aspx或者.html页面。总之就是能呈现在用户眼前的东西。

Controller:对应的就是每个.aspx页面对应的.cs文件或者.js文件中的代码,这其中最重要的也就是各个响应事件的处理逻辑,因为Controller的核心作用就是控制View的动态呈现,而这些呈现直接相关的就是这些响应事件咯。

但是对于一个后台处理逻辑比较复杂的程序而言,其实以上三部分也只是这个系统中的一部分——前台展示与较浅层次业务逻辑处理部分,但是后台数据处理部分没有涉及到,这也是困惑了我近两年的一个疑问,与传统的三层架构设计(界面展示层、业务逻辑层、数据访问层)揉在一起后,更是苦不堪言,这个稍后再谈,还是先说说Web开发中的最简单的MVC思想运用。

在Web开发中,要说到MVC运用事例,以表数据的显示与处理最形象、也最好理解:一个表格控件若需要显示出一页数据,需要我们绑定一组数据,这组数据通常就是一个对象列表,而这些对象实例对应的那个实体类,就是我们的Model,而最终呈现在页面中的表格内容就是我们的View,那Controller在哪呢?Controller在这里分两部分来讲可能更好理解:一部分是控制数据呈现,例如某个字段数据是直接显示文本内容还是根据不同数据值显示不同图片,这个由Controller来决定;另一部分是呈现完数据后界面与用户的交互处理,典型场景就是,用户看到这些数据后,可能会挑某些单元格点点,而点击了之后,系统的处理逻辑也属于Controller的范畴。这样一说,Web开发中的MVC应该就比较好理解了。

那么移动开发中的MVC呢?个人喜欢比较学习法,在学习IOS开发的MVC运用时,总是不由自主地拿去跟Web开发中的MVC模式做比较。相较web开发,IOS中的MVC思想运用得更直接、更彻底。

Modal:依然是你需要定义的各个业务实体类(Entity),貌似有一项叫Core Data的技术,也是一项对象-关系映射技术,类似于.net的Linq技术,不过笔者今年才开始涉入IOS开发,这一块的技术还没接触很深,所以也不敢赘言。

View:就是在xib文件中设计出来的那些View对象(storyboard暂时我还没去学,不敢妄下结论哈);

Controller:就是各个ViewController对象;

确实很简单明了,但是在实际开发中,还是发现有不少问题需要注意,例如最近遇到的一个问题就是:有一个较复杂界面,需要根据上半部分子视图中日期的变化,动态更新中部表视图数据,界面支持日期一栏左右滑动,以切换日期,日期切换后需要同步更新表视图数据;另外界面底部还有命令按钮视图,支持表数据提交操作;

一开始笔者将这个界面进行了分拆,分为四个View来实现,且每个View对应自己的ViewController:顶部一个是导航NavView,一个日期切换DateView,一个表视图TableView,底部一个命令按钮操作CommandView,后三个作为NavView的子View加到其contentView中。但是界面与响应事件设计完成后,在处理网络请求数据时,开始发现问题:三个子View因为都涉及网络请求数据,各子View所需的Rest服务请求处理逻辑都分别写在各自ViewController中,这样不同View的数据交互就变得很复杂。

在DateView中发起GetDateTime服务请求并获取到数据后,需要将日期数据传递给TableView以发起获取表业务数据并加载到页面的操作,但因为这两个View是兄弟关系,而非父子关系,所以数据的传递只能采用发通知或者写委托的方式来处理,若真这样进行处理,数据传递逻辑就设计得有点复杂了。以往的开发经验表明,一个如此简单的数据传递处理,不值得用此“牛刀”。

于是渐渐有了用一个ViewController管理多个View的想法。到网上搜了一把,看了Apple推荐的关于一个ViewController管理多个View的设计方式——同层子View建议用同一个ViewController来管理——真有种相见恨晚的感觉。一旦这样设计,数据交换逻辑就简单多了,可以将所有网络请求都在一个ViewController中集中处理,各个子视图只管各自子控件的布局、显示。

当然,在实际开发过程中,还是遇到了一些小问题——主要是xib文件中控件、事件与代码中属性、变量或方法的连接问题。(这个多半还是因为笔者对IOS开发工具不熟所致,还望见谅)

因为只有一个ViewController,所以所有响应事件的处理逻辑都在此ViewController对象中声明与实现。但是,若每个子View都使用各自xib文件进行设计,那事件的连接线似乎无从接起,因为貌似无法跨xib文件进行连接。目前想到的解决方案有两个:一是不用连接线,而就在ViewController中初始化完子View后,挨个注册响应事件(这是根据Web开发经验而来,但还未100%验证过)。

另一个法子,也是目前我在项目中使用的法子,即是只用一个xib文件进行设计,每个子View的界面设计工作都放到ViewController对应的xib文件中来设计,这样界面事件就能轻松跟ViewController中事件响应逻辑连接起来了。不过此法也有需要注意的地方:1、各个子View一定要跟ViewController中的子View属性或变量用连接线连接起来;2、还是没法包含太多子View(当然,对于移动开发而言,貌似也不应该包含太多子View)。

另外,对于第二个法子,因为处理逻辑集中,必然会使这个ViewController.m文件代码量很大,可以尝试使用Catalog将代码分拆,不同子View的事件逻辑用不同的Catalog类实现;这样ViewController.m主文件的代码量就能降低,代码维护性、可读性也更好。

结语:因为IOS开发还只能算个新手,所以MVC目前进境也就到此了,欢迎高人不吝指教。

似乎忘记谈谈MVC与Web开发中常用的三层架构模型的区别与关系了。

三层架构设计即是界面展现层、业务逻辑层(BusinessLogic Layer,简写BLL)、数据访问层(Data Access Layer,简写DAL)。

这两者很像,但是仔细考量其实还是不一样,两种系统设计方式分别侧重不同的开发场景:

传统三层架构设计更适合Web开发,因为Web系统重在服务端数据的大量展现,数据从用户界面产生后,最终会流转、持久化到数据库中。Web系统是以数据(或者呈现数据)为中心的,这即意味着DAL层很厚,而且“偏硬”些,将DAL层中数据库表数据映射为业务领域模型对象的处理,一般会放到BLL的下半部分,貌似有个术语叫“语义层”。

而MVC系统设计方法更适合客户端开发,特别是移动客户端开发。在MVC中,似乎数据流转到M就停止了(虽然也有很多基于服务端数据的APP应用),这是因为客户端数据量相对更少,客户端系统是以功能为中心的,相较于数据是什么,用户更关心数据是如何呈现的(或者叫数据的流转方式)。

当然,也可以像笔者一样,在Web开发中运用简单MVC设计思想,不过基本就只能将M对应到语义层咯,再往下的话设计就会变得很痛苦了。

0 人点赞