使用简单工厂模式和反射机制优化MVP数据绑定流程

来源:互联网 发布:小米平板2怎么关闭优化 编辑:程序博客网 时间:2024/06/03 18:50

Android项目无论是采用MVP模式还是MVVM模式,都会有一个View层和Presenter层绑定或者View层和ViewModel层绑定的过程。

MVVM模式采用数据绑定框架DataBinding,很多代码都自动生成了,但是MVP模式数据绑定需要我们自己实现。

之前维护一MVP项目,View和Presenter绑定采用简单工厂模式,定义一个工厂类,里面有一个静态方法,用于“生产”Presenter, “生产标准”就是根据Presenter类名,做很多if (name.equas(className))判断,去实例化对应的Presenter。

随着业务需求增加,Presenter越来越多,结果就是造成创建Presenter的这个静态工厂方法里面处理的逻辑越来越庞大,编译时经常出现警告:method is too complex to analyze by data flow algorithm,警告虽然看着不爽,但是能跑起来,所以有一段时间这个问题被选择性忽视掉了。

新来的同事用Presenter写业务,看到这个方法,心情肯定是下面这样的
这里写图片描述

“代码肯定是要优化的,只是我没时间”
这里写图片描述

大概拖了一段时间,这个工厂类实在是让人看不下去了,代码维护和扩展性越来越差,组内一同事想到可以换成工厂方法模式,一个Presenter类对应一个工厂类,这样做解决了一个方法里太多处理逻辑的问题,扩展性也很好,添加一种Presenter,就对应新增一个Factory。

这里写图片描述

问题来了,MVP模式本来就需要增加很多Presenter类和接口,并且大部分Presenter跟业务关联,基本不能复用,这样代码量已经很多了,再创建Presenter对应的Factory类,有可能会造成Android方法数超出限制(当然这个方法数超过65k问题,目前似乎已经有解决方案),所以这个方案也不是最优的。

工厂模式还有最后一种方式没有尝试,那就是抽象工厂模式,这个和工厂方法模式有点像,”提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类”,看定义就知道,他在工厂方法模式基础上添加了产品族概念。

我们也试过这种模式,具体做法是将Presenter按照功能模块划分聚合在一起,因为很多时候,一个模块的功能可能有多个Presenter协作完成,一个按照功能定义的工厂类,里面可能定义多个创建不同Presenter的方法,每个Presenter都跟实现该功能相关联,这样工厂类就减少了很多。

类的数量是减少了,可是划分模块也不是很容易的事儿。很多时候,功能设计耦合度是很高的,部分Presenter因为复用关系,所做的事情可能交叉多个功能模块,这种模糊不清的区分,会失去一个统一的标准,大家开发就会纠结于这个Presenter实例化该放在哪个工厂里,那个Presenter实例化该放在哪个工厂里。
这里写图片描述

有没有更为优化的方案呢?我们先用类图来具象化上面用到的三种工厂模式

这里写图片描述
简单工厂模式

这里写图片描述

工厂方法模式

这里写图片描述
抽象工厂模式

分析一下类图就知道,简单工厂模式“生产产品”只用到一个工厂,会生产所有类型产品,生产过程需要判断各种产品类型,是一对多的关系;工厂方法模式,产品和工厂是同级的,一个工厂生产一种产品,需要很多工厂,是一对一的关系;抽象工厂模式,则是给产品分了一个大类,一个工厂生产多个产品,有多个工厂,是多对多的关系。

后面两种模式会新增很多类,第一种模式,只需要一个工厂类,但是要很多判断,新增产品,就要修改之前的生产引擎,不然判断出错,生产的东西就不是需要的。
这里写图片描述

从结论出发,我们还是偏向于使用简单工厂模式,兜兜转转又回到原地,不同的是,这次我们要使用其变种形式,解决掉判断的弊病。能不能不使用很多if判断条件来决定生产哪个Presenter呢?解决方法还是有的,那就是结合Java反射机制来做。

利用反射,我们可以用包名.类名字符串反射到对应的类,结合项目出发,就是通过”Presenter所在的包名.Presenter类名”实例化Presenter。问题迎刃而解,你只需要传入这种规则的字符串,我就能给你造出一个Presenter,妥妥的!
这里写图片描述

最后,奉上代码示例,为了感谢看完本文的童鞋,文末会贴出福利图一张,不要着急离开哦!
这里写图片描述

这里写图片描述

原创粉丝点击