首页 产品 运营 查看内容

前端之Android入门(5):MVC模式

2014-8-12 23:24| 发布者: tianzc| 查看: 375| 评论: 0

摘要: 在上一篇文章中,我们将 View 类单独出来并完成了设计和编写。这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序。模型(Model)就是程序中封装了数据,并定义了操作和处理这些数据的 ...
 在上一篇文章中,我们将 View 类单独出来并完成了设计和编写。这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序。

模型(Model)就是程序中封装了数据,并定义了操作和处理这些数据的逻辑的对象。在计算器的例子中,就是处理输入的操作数和运算符,并计算返回结果。Let’s Go

(注意:示例中直接使用 double 类型来处理数据,但严格来说很多语言的浮点数计算都是不精确的)


一,设计模型的接口


在程序构建之初,我们首先考虑的应该是各模块间的封装和扩展,设计好模块的接口,然后再实现模块的细节,最后把模块组合起来构成整个程序。这就是面向接口编程的概念。


思考一下 Model 类,它主要实现三个功能,1,接受操作数输入;2,接受运算符输入并返回计算结果;3,重置。这些功能主要都是被外部使用的,所以基于此来设计接口,对其它类而言,只需知道该接口定义了什么方法然后使用就行,而不需要了解实现细节。


创建 com.test.interfaces 包,并右键选择 New -> Interface 创建一个名为 ICalculator 的接口(一般接口命名都以大写字母 I 开头)


android_5_interface1


创建 com.test.model 包,并创建 CalModel 类,同时实现 ICalculator 接口。


android_5_calmodel


二,通过栈和递归函数实现计算器算法


计算器的计算规则很简单,从左到右计算,不考虑运算符的优先级,例如:2 + 1 * 2 – 3,相当于: (((2 + 1) * 2) – 3) = 3;这样保证编写的简易性。


我们知道,栈是一种后进先出的数据结构,我们通过一个栈 dataStack 记录输入的运算数和操作符。如图所示:

android_5_datastack


所谓的递归函数,就是接受有限的自然数,通过重复调用自身,最终得到一个自然数结果的函数。算法的核心就是设计这样一个递归函数 popOpOffStack 来对 dataStack 进行求解,过程如图:


android_5_popstack


三,编写程序


按上面的思路,popOpOffStack 可以单独写出,并不需要实例化后才能使用,所以将 popOpOffStack 设为 CalModel 的静态方法则可,如图:


android_5_javapop


完成编写后,可以构建一个栈来测试一下,因为返回的是 double 类型,所以结果是 3.0,如图:


android_5_test1

android_5_test2


核心算法完成后,完成对运算数和操作符的输入的处理并补充其它细节。这样我们的 CalModel 就完成了。


android_5_javamodel


四,通过Controller将Model和View连接


在 Android 的文档中,Activity 是被推荐作为 Controller 的角色,负责视图和模型的协调、沟通。而从 Activity 所拥有的功能的角度看,也是最合适的选择。至此,代码结构也清晰了。MainActivity 将作为 Controller 协调视图和模型,并对一些数据及细节进行处理。其代码如下:


android_5_controller


通过 MainActivity 将模型和视图连接起来后,我们的计算器也最终完成了。可以运行测试一下。


五,结束及回答


本次要点:


1)通过 MVC 设计,使计算器程序有了较好的扩展和维护能力,假如使用另一种计算器算法,只需创建另一实现 ICalculator 接口的 Model 类,并代替原来的 CalMode 则可。当需要增加功能时,可以将代码增加到对应的模块处而不用随意写在一起。


2)这次只介绍了最基本的 MVC 知识,而至于 MVC 模式更高级的使用以及模块间的通信会在后面再讲。从代码的编写中,大家可能会发现 MainActivity 其实很难进行抽象,因为都是一些连接的逻辑和细碎代码。这也就是为什么 MVC 概念提出这么久以来,Model 和 View 的封装技术有了长足进步,而 Controller 却没什么突破的原因之一。作为前端,这方面大家可以对比一下现时流行起来的 MVC 库,对 Controller 角色的处理。而苹果在 Cocoa 中对 Controller 的封装也是很有特色,有机会会介绍对比一下。


3)例子中的细节处理还可以处理得更好,就留给大家修改。另外,有时间的话可以尝试使用经典的双栈算法来实现这个计算器,替换 CalModel 类。


在上几篇文章中大家提到的問题在这里总结回答一下:


1)什么时候用回调和 MVC 的设计为什么可以提高维护和扩展性:对于前者,当我们设计一个模块时,模块除提供方法外,自身发生的事是需要被外界了解时,或外界对这个模块发生的事是“渴望”得知的,这个时候就需要进行回调处理了。对于后者,在这次的文章中讲得比也较清晰了。


2)创建工程时,为什么会多出一些 support-v4、 support-v7 等这些包,这是 Android 的一些高级 API 或组件为在低版本中向下兼容实现而自动加载到工程中的,对自身程序并没有什么影响。



鲜花

握手

雷人

路过

鸡蛋

扫一扫关注最新动态

毒镜头:老镜头、摄影器材资料库、老镜头样片、摄影
爱评测 aipingce.com  
返回顶部