在上一篇文章中,我们将 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. C++ 虚函数&纯虚函数&抽象类&接口&虚基类(转)

    http://www.cnblogs.com/fly1988happy/archive/2012/09/25/2701237.html 1. 多态 在面向对象语言中,接口的多种不同实现方式即为多态.多 ...

  2. POJ 3281 网络流 拆点 Dining

    题意: 有F种食物和D种饮料,每头牛有各自喜欢的食物和饮料,而且每种食物或者饮料只能给一头牛. 求最多能有多少头牛能同时得到它喜欢的食物或者饮料. 分析: 把每个牛拆点,中间连一条容量为1的边,保证一 ...

  3. Nginx快速安装

    登录nginx官网,点击download 点击稳定版本 复制箭头上面的内容 vim /etc/yum.repos.d/nginx.repo 修改yum文件 将复制的内容粘贴上去 yum list | ...

  4. Diango 一——URL

    内容概要 1.web框架初识 2.MTV模式 3.Django创建流程和命令行工具 4.配置文件  settings 5.视图函数  views 6.路由系统  URL 7.模板系统  templat ...

  5. Notepad++ 使用正则表达式查找替换字符串

        最近在改一些别人写的PHP代码,由于之前的代码可维护性比较差,因此工作量比较多,因此想找一些高效的方式改一些有规律的代码. 比如: 我想将一些类似$rowss[MaxGetCash_num], ...

  6. Wannafly挑战赛6

    完全平方数 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 131072K,其他语言262144K64bit IO Format: %lld 题目描述 多次查询[l,r]范围内的完全平方 ...

  7. 关于windows系统DPI增大导致字体变大的原因分析

    最近再学习WPF开发,其中提到一个特性“分辨率无关性”,主要功能就是实现开发的桌面程序在不同分辨率的电脑上显示时,会根据系统的DPI自动进行UI的缩放,从而不会导致应用程序的失真. 这个里面就提到了个 ...

  8. 2016湖南省赛----G - Parenthesis (括号匹配)

    2016湖南省赛----G - Parenthesis (括号匹配)   Bobo has a balanced parenthesis sequence P=p 1 p 2…p n of lengt ...

  9. 【转】UML中的几种关系详细解析

    UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...

  10. Welcome-to-Swift-06函数(Functions)

    函数是执行特定任务的代码自包含块.给定一个函数名称标识, 当执行其任务时就可以用这个标识来进行"调用". Swift的统一的功能语法足够灵活来表达任何东西,无论是甚至没有参数名称的 ...