在上一篇文章中,我们将 View 类单独出来并完成了设计和编写。这次我们将完成 Model 类,并通过 Controller 将两者连接起来,完成这个计算器程序。

模型(Model)就是程序中封装了数据,并定义了操作和处理这些数据的逻辑的对象。在计算器的例子中,就是处理输入的操作数和运算符,并计算返回结果。Let’s Go
(注意:示例中直接使用 double 类型来处理数据,但严格来说很多语言的浮点数计算都是不精确的)

一,设计模型的接口

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

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

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

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

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

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

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

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

三,编写程序

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

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

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

四,通过Controller将Model和View连接

在 Android 的文档中,Activity 是被推荐作为 Controller 的角色,负责视图和模型的协调、沟通。而从
Activity 所拥有的功能的角度看,也是最合适的选择。至此,代码结构也清晰了。MainActivity 将作为 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 或组件为在低版本中向下兼容实现而自动加载到工程中的,对自身程序并没有什么影响。

Android:MVC模式(下)的更多相关文章

  1. Android MVC模式

    Android MVC模式 下面是我对Android MVC模式的理解 Model 模型层 包括实体模型层,存放程序中调用的实体. 业务模型层,存放程序中调用的业务逻辑.   View 显示层  An ...

  2. MVC模式下My97DatePicker日期控件引用注意事项

    My97DatePicker日期控件之前在用webform模式开发的时候,只要 <script language="javascript" type="text/j ...

  3. MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  4. 卡卡游戏引擎之MVC模式下的事件处理

    前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...

  5. 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表

    提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...

  6. 在MVC模式下通过Jqgrid表格操作MongoDB数据

    看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...

  7. Android:MVC模式(上)

    很多Android的入门书籍,在前面介绍完布局后就会逐个介绍组件,然后开始编写组件使用的例子.每每到此时小伙伴们都可能会有些疑问:是否应该先啃完一本<Java编程思想>学点 Java 知识 ...

  8. 编码风格:Mvc模式下SSM环境,代码分层管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.分层策略 MVC模式与代码分层策略,MVC全名是ModelViewController即模型-视图-控制器,作为一种软件设计典范,用一种业 ...

  9. Android MVC模式和MVP模式的区别

    MVC模式: 1. MVC的所有通信都是单向的. 2. view传送指令到controller(用户也可以直接将指令传到controller). 3. controller完成业务逻辑后要求model ...

随机推荐

  1. jenkins匿名用户登录 - 安全设置

    最近自己安装配置jenkins,但是跑任务时,发现是匿名账户登录,且提示: 后来发现搭建好jenkins之后,默认就是匿名用户登录的,可以在安装设置菜单里进行账户管理. 1.登录Jenkins服务器, ...

  2. selenium2常用API介绍

    我们模拟web操作都是基于元素来操作的,我们首先要先确定元素,然后这个元素下对应的方法就可以看WebElement的方法. 1.点击操作 WebElement button=driver.findEl ...

  3. Mysql显示所有数据库

    show databases; mysql> show databases; +--------------------+ | Database | +--------------------+ ...

  4. python基础学习笔记——面向对象初识

    面向对象初识 python中一切皆对象. 类有两种: 新式类:在py3中所有类都是新式类 经典类:在py2中只有类本身继承了object类才叫做新式类,默认是经典类 class Person: cou ...

  5. JAVA-基础(三)

    Character 类型字符(Character)是围绕字符型(char)的一个简单的包装器.字符(Character)的构造函数如下:Character(char ch)这里ch指定了被创建的字符( ...

  6. 智能DNS解析之edns-client-subnet篇

    摘要:智能DNS解析是CDN的重要组成部份,所谓的智能也就是根据请求用户来对同一域名作出相应不同解析(目前大多数域名注册商还没提供线路解析的服务),所以CDN的调度准确性也就完全依靠DNS智能解析,但 ...

  7. SDOJ 3740 Graph

    8.9 t3 [描述] 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点 到达. 2. ...

  8. SDOJ 1195 Zhenhuan

    描述 今日又在看甄嬛传,皇上觉得后宫们的勾心斗角太险恶了,有点不好,决定给每个妃子发丝带以让后宫之间和睦相处.皇上一共有N个后宫(标号为1~n),站成一个环形(1号与n号相邻),每个后宫想要ai个丝带 ...

  9. [python学习篇 ] subprocess 子进程

    http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

  10. 常见shell脚本命令整理

    1.cat /dev/null > test.txt txt的文件内容被清空. 2.ls | xargs rm 目录中大量文件的删除 3.查看文件夹下文件个数 ls | wc -w 查看有多少个 ...