ios中生产者模式实例:非激励广告架构的优化过程

来源:互联网 发布:小米手机数据迁移应用 编辑:程序博客网 时间:2024/06/06 00:36

作者:代培
地址:http://blog.csdn.net/dp948080952/article/details/52972154
转载请注明出处

前言

这篇博客基于我很久以前在公司项目中做的一个模块,当时刚做这个模块的时候完全没有考虑过设计模式上的东西,一心想着把功能实现了,最后的确是把功能实现了,但是内部逻辑混乱毫无章法,可能当时项目没有太忙,我的mentor就让我不断的优化那个模块,本来不到一个星期就完成的模块,加上后面优化的时间竟然是花了整整一个月!后来也做了一个组内的分享,现在也拿来分享给大家吧!

正文

生产者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。

严格意义上来说是没有生产者模式这一说法的,而是和消费者一起并称为生产者消费者模式,生产者消费者模式的核心思想是在生产者和消费者直接插入一个缓冲区,来达到生产者和消费者间的解耦,而我这里的模块中没有这么一个缓冲区来完成生产者消费者的解耦,所以我姑且称它为生产者模式。

需求分析

首先说一下这个非激励广告的需求是怎样的,我们需要在全局的任意一个地方弹出一个广告,广告形式为轮播图或视频,而这个广告内容需要自己下载,展示完成后还需要删除,一个很简单的功能,我来列举一下具体要做哪些:

  • 启动方法
  • 拉取广告基础信息
  • 缓存图片或视频
  • 清除缓存
  • 展示入口
  • 广告展示
  • 广告点击跳转
  • 广告刷新
  • 保存广告展示记录

第一版功能实现

我们看到这一版中可以说是毫无设计,总共只有两个模块,分别是负责逻辑的helper类、负责展示的VC。这里存在哪些问题呢,首先是helper类功能过于复杂,做了些不应该属于他的事情,比如数据的获取、处理,而对于VC,他的代理方法设计的很不好,而且对于缓存的删除工作直接让VC来做也很不合适(虽然很方便)。

下面分析一下VC这三个代理方法为什么不好

  • saveAD(记录展示过的广告)
  • refreshTarget(刷新广告数据)
  • showStoreVC(跳转到商店页面)

我们看到这三个方法所做的事情分别是记录展示过的广告、刷新广告数据、跳转到商店页面,这些事情严格意义来说不应该是VC应该知道的,他所知道的只是view展示出来了,那个button被点击了诸如此类,这些事情更应该是控制逻辑的helper做的,而且代理这样写的化,这个VC的重用性就下降了,他变得十分具体,不够抽象,只能符合此处一个场景。

第二版优化

我们看到第二版最大的变化就是将数据部分的处理单独拿了出来:DataController,然而改革的还不够彻底,比如删除缓存的任务也应该是dataController做的事情,却只是从VC转移到了Helper中,而VC的代理虽然方法名称改变了,但是实质没有变,耦合度仍然很高!

而这里的生产者模式还不明显,在Helper中start方法中会去调用DataController的下载方法,然后当Helper需要这个下载的东西时就会去问DataController要,生产者没有一种主动的姿态。

第三版最终版

这一版中有三点要说

  1. 分工清晰
    关于数据的操作无论是数据的下载,处理,记录,删除全部交给了DataController,而且接口只有两个一个是拿数据的接口,一个是刷新数据的接口,其他逻辑都在内部实现;Helper只有两个接口一个是start使这一整个模块进入运行状态,一个是showStoreVC,跳转到商店页面;VC只负责展示。
  2. 代理接口合理
    viewDidShow,viewDisappear,confirmButtonClicked,cancelButtonClicked,这几个接口简化了View的生命周期,将这些代理出去,已经足够抽象,Helper根据View不同的状态,进行不同的操作,如此复用性大大提高,因为VC也就那几个生命周期,这些代理已足够使用。
  3. 生产者模式
    这里说的生产者模式主要说的是生产者一种主动的态度,DataController的fetch接口带有一个回调,当调用这个方法时,如果生产者没有加载好数据,那就等待加载好调用这个回调,将数据返回给调用者,如果还没开始加载数据,那就立刻加载数据,成功后通过回调给调用者,如果已经有加载好的数据,则立刻通过回调将数据返回给调用者,然后进行下一个数据的加载。
    这样做有什么好处呢?避免数据的重复下载,当数据正在加载时,调用这个方法不会开启另一个下载,而会等下载好并将其传出去。其次凸现了生成者的主动态度,就是别人需要这个东西了,你生产好了后要主动告诉别人你已经好了,而不是等别人再来问你是不是好了!

生产者消费者模式的思考

在我的这个例子中,确实不能算是标准的生产者消费者模式,但这里Helper似乎又承担了生产者和消费者之间的容器,只不过这个容器的容量是1,而且生产者也会承担缓存储存的工作,当时已经觉得完美的架构现在看来还是有些不足,缓存的储存应该专门有一个容器来储存,将生产者消费者解耦。
所以如果改进我想应该这样改:

@protocol DataControllerDelegate;@interface NonRewardAppPromotionDataController : NSObject@Property (nonatomic, weak) id<DataControllerDelegate> delegate;- (void)startProducting;@end@protocol DataControllerDelegate <NSObject>- (BOOL)produceAd:(NonRewardAppPromotionViewModel *)viewModel;@end

生产者只有一个开始生产的接口和一个代理,代理方法根据返回值确定是否继续生产,在Helper中维护一个容器,当容器量不足时让生产者开始生产,生产完成后在代理方法中将产品加入容器,如果容器没满返回NO生产者继续生产,容器满了以后返回YES停止生成,当容器中的产品被使用后,如果低于设定值,让生产者开始生产。

后记

这个模块是我开始做iOS后不久写的东西,所以希望大家见谅当时水平有限。其实现在看来不是什么复杂的东西,但是在当时看来真的挺复杂,这种设计还是在mentor不停的指导下才不断完善的,现在回头看看此时的自己与那时相比应该是有那么些进步吧!如果你觉得我文中的观点不正确的化,欢迎留言!

0 0
原创粉丝点击