`
univasity
  • 浏览: 809971 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

[资料]MVC在J2ME项目中的应用之MVC慨述

    博客分类:
  • J2me
阅读更多

内容提要:

  本文简要的介绍了MVC模式的思想,并分析了MVC模式的利弊,最后结合MIDP平台给出几种常见的MVC模式实践。相信此文对任何一个使用midp平台的商务程序开发者都或多或少的有所帮助。

  正文:

  初识MVC模式

  第一次认识到MVC模式是从Microsoft MFC框架所采用的“文档-视图”模型开始的。第一次接触到这个概念让我兴奋不已,很长时间困扰我的程序框架问题似乎迎刃而解了。而后我翻阅了GOF一书中对MVC模式的描述,增进了对这个模式的一些理解。应该说MVC框架是程序设计领域的常青树,也是GOF模式中最为重要的模式之一。这一经典的模式被广泛的使用,有太多的程序构架在这一框架之下,从早期的卓面Application到现在流行的Web。并因各自的需求不同,MVC有了很多的变种。了解MVC是每个程序设计人员的必修课,最好能够达到熟练运用的程度。

  我并不打算详细介绍这一模式,因为细节比较复杂,我口舌拙笨也不容易说清楚,大家应该参阅一下有关模式的书籍,任何一本都比我要讲的清楚。所以此处就一带而过。MVC模式是Model-View-Controller的缩写,中文译为“模型-视图-控制器”。MVC的核心思想是分离。Model就是对实体类的抽象;View就是Model在屏幕上的表示;Controller就是协调者。可能有朋友发现Controller的描述多少有些含糊,不要着急,这个一会还要谈到。大概因为太过有名,MVC模式的每个实现都出处很大,但他们却都叫做MVC!!搞得初学者一头雾水。往往滥用,最后搞得M.V.C.三者之间的协调很混乱。这其实并不是他们的错,理清思路的关键还是刚刚提到的一个词“分离”。尽管MVC实现不同,但是思想是一致的。

  MVC模式的利与弊

  先谈优点:

  1)将M.V.C.分离可以让不同的专家负责不同的模块,一般情况下,M部分由熟悉数据库,网络传输的专家来负责;V则交给对UI有研究的专家。这对于项目的管理者而言是多么的诱人,分工意味着可以提高效率并可以按照传统的责任划分来处理软件开发过程。对开发者而言也可以专心于一个领域。这样做的前提是接口要明确,MVC的分离思想正为其提供了基础。

  2)一旦V的部分发生变化,可以迅速的重构而不必引起整个工程的返工。如今的软件表现层的部分变化实在是太快了…

  3)M的部分,因为足够抽象,可以方便的重复利用,符合OO的思想。另一方面我们可以利用JUnit等单元测试工具对M进行测试,保证工程质量。

  谈完了优点再来看看缺点:

  1)利用MVC模式(也包括近代的其他一些模式)暗示我们通过多产生一些类,来提高程序的可读性与健壮性。附带来的缺点就是类的数量的膨胀。说句笑话,MVC就好像是发面时用的速效粉一样,是最为方便的代码膨胀剂,相信大家都深有体会:)

  2)MVC虽然定义了M.V.C.个个部件的含义,但并不具体,而且没有非常明确的固定三者之间的联系。所以一直以来除了View没有争论外,其他方面都有很多争论,大家都想把自己的理解作为正解。尤其是“Model到底是屏幕数据的集合还是实体数据”、“控制器的作用”是两个经常争论的问题。前面提过MVC变种很多,这也给初学者留下了不少的陷阱。后面结合实例将会分析几种常见的做法。

  3)MVC的实现成本偏高。但请注意是这是相对的,一般而言项目越大,越可以看出其优势。

  常见的MVC模式实践

  下面将会介绍在midp平台几种常见的实践,最后是我习惯的做法

  M—V形式(或者MC—V、M—VC)

  这也是在j2me中一种惯用的方法,精炼的说这种方法是以屏幕为组织单位的,因而很适合RAD工具的开发思路。一个屏幕及其控制被抽象成一个VC类,而这个类中有一个私有的Model对象来代表屏幕上要用到的数据元素。屏幕对象并不保存任何的实体数据,这些数据被组织在了Model对象中。大概因为屏幕对象很直观,控制器的作用也不明晰(它绝大部分的功能被view或是model取代,具体取决于你的实现),所以也常常称呼为model-view模式。形式如下:

class MyFrame extend Frame{
 private Model model;
 private StringItem name;
 MyFrame(Model model){
  this.model=model;
  name=new StringItem(model.getName());//请求模型的数据
  append(name);
 }
}

class Model{
 private String name="M-C pattern";
 public String getName(){//这是一个服务接口
 return name;
}
}


  上面看到的是个典型的M—V模型,我们可以理解这种以屏幕为核心的分离的含义。Model组织起屏幕的数据,view向Model索要其希望显示的数据,注意这一操作一定要通过预先协商好的接口访问,而不是直接操作。如果出现复杂的事务逻辑(用户选择的某种操作),有人将其放在Model端,也有人放在View端,但一般上放在Model端,这时Model带有严重的Controller的色彩。

  这种形式的优点是非常的直观,也有限的分离了显示和数据。如果常看j2medev.com站长Mingjava的文章,可以看到大部分他写的例子都是这种模式。并且这种模式也常常用于RAD工具。

  这种模式的缺点是它与RAD工具一样鼓励你从屏幕开始思考问题,这往往让你陷入RAD的陷阱——不先考虑事务的流程,而是从用户接口直接下手去分析问题,这往往扼杀了你的全局构思。

 

    Sun blueprints: Smart Ticket中使用的MVC模式

  著名的蓝图程序Smart Ticket中使用了MVC模式,并且这一模式帮助Sun的程序员在MIDP2发布时,快速的将Smart Ticket的view部分从MIDP1.0 更新到MIDP2.0。

  Sun针对MIDP的特点,设计并改进了这一模式,在SUN的解决方法中是一个很标准的方法,只是 Controller变成了一个巨大的事务处理器,所有由UI对象收集到的用户的需求都转发给Controller处理。Controller内部保存了一组常量。在一个dispose(int id)形式的方法里一个巨大的switch case语句根据比较不同的常量,处理不同的请求。这种技术有时也将Controller称为处理器,或者屏幕导航器。这种模式的提出者主要是要集中处理j2me里频繁的画面导航。

  很多人都觉得,在j2me中将Controller改造成巨大的事务处理器是一个很好的方法。我对此持保留意见。

    iFeedback 中简化的MVC

  为了大大减少类的数量,iFeedback的作者,将MVC封装到一个类中,用不同的方法来代表对这三者的分离,这种举动证明对减少类的数量又很大帮助。

 

public abstract class MVCComponent implements CommandListener {
 // Set from outside at beginning
 public static Display display;

 // Returns the screen object from the derived class
 public abstract Displayable getScreen();

 public Displayable prepareScreen () throws Exception {
  if ( getScreen() == null ) {
   initModel();
   createView();
  } else {
   updateView();
 }
 getScreen().setCommandListener ( (CommandListener) this );
 return getScreen ();
}

public void showScreen() {
 try {
  display.setCurrent( prepareScreen() );
 } catch (Exception e) {
  e.printStackTrace();
  Alert a = new Alert("Error in showing screen");
  a.setTimeout(Alert.FOREVER);
  display.setCurrent(a);
 }
}

// Initialize. If a data member is not backed by RMS, make sure
// it is uninitilzed (null) before you put in values.
protected abstract void initModel () throws Exception;

protected abstract void createView () throws Exception;

protected abstract void updateView () throws Exception;

public abstract void commandAction(Command c, Displayable s);

}

 


  因为都在一个类里面,你在也不必被MVC三者之间的关系操心了,这种退化的做法,是对MIDP有限资源的妥协。

  我的习惯做法

  下面结合我对MVC的理解和大家交流一下。我使用的是一种UML标准的做法,最大程度上对的体现分离的思想。首先和大家交流一下词汇表:

  View代表屏幕。

  View通过预先商定好的接口向Controller索要数据,View同时收集用户的输入,View并不处理这些输入,而是根据不同的输入回调Controller不同的方法。通常View的子类使用UI后缀。

  Controller 控制器

  提供View调用的接口,负责和model交流。控制器和View共同担负起和用户交流的作用。

  Model 泛指一系列的实体对象

  需要注意的是我理解的Model并不是屏幕数据的组织单位。Model代表一系列的实体对象。由Controller跟Model交流。我觉得RAD工具中常常将Model代表屏幕数据的集合正式导致MVC概念混乱的一个原因。RAD工具中Model,大体相当于这里的Controller所起的作用。

 

 


  控制器并不总是联系着Model,有时只是依赖关系。并且Controller往往通过Model的对应的生命期类来获得Model对象。在这种形式中,层层隔离,View与Controller紧密相连,而Model有很高的独立性,可以很好的重用。

  一般的结合UML设计的过程,对MVC的各个类有相应的命名习惯。

  View  称为Boundary 类(边界类) 以UI结尾

  Controller   称为 Controller 类(控制类)  以Workflow结尾

  Model   称为Entity 类(实体类)  以Entity结尾或者没有尾缀

  Model对应的Lifecycle 类(生命周期类)  以Locator结尾

 

 


  边界类和控制类的基础类如下

 

BaseView.java
/**
* @author Favo
*
* 视图类
*/
public abstract class BaseView {

 public abstract Display getDisplay();

 /**
 * 简单的返回包装的屏幕对象,不要做任何准备屏幕的操作!
 */
 public abstract Displayable getScreen();

 /**
 * 创建屏幕
 */
 protected abstract void createView() throws Exception;

 /**
 * 更新屏幕
 */
 public abstract void updateView() throws Exception;

 /**
 * 返回控制器
 */
 public abstract BaseController getController();

 /**
 * 准备屏幕
 * 返回准备好的屏幕对象
 */
 public Displayable prepareScreen() throws Exception {
  if(getScreen()==null){
   createView();
  } else {
   updateView();
  }
  return getScreen();
 }

 /**
 * 显示当前屏幕
 */
 public void displayScreen(){
  try{
   getDisplay().setCurrent(prepareScreen());
  } catch (Exception e) {
   e.printStackTrace();
   Alert al=new Alert("Error",e.toString()+'\n'+e.getMessage(),null,AlertType.ERROR);
   al.setTimeout(Alert.FOREVER);
   getDisplay().setCurrent(al);
  }
 }

}

BaseController.java
/**
* @author Favo
*
* 控制类
*/
public abstract class BaseController {
 public abstract BaseView getView();
 public abstract void setView(BaseView view);
}

 


  注意到这些基础的类并没有向MFC框架那样产生完整的框架,而是设计成了抽象类,一来希望强迫大家实现抽象类(防止出错);二来希望增加一点灵活性。所以两个类之间的通信就要靠大家撰写的子类的构造函数了。一般我的习惯是,初始化好控制器,然后将控制器作为参数传给边界类的构造函数,由边界类的构造函数来回调控制器的setView()来实现的。这些步骤是一定要有的,不然会NULLpointerExcpetion哦。

  尽管理论上可能很清晰,但实践带来的复杂性是惊人的。这正是软件开发的问题,太多的细节困扰这开发者对大局的把握。本文接下来,将结合最后这种设计思想,给出一个完整的设计实例。帮助大家从实践的角度理解运用这一模式。敬请大家期待。

分享到:
评论

相关推荐

    基于MVC模式的J2ME应用程序框架设计

    为了解决这个问题,开发者开始探索在J2ME中应用Model-View-Controller(MVC)模式来构建应用程序框架。 **MVC模式的概念** MVC模式最初由Trygve Reenskaug提出,主要目的是将应用程序的业务逻辑、用户界面和数据...

    NIIT第三模块考试试题及答案 mvc3 J2ME

    6. **实践应用**:理论学习的同时,应结合实际项目练习,例如开发简单的J2ME手机游戏或使用MVC3构建Web应用,这将有助于巩固所学知识,并提升实际操作能力。 总的来说,这份资源对于正在学习J2ME和MVC3的学员来说是...

    NIIT MVC4 MT2 J2ME试题与答案

    这些文件可能包括练习题、解答、示例代码、项目实践以及可能的讲解材料,帮助学习者深入理解MVC4如何在资源有限的J2ME平台上实现和应用。 知识点详述: 1. **MVC设计模式**:模型-视图-控制器架构是一种将应用程序...

    j2me手机程序mvc模型设计

    #### 二、MVC在J2ME中的应用 J2ME(Java 2 Platform Micro Edition)是为移动设备和嵌入式系统设计的一个版本的Java平台。在J2ME平台上实现MVC模型,可以显著提高代码的可维护性和可扩展性,同时简化开发流程。 1....

    j2me实现mvc的框架源码

    由于信息有限,无法提供更具体的细节,但可以推测这个"kb ox1.03"是MVC框架的一部分,用于在J2ME项目中引入和使用。 **相关知识点** 1. **J2ME**: Java 2 Micro Edition是Java平台的一个子集,专为资源有限的...

    MVC设计模式在客户端的应用.pdf

    ### MVC设计模式在客户端的应用详解 #### 一、引言 MVC(Model-View-Controller)设计模式是一种广泛应用于用户界面设计的经典架构模式。...希望本文能够帮助读者更好地理解MVC设计模式,并在实际项目中加以应用。

    基于mvc实现的j2me 通讯录

    在本文中,我们将深入探讨如何利用MVC架构来构建这个通讯录应用,以及在J2ME环境下如何实现其主要功能。 **一、MVC设计模式** MVC是一种软件设计模式,它将应用程序分为三个相互独立的组件:模型(Model)、视图...

    j2me-mvc 模式思想

    ### j2me-MVC 模式思想 #### 一、MVC模式简介 MVC(Model-View-Controller)模式是一种广泛应用于软件工程的...无论是在简单的应用开发还是复杂的商业应用中,MVC模式都能够帮助开发者构建出更加健壮和灵活的系统。

    J2ME的MVC模式+J4ME使用Demo

    MVC模式在J2ME中的应用对于构建可扩展和模块化的移动应用程序至关重要。 1. **模型(Model)**: 模型层是应用的核心,负责处理业务逻辑和数据管理。它包含应用程序的数据,并提供对这些数据的访问接口。在J2ME中,...

    J2ME客户端的MVC结构设计介绍

    在J2ME客户端开发中,MVC(Model-View-Controller)模式是一种广泛采用的设计模式,用于构建可扩展且易于维护的用户界面。MVC模式将应用程序分为三个核心组件: 1. **模型(Model)**:这是应用程序的核心部分,...

    J2ME应用程序架构模型

    以下是一个简化的伪代码示例,展示了MVC模式在J2ME应用程序中的应用: ```java // 视图(View) package view; public class View extends Canvas { public String getUserName(); public String getUserPassword()...

    J2ME,J2EE与Android开发学习资料

    Java技术在移动和企业应用开发领域占据着重要地位,其中J2ME、J2EE和Android是三个关键的分支。本学习资料集涵盖了这三个领域的核心概念、技术和实践,旨在帮助开发者深入理解并掌握它们。 首先,J2ME(Java 2 ...

    MIDlet控件实例项目(mvc)

    **MIDlet 控件实例项目 (mvc) 深度解析*...通过这个项目,学习者可以深入理解MIDlet的生命周期管理,控件的使用,以及如何在J2ME环境中实现MVC设计模式。这对于想要进入移动开发领域的开发者来说是一份宝贵的实践资料。

    J2ME中实现电话通讯录的源代码

    综上所述,这个项目展示了如何在J2ME环境中利用MVC模式来构建一个实用且功能丰富的电话通讯录应用。开发者需要理解J2ME的API,掌握MVC设计模式,并能有效地管理数据存储和用户交互,以实现一个高效、易于维护的移动...

Global site tag (gtag.js) - Google Analytics