漫谈MVC

作者: LuckySunSet | 来源:发表于2019-05-09 01:13 被阅读0次

引言

MVC架构模式,把系统划分为Model - View - Controller 三个基本的部分。其中model(模型层)负责对数据进行封装与存储;view(视图层)负责对数据进行展示以及监听用户的交互;controller(控制器)作为view与model的桥梁,负责view与model间的数据传递,同时处理数据传递过程中的业务逻辑,以及响应view层接收到的用户交互。

下面放上网上经典的交互图:

图片来源于网络

MVC存在的问题

iOS中,model层和view层之间是禁止通讯的,必须有controller层来协调view和model之间的变化。根据职责划分:

   model:封装并存储数据

   view:数据展示、监听用户交互

   controller:协调view和model,处理协调过程中涉及的业务逻辑,响应view监听的交互

分析可知,controller承载了太多的内容,在加上iOS中并未将controller单独分离出来,其自身还要维护一个view,势必会导致controller如同一个巨无霸,动则上千行代码,即便能通过代码归类以及详细注释增加可读性,面对如此大的代码量、如此复杂的业务内容,也会让人倍感头疼。

Controller瘦身之充实Model

提出疑惑:model只是一个纯粹的数据结构吗?

我在过往的开发中,在对json->Object的数据转模型过程中,经历过 获取到数据后为对象属性逐个赋值、为对象添加接收json数据返回对象的类方法、使用Mantle进行映射和使用ObjectMapper进行映射等过程。其中只有作为开发的初始阶段,数据转模型是放在model之外的。这样做,会让model显的比较单薄,而数据转模型代码如果在多个地方都存在,会产生很多垃圾代码。将数据转模型这一逻辑转移到model层后,model相对而言就不会那么单薄了,同时也大大增强了数据->模型的复用性,外部只需要调用接口即可完成。

当然,如果基于对controller的瘦身,还可以将数据向展示出输出的业务转移到model层。比如,我们有一个Persion类,有Int类型的age属性,UI层做显示的时候,不能直接显示Int数据,所以势必会将其转化为String类型。这时候就可以在model层添加一个将age转成字符串的接口,外部需要时直接调用即可。

controller瘦身之分离代理

iOS开发中,UITableView是出现频率较高的控件之一。使用UITableView就很难避免使用其UITableViewDataSource以及UITableViewDelegate这两个协议。往往在这两个协议的方法实现中,代码会占用controller代码的很大篇幅。如果将这两个协议的实现从controller中分离出去,让一个第三者类来实现,一些交互信息通过第三者类的代理或者通过通过block的形式实现,当然这会使架构看起来不那么“MVC”,但是对于controller的瘦身,还是很有帮助的。而且,让controller这位“大佬”多了一个“小弟”,听上去也不那么糟糕(手动滑稽~)

controller瘦身之分离控件的初始化

lazy var buyBtn:UIButton= {         let btn =UIButton()        btn.backgroundColor = UIColor.clear        btn.addTarget(self, action: #selector(buyBtnAction), for: UIControlEvents.touchUpInside)         btn.setTitle(kText("买入"), for: UIControlState.normal)        btn.setTitleColor(UIColor.init(hex:0x109053), for: .normal)        btn.titleLabel?.font=UIFont(name:"PingFang SC", size:16)        return btn    }()

以上是对买入按钮通过懒加载的方式进行的初始化,在UIViewController中,这种组件的初始化比比皆是,即便使用Mark进行了分段,但其庞大的代码量依然是让人头疼的问题。我通常的做法是,为一些组件添加一些通用的便利构造函数,controller需要创建组件时,通过调用便利构造函数,传入一些配置相关的参数,即可得到想要的组件对象,这样代码不仅可读性更强,开发者只需要查看构造函数的实现,即可通过参数判断出组件的构造过程以及构造出怎样的组件对象,同时也更加简洁。当然,这样的局限性同样不小,特别是对于大型的团队协作开发,组件的扩展管理同样会带来很多问题。因此,这种方法需要慎用。

controller瘦身之动画实现向view迁移

@implementation ViewController: UIViewController //弹窗动画效果 - (void)animatedAlertView { AlertView *alert = [[AlertView alloc] initWithMessage: @"这是一条弹窗警告信息"]; alert.alpha = 0; alert.center = self.view.center; alert.transform = CGAffineTransformMakeScale(0.01, 0.01); [UIView animateWithDuration: 0.25 animations: ^{ alert.alpha = 1; alert.transform = CGAffineTransformIdentity; }]; } @end

在以往的开发中,经常会看到这种代码,甚至同种动画效果在不同地方多次出现。动画的实现迁移到view层,我的理由有两个:

1、动画实现与演示建立了依存关系:谁的动画谁实现

2、可以增强动画的复用

总结

本篇文章,做为我在开发过程中,对MVC的理解,和使用上的一些体会,分享给大家。MVC作为经典的架构模式,受到苹果官方所推崇,虽然有其局限性,但是我们如果灵活应用,同样可以得到很好的效果。我们在实际开发过程中,也不必纠结于什么架构模式是最好的,因为没有一种架构能够做到绝对的完美。多学、多看,在学习的过程中,找到适合自己的架构模式。它并不是也不会是一种结果,因为我们面对的需求本身就是动态的,它是一个过程,伴随着我们不断成长于进步,也为我们的开发生活带来许多刺激与惊喜。

相关文章

  • 漫谈MVC

    引言 MVC架构模式,把系统划分为Model - View - Controller 三个基本的部分。其中mode...

  • 基于ReSwift和App Coordinator的iOS架构

    iOS架构漫谈当我们在谈iOS应用架构时,我们听到最多的是MVC,MVVM,VIPER这三个Buzz Word,他...

  • 漫谈培训简史(完结篇)

    前情回顾: 漫谈培训简史(一) 漫谈培训简史(二) 漫谈培训简史(三) 漫谈培训简史(四) 二战结束了,人类文明进...

  • 架构文章

    架构漫谈 架构漫谈(一):什么是架构?架构漫谈(二):认识概念是理解架构的基础架构漫谈(三):如何做好架构之识别问...

  • 漫谈 Clustering

    漫谈 Clustering (1): k-means 漫谈 Clustering (2): k-medoids 漫...

  • Spark整合Ray思路漫谈

    参考链接: Spark整合Ray思路漫谈 Spark整合Ray思路漫谈(2)

  • Spring MVC书目录

    MVC历史 MVC概念 为什么会出现MVC框架 常用的MVC框架 MVC模型的发展轨迹 简述Spring MVC的...

  • 愿人人都有美好的未来

    (动态逻辑漫谈之十一) 前面十篇漫谈主要谈动态逻辑(科学方法),这篇漫谈将人文精神与科学方法结...

  • Flink

    本文主要参考自: Apache Flink 漫谈Apache Flink 漫谈系列 - 序Apache Flink...

  • 漫谈人生 (岩竹呓语·九五)

    漫谈人生 (...

网友评论

      本文标题:漫谈MVC

      本文链接:https://www.haomeiwen.com/subject/xxkboqtx.html