`

自己写的j2meMVC模式

    博客分类:
  • j2me
阅读更多

cotroller 控制类包

model 数据组织类包

view 视图类包

参考文章:

转载:http://www.yesky.com/395/1923895.shtml

MVC在J2ME项目中的应用之MVC慨述

2005-03-19 09:49 作者:Favoyang 出处: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;
}
}

 

 

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哦。

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


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

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

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

分享到:
评论

相关推荐

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

    火龙果软件工程技术中心 摘要随着嵌入式硬件和软件技术的发展,J2ME应用程序的复杂度和代码量越来越大...关键词J2MEMVC应用程序框架1J2ME应用程序框架的现状Sun公司在1999年6月推出了J2ME(Java2MicroEdition,Java2袖

    06_QLibrary.zip

    06_QLibrary.zip

    毕业设计: 基于Densenet + CTC技术的文字检测识别的技术研究

    本毕设课题是属于计算机视觉下的目标检测与识别,对象为自然场景下的各种文本信息,通俗的说就是检测识别图片中的文本信息。由于文本的特殊性,本毕设将整个提取信息的过程可以分为检测、识别两个部分。 论文对用到的相关技术概念有一定的介绍分析,如机器学习,深度学习,以及各种的网络模型及其工作原理过程。 检测部分采用水平检测文本线方式进行文本检测,主要参考了乔宇老师团队的 CTPN 方法,并在正文部分从模型的制作到神经网络的设计实现对系统进行了较为详细的分析介绍。 识别部分则采用的是 Densenet + CTC,对于印刷体的文字有较好的识别。

    毕业设计 基于javaweb的在线答题平台

    毕业设计 基于javaweb的在线答题平台

    numpy安装 python get-pip.py

    numpy安装 numpy安装 python get-pip.py

    基于用户、物品的协同过滤算法.zip

    协同过滤算法(Collaborative Filtering)是一种经典的推荐算法,其基本原理是“协同大家的反馈、评价和意见,一起对海量的信息进行过滤,从中筛选出用户可能感兴趣的信息”。它主要依赖于用户和物品之间的行为关系进行推荐。 协同过滤算法主要分为两类: 基于物品的协同过滤算法:给用户推荐与他之前喜欢的物品相似的物品。 基于用户的协同过滤算法:给用户推荐与他兴趣相似的用户喜欢的物品。 协同过滤算法的优点包括: 无需事先对商品或用户进行分类或标注,适用于各种类型的数据。 算法简单易懂,容易实现和部署。 推荐结果准确性较高,能够为用户提供个性化的推荐服务。 然而,协同过滤算法也存在一些缺点: 对数据量和数据质量要求较高,需要大量的历史数据和较高的数据质量。 容易受到“冷启动”问题的影响,即对新用户或新商品的推荐效果较差。 存在“同质化”问题,即推荐结果容易出现重复或相似的情况。 协同过滤算法在多个场景中有广泛的应用,如电商推荐系统、社交网络推荐和视频推荐系统等。在这些场景中,协同过滤算法可以根据用户的历史行为数据,推荐与用户兴趣相似的商品、用户或内容,从而提高用户的购买转化率、活跃度和社交体验。 未来,协同过滤算法的发展方向可能是结合其他推荐算法形成混合推荐系统,以充分发挥各算法的优势。

    strcmp函数应用.zip

    strcmp函数应用.zip

    2.py

    2.py

    解读MIT-BIH数据的MATLAB代码.zip

    解读MIT-BIH数据的MATLAB代码.zip

    医保基本药品耗材目录查询2.0.exe

    可以查询各种医保内的药物,包括规格厂家和详细的相关资料,种类很齐全,方便大家查询,和了解药物价格等方面。

    使用Numpy将类保存到npz文件并读取文件,然后绘制图形的Python代码示例

    npz文件 代码中,我们首先定义了一个数据类Data,其中包含x和y两个成员变量。 然后,我们创建了数据对象,并将其保存到文件中。我们使用np.savez函数将数据字典保存到文件中,其中字典的键为变量名,值为对应的数据数组。 接下来,我们使用load_from_file方法从文件中加载数据,并创建一个新的数据对象。 最后,我们使用Matplotlib库绘制出新数据对象的图形。通过plot函数,我们将x和y作为横纵轴数据进行绘制。然后,我们添加坐标轴标签、标题,并显示网格线。 运行代码后,将显示一个绘制出的数据图形。 数据保存: def save_to_file(self, filename): data_dict = { 'x': self.x, 'y': self.y } np.savez(filename, **data_dict) # 将数据保存到文件 filename = 'data.npz' data.save_to_file(filename)

    matlab矩阵的生成.zip

    matlab矩阵的生成.zip

    模拟器非常好用,赶紧来下载

    模拟器非常好用,赶紧来下载

    常用进制转换器16进制10进制2进制转换计算器..exe

    大家好呀!今天来介绍一款常用进制转换器,也就是 16 进制、10 进制、2 进制转换计算器。有了它,你可以轻松实现不同进制之间的快速转换。无论是将 16 进制转换为 10 进制或 2 进制,还是从其他进制转换过来,它都能准确而高效地完成。无论是在计算机编程、数字电路等领域,还是日常对进制转换有需求的时候,它都能成为你的得力小助手,让进制转换不再麻烦,快来试试吧!

    GIMP完整指南GIMP完整指南

    GIMP完整指南

    IMG_20240519_155556.jpg

    IMG_20240519_155556.jpg

    java spring boot集成minio文件上传下载

    资源内容为java操作minio文件上传下载,也涉及到加密操作,主要是minio的SSE-C模式,具体内容在Sprintboot01ApplicationTests.MinioTest()中。 包含以下内容: //1.测试数据上传 testUploadString(); //2.测试数据下载 testDownLoadString(); //3..测试数据加密上传 testUploadStringEncryt(); //4.测试加密数据下载 testDownLoadStringEncryt(); //5.测试文件上传 testUploadFile(); //6.测试文件加密上传 testUploadFileEnctry(); //7.测试文件加密下载 testDownLoadFileEncryt();

    web期末大作业基于HTML+CSS实现的品优购购物网站静态网页源码(仿京东-期末大作业).rar

    品优购购物网站静态网页源码是基于HTML+CSS实现的一款仿京东风格的购物网站项目。该项目旨在帮助计算机相关专业的在校学生、老师以及企业员工更好地学习和掌握HTML+CSS技术,提升网页设计与制作的实践能力。 该源码经过精心设计和编码,实现了良好的页面布局和视觉效果,同时保证了代码的易读性和可维护性。通过下载和使用该源码,用户可以快速搭建起一个具有完整功能的购物网站静态页面,为后续动态交互功能的实现打下坚实基础。 此外,该源码还提供了详细的注释说明,方便初学者快速上手,理解并掌握网页制作的关键技术。对于有一定基础的学员来说,更可以在源码的基础上进行二次开发,实现更多个性化功能,满足实际项目需求。 经过运行测试,该源码表现稳定,无兼容性问题。无论是作为课程设计的参考资源,还是毕业设计的实践项目,品优购购物网站静态网页源码都将为您提供一个高质量的起点,助您在学习和实践中取得优异成绩。放心下载使用,开启您的网页制作之旅吧!

    【一键平仓ea 】一键平仓ea ,一键全部平仓mt5面板ea

    包含一键全平 一键平盈利单 一键平亏损但 只平多单 只平空单 盈利单平二分之一仓位 盈利单平三分之一 亏损单平二分之一仓位 亏损单平三分之一 适用于 mt5 平台

Global site tag (gtag.js) - Google Analytics