楼主: z74646
1305 1

[其他] iOS开发丨登陆示例的MVC和MVP实现 [推广有奖]

  • 0关注
  • 1粉丝

本科生

75%

还不是VIP/贵宾

-

威望
0
论坛币
300 个
通用积分
0
学术水平
0 点
热心指数
1 点
信用等级
0 点
经验
890 点
帖子
55
精华
0
在线时间
12 小时
注册时间
2014-2-26
最后登录
2016-7-2

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

下面这个问题是很多人思考的: 在UIKit自身的设计中UIViewController是被当做C还是V呢?

QQ截图20160420200120.png

例如我们点击View上某个Button时,可能会使用调用self.navigationControllerpushViewController:animated:方法来跳转到一个新的界面。

在这个场景中,点击事件通过View传递到UIViewController,然后跳转到一个新的MVC。事件的逻辑处理是在UIViewController中完成的,事件的处理者是self(一个UIViewController),可见在UIKitUIViewController是被视为Controller的。

那么第二个问题来了,如果需要在一个UIViewController中实现很复杂的View结构或者subViews之间的动画逻辑,那么如何合理设计UIViewControllerUIView两者之间的关系呢?

在上文中说过,我的想法是通过给每一个UIViewController设计一个对应的XXXContainerView,通过这样的方式来强行分离VC,避免由于V太复杂时出现MassiveViewController。但这样同时也带来了一个坏处:无法像在UIViewController自带的view里添加控件一样,可以将控件的响应方法直接绑定到UIViewController.m文件中,也无法享受类似viewDidDisappear:生命周期方法带来的便利了。

当然,对于有一定MVC经验的开发者,也可以通过类似下面的代码来简化XXXContainerView这一层:

[self.view addSubview:self.topView];

[self.view addSubview:self.midView];

[self.view addSubview:self.bottomView];

虽然任何Demo都不可能模拟出实际项目中遇到的问题,但通过不同横向对比还是很容易看出不同架构的区别所在。接下来,我将以我目前对MVC的理解,给出一个简单的登录示例DemoDemo地址 )。

Demo十分简单,这里仅做简单说明:

LoginContainerView:负责创建用户所能看到的界面,以及将向Controller中传递登录事件和登录参数。

LoginModel:提供接口完成具体的登录业务,Demo中省略了网络层以及存储层。

LoginController:负责创建LoginContainerView,以及当监听到登录事件时,调用LoginModel中的登录业务方法。

由于仅为了明确MVC的结构,所以Demo中对很多实际项目设计到的业务没有具体处理,比如网络请求(Demo中通过本地进行了模拟),数据持久化,以及登录成功后rootViewController的切换。

这里有一点值得谈论的时,对用户输入数据的校验应该放在哪一层来完成呢?为了简化调用,Demo中是直接放在View层来进行判断的。当然,好像放在任何一层都有道理。

上面也提到过,MVC的一个复杂点在于,当View结构复杂之后,如果一个UIViewcontroller来管理多个的复杂的View,势必会造成View层和Controller层的交互变得复杂,并随着业务增长逐渐膨胀,直至崩溃。

那么,为每个单独的View构造一个对应的Controller是否可行呢?

其实UIKit就是这么做的,比如UINavigationController栈中的每一项,都是一个新的MVC,更具体的关于多重MVC的介绍可以参见斯坦福大学公开课: iOS 8开发- 多重 MVC

但是实际开发中对于我们自定义的继承自UIView的类,好像我们都并没有对其创建一个Controller的习惯—除非你愿意加班来完成这些额外的代码。苹果也没有强制推荐这么做—否则,只要设置不能单独创建UIView,只有通过UIViewController才能创建UIView就可以了。

接下来,同样对这个登录示例,我会再给出一个MVP的例子。通过二者横向对比,两者的差异会很明显的体现出来。

登录示例:MVP

在上文MVC登录示例中提到了一点,在一个Controller管理多个复杂View的场景时,CV之间的事件以及参数传递会变得很不顺畅,而实际开发中我们也没有为每个继承自View创建对应Controller的开发习惯。

为什么会出现这么别扭的情况呢?《iOS基于MVC的项目重构》总结中我简单提到过MVCMVP的差异:

我的理解是,MVP是用户视角:所见即ViewMVC则是程序员视角:I control everyone

在群里讨论的时候有人问我这句话如何解释,在这里我详细说明一下。

MVC中的C可以比喻为一个大管家,家里的每个成员(View)需要就餐时,会将每个人的口味偏好告知给管家(Controller),管家将这些信息告知厨房(Model),厨房做好后上菜开饭。

MVP中的P则可以比喻为一个私人秘书,你要吃什么直接跟秘书(Presenter)说就好了,只要秘书(Presenter)拥有调用厨房(Model)的权限即可。

一句话总结,C是家族大管家,P是贴身小秘书。

可能这里解释的还是不太清楚,还是直接用代码来说明吧。

MVP登录示例Demo

Demo的简单说明如下:

View层:LoginViewController负责创建UI,响应交互。当有交互事件触发时,调用自己的preseter的对应方法处理。

Presenter层:LoginPresenter,是LoginViewController的贴身秘书,负责具体处理事件交互,并将处理结果报告给LoginViewController

Model层:LoginModel,完成登录业务逻辑。

对比MVC,以前View的事件通知给Controller可能需要使用blockdelegateView结构层级复杂的话可能还需要使用通知等等。还会多个View共用一个Controller的情况:Controller拿到Model的返回后,需要将返回值交给View并逐级传递下去完成展示。

而在MVP中,每个View都会有一个贴身Presenter来处理交互,这样就将原本MVC中的多View共用Controller的场景进行了拆分,这样避免了出现跨层传值的情况。(示例涉及到一个界面,因为没有模拟这种情况)

架构设计并不是为了给开发者增加麻烦,而是在开发及维护的大层面上给开发者减少麻烦。iOS开发过程中遇到的问题可以来这里学习iOShttp://www.maiziedu.com/course/ios-px/

可能有的开发者会说,这么简单的一个登陆随便写写不就完了,所谓”专家”就会把简单问题复杂化。但是,“一千个人一千个哈姆雷特”这种想法在开发中是绝对不能出现的。


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:iOS MVP controller navigation container 开发

沙发
kael123456 发表于 2016-4-21 23:22:18 来自手机 |只看作者 |坛友微信交流群
收藏了,谢谢楼主分享

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-11-23 18:09