通过Observer(观察者模式)来看Android的MVC

本文深入探讨了在Android开发中观察者模式的应用,并通过实例展示了如何将其与MVC模式结合,实现更清晰的代码结构和更好的组件复用性。通过观察者模式和MVC模式的重构,文章详细阐述了如何优化UI组件间的交互,以及如何将业务逻辑与UI逻辑分离,提高代码的可维护性和可扩展性。

Android工资翻倍篇之观察者模式

android中运用最多的observer模式就是listener的使用
比如一个activity中点击button响应onClick事件
View就是一个被观察者(observable)
这个View里面一定有一个onClickListener观察者,activity中调用的view.setOnClickListener(this)就是对监听器观察者的初始化,将观察者添加到被观察者中。
当然这个activity implement了onClickListener接口,所以自身就是一个观察者。
然后当我们点击View的时候,view里面的逻辑就调用了我们初始化时listener的onClick方法。就是activity的onclick方法。


下面将从Observer模式的重构中分析mvc模式

两个仪表盘,一个显示燃烧率的曲线,一个显示推力的曲线,曲线的变化由滑动条tpeak值来确定,当最高值tpeak变化时,仪表盘也会发生变化


下图中的changeListener是滑动条滑动是的变化监听器。ShowBallistics是显示弹道的类,里面有burnPanel()燃烧仪表盘和thrustPanel()推力仪表盘两个方法还有valueLabel():jLabel用于显示0.24值的变化。
ShowBallistics中持有两个仪表盘BallisticsPanel,show类是一个观察者,滑动条是一个被观察者,当观察到滑动条变化时,就调用burnPanel得到Panel对象,调用Panel对象的setTpeak设置峰值,通过公式绘制出曲线。
图中BallisticsPanel是MVC中的V,showBallistics是C,C中含有两个V,这种关系是紧耦合的


slider是滑动器,是一个被观察者,show中的slider()方法中添加了监听器this,他本身实现了ChangeListener

show中的stateChaged方法在滑动器变化的时候被调用,里面的两个仪表盘Panel对变化的tp值进行了set,这样,当滑动滑动器时,tp值发生变化,然后引起仪表盘的曲线变化



也就是说上面的方法不是最好的,因为他有点曲解了观察者的模式,我们不应该让showBallistics自身注册slider的监听事件,而是应该明确的知道showBallistics中的两个仪表盘才是需要更新的对象,所以要做到让仪表盘注册监听事件。所以需要进行改进。

改进后的类图中,仪表盘panel2实现了ChangeListener,这里interface用圆圈表示不用三角虚线表示,是因为没必要写明listener中的方法了。
上面类图明确的把观察者从showBallistics变为了仪表盘。思路更加清晰了。
让仪表盘自己作为一个观察者的话,那么他初始化的时候就必须加入被观察者对象参数slider(滑动器),才能正确的进行观察

仪表盘自身收到数据变化通知之后就会重新绘制曲线图

用observer模式重构之后已经清晰很多了,让感兴趣的类自己作为一个观察者

重构之后还是有不足之处,出现了代码重复的问题,所以需要再次进行重构
重点来了

我们可以在panel视图和show控制器之间添加一个
tPeak模型,将视图和控制器进行分离。实现MVC模式


视图和控制器是紧耦合的,mvc就是希望把视图和控制器进行分离,这样控制器也能进行重用。比如分离LoginActivity中的login逻辑到LoginPlatform中,这样在修改密码应用新密码的时候可以重用LoginPlatform。

下面利用MVC模式进行重构
可以发现其实两个仪表盘和标签需要的数据都是tpeak值。所以可以将tPeak值算作一个模型进行分离,让Tpeak作为一个被观察者


滑动条移动会驱动ChangeListener去更新Tpeak对象,反过来,Tpeak对象的改变会通知标签和面板容器对象,然后让这些对象重绘他们自己。
这样设计之后,很明显的,showBallistics中不必再持有Panel类了,只需要持有Tpeak类,通过Tpeak的改变来通知Panel进行重绘,这样就实现了视图和控制器的分离,将视图和控制器之间的紧耦合关系,使得程序的可复用性和可扩展性得到了很大的提示。
在android开发的时候,我们也应该尽量的将控制器从Activity中分离出来,这样可以让Activity显得更加简洁易懂,如我前面提到的将LoginActivity中的login逻辑分离出LoginPlatform,这样在重置密码后重新登陆功能中就能够复用LoginPlatform.login().
有人认为Activity本身就是controller,但是不管如何逻辑代码都不应该大量的出现在Activity中。



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值