• iOS 开发 – 均衡代码职责


    前言

    文章的标题有点绕口,不过想了半天,想不到更好的标题了。本文的诞生有一部分功劳要归于iOS应用现状分析,标题也是来源于原文中的“能把代码职责均衡的划分到不同的功能类里”。如果你看过我的文章,就会发现我是一个MVC主导开发的人。这是因为开发的项目总是算不上大项目,在合理的代码职责分工后项目能保持良好的状态,就没有使用到其他架构开发过项目(如果你的状态跟笔者差不多,就算不适用其他架构模式,你也应该自己学习)

     11783864-acab38493e59bbdb

    OK,简短来说,在很早之前我就有写这么一篇文章的想法,大致是在当初面试很多iOS开发者的时候这样的对话萌生的念头,下面的对话是经过笔者总结的,切勿对号入座:

    Q: 你在项目中使用了MVVM的架构结构,能说说为什么采用的是这种结构吗?

    A: 这是因为我们的项目在开发中控制器的代码越来越多,超过了一千行,然后觉得这样控制器的职责太多,就采用一个个ViewModel把这些职责分离出来

    Q: 能说说你们控制器的职责吗?或者有源码可以参考一下吗?

    面试者拿出电脑展示源码

    最后的结果就是,笔者不认为面试者需要使用到MVVM来改进他们的架构,这里当然是见仁见智了。由于对方代码职责的不合理分工导致了ViewModel层几乎没有业务逻辑,从而导致了控制器的失衡,变得笨重。在这种情况下即便他使用了ViewModel将控制器的代码分离了出来,充其量只是将垃圾挪到另一个地方罢了。我在MVC架构杂谈中提到过自身对MVC三个模块的职责认识,当你想将MVC改进成MVX的其他结构时,应当先思考自己的代码职责是不是已经均衡了。

    码农小明的项目

    在开始之前,还是强烈推荐推荐《重构-改善既有代码的设计》这本书,一本好书或者好文章应该让你每次观赏时都能产生不同的感觉。

    正常来说,造成你代码笨重的最大凶手是重复的代码,例如曾经笔者看过这样一张界面图以及逻辑代码:

     12783864-c74ad67c7948d848

    别急着嘲笑这样的代码,曾经的我们也写过类似的代码。这就是最直接粗浅的重复代码,所有的重复代码都和上面存在一样的毛病:亢长、无意义、占用了大量的空间。实际上,这些重复的代码总是分散在多个类当中,积少成多让我们的代码变得笨重。因此,在讨论你的项目是否需要改进架构之前,先弄清楚你是否需要消除这些垃圾。

    举个例子,小明开发的一款面向B端的应用中允许商户添加优惠活动,包括开始日期和结束日期:

    由于商户同一时间只会存在一个优惠活动,小明把活动写成了单例,然后其他模块通过获取活动单例来计算折后价格:

    小明在开发完成后优化代码时发现了多个模块存在这样的重复代码,于是他写了一个NSDate的扩展来简化了这段代码,顺便还添加了一个安全监测:

    过了一段时间,产品找到小明说:小明啊,商户反映说只有一个优惠活动是不够的,他们需要存在多个不同的活动。小明一想,那么就取消Promotion的单例属性,增加一个管理单例:

    随着日子一天天过去,产品提出的需求也越来越多。有一天,产品说应该让商户可以自由开关优惠活动,于是Promotion多了一个isActived是否激活的属性。其他模块的判断除了判断时间还多了判断是否启动了活动。再后来,还添加了一个synchronize属性判断是否可以与其他活动同时计算判断。最近产品告诉小明活动现在不仅局限于折扣,还新增了固定优惠,以及满额优惠,于是代码变成了下面这样:

    这时候模块获取优惠活动信息的代价已经变得十分的昂贵,一堆亢长的代码,重复度高。这时候小明的同事对他说,我们改进一下架构吧,通过ViewModel把这部分的代码从控制器分离出去。其实这时候ViewModel的做法跟上面小明直接扩展NSDate的目的是一样的,在这个时候ViewModel几乎无作为,基本所有逻辑都在控制器中不断地撑胖它。小明认真思考,完完全全将代码阅览后,告诉同事现在最大的原因在于代码职责混乱,并不能很好的分离到VC的模块中,解决的方式应该是从逻辑分工下手。

    首先,小明发现Promotion本身除了存储活动信息,没有进行任何的逻辑操作。而控制器中判断活动是否有效以及折扣金额计算的业务理可以由Promotion来完成:

    除此之外,小明发现先前封装的活动管理类PromotionManager本身涉及了网络请求和数据管理两个业务,因此需要将其中一个业务分离出来。于是网络请求封装成PromotionRequest,另一方面原有的数据管理只有获取数据的功能,因此增加增删改以及对活动进行初步筛选的功能:

    最后,小明发现其他模块在寻找最优惠活动的逻辑代码非常的多,另外由于存在满额优惠和普通优惠两种活动,进一步加大了代码量。因此小明新建了一个计算类PromotionCalculator用来完成查找最优活动和计算最优价格的接口:

    当这些代码逻辑被小明分散到各处之后,小明惊讶的发现其他模块在进行计算时剩下几行代码而已:

    这时候代码职责的结构图,小明成功的均衡了不同组件之间的代码职责,避免了改变项目原架构带来的风险以及不必要的工作:

     13783864-dfb614fc2ec87d9e

    尾语

    这是第二篇讲MVC的文章,仍然要告诉大家的是MVC确确实实存在着缺陷,这个缺陷会在项目变得很大的时候暴露出来(笔者没有开发过大型项目的弱鸡),如果你的项目结构分层做的足够完善的话,那么该改进更换架构的时候就不要犹豫。但千万要记住,如果仅仅是因为重复了太多的无用代码,又或者是逻辑全部塞到控制器中,那么更换架构无非是将垃圾再次分散罢了。

    关注iOS开发获得笔者更新动态
    转载请注明地址以及作者

    转载:http://ios.jobbole.com/90045/

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯VIP基础练习 矩形面积交
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
    在Linux中如何利用backtrace信息解决问题
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/6000260.html
Copyright © 2020-2023  润新知