`

自己写的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的陷阱——不先考虑事务的流程,而是从用户接口直接下手去分析问题,这往往扼杀了你的全局构思。

分享到:
评论

相关推荐

    外加热强制循环蒸发器装配图(CAD).rar

    外加热强制循环蒸发器装配图(CAD).rar

    数控车床纵向进给系统设计.zip

    数控车床纵向进给系统设计.zip

    vault_side_off_ominous.png

    j

    爬虫 bangumi名称和评论数

    爬虫 bangumi名称和评论数

    基于SpringBoot的垃圾分类回收系统(源码+数据库+万字文档)526

    基于SpringBoot的垃圾分类回收系统,系统包含两种角色:管理员、用户主要功能如下。 【用户功能】 首页:浏览垃圾分类回收系统信息。 个人中心:管理个人信息,查看历史记录和订单状态。 运输管理:查看运输信息,垃圾回收的时间和地点。 公告管理:阅读系统发布的相关通知和公告。 垃圾回收管理:查看垃圾回收的信息,回收类型和进度。 垃圾出库申请管理:提交和查看垃圾出库申请的状态。 【管理员功能】 首页:查看垃圾分类回收系统。 个人中心:管理个人信息。 管理员管理:审核和管理注册管理员用户的信息。 用户管理:审核和管理注册用户的信息。 运输管理:监管和管理系统中的运输信息。 公告管理:发布、编辑和删除系统的通知和公告。 垃圾回收管理:监管和管理垃圾回收的信息。 垃圾出库申请管理:审批和管理用户提交的垃圾出库申请。 基础数据管理:管理系统的基础数据,运输类型、公告类型和垃圾回收类型。 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术:SpringBoot 三、运行环境 操作系统:Windows、macOS都可以 JDK版本:JDK1.8以上都可以 开发工具:IDEA、Ecplise、Myecplise都可以 数据库: MySQL5.7以上都可以 Maven:任意版本都可以

    这篇文章是台湾大学(NTU)计算机科学与信息工程系(CSIE)2021年秋季学期算法设计与分析课程的第一份作业(Homework#1)的具体要求和题目描述 以下是主要内容的总结:

    内容概要:本文档是台湾大学计算机科学与信息工程系2021年秋季学期《算法设计与分析》课程的第一次作业(Homework#1)。作业包含四道编程题和三道手写题,旨在考察学生对算法设计和分析的理解与应用能力。编程题涉及汉诺塔、数组计算、矩形点对、糖果分配等问题;手写题涵盖渐近符号证明、递归方程求解、幽灵腿游戏优化、不公平的卢卡斯问题等。文档详细描述了每个问题的具体要求、输入输出格式、测试用例以及评分标准。此外,还提供了编程技巧和注意事项,如避免延迟提交、正确引用资料、处理大输入文件等。 适合人群:具备一定编程基础的本科生或研究生,特别是修读过或正在修读算法设计与分析相关课程的学生。 使用场景及目标:①帮助学生巩固课堂所学的算法理论知识;②通过实际编程练习提高解决复杂问题的能力;③为后续更深入的学习和研究打下坚实的基础。 其他说明:此作业强调团队合作和个人独立思考相结合的重要性,鼓励学生在讨论后用自己的语言表达解决方案,并注明参考资料。对于编程题,特别提醒学生注意输入文件可能较大,建议采取适当的优化措施以确保程序运行效率。

    基于SpringBoot的铁路订票管理系统(源码+数据库+万字文档+ppt)528

    基于SpringBoot的铁路订票管理系统,系统包含两种角色:管理员、用户主要功能如下。 【用户功能】 首页:浏览铁路订票管理系统的主要信息。 火车信息:查看火车的相关信息,包括车次、出发地、目的地和票价等。 公告资讯:阅读系统发布的相关通知和资讯。 后台管理:进行系统首页、个人中心、车票预订管理、车票退票管理等操作。 个人中心:管理个人信息,查看订单历史记录等。 【管理员功能】 首页:查看铁路订票管理系统。 个人中心:修改密码、管理个人信息。 用户管理:审核和管理注册用户的信息。 火车类型管理:管理系统中的火车类型信息。 火车信息管理:监管和管理系统中的火车信息,添加、编辑、删除等。 车票预订管理:处理用户的车票预订请求。 车票退票管理:处理用户的车票退票请求。 系统管理:管理系统的基本设置,公告资讯、关于我们、系统简介和轮播图管理。 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术:SpringBoot 三、运行环境 操作系统:Windows、macOS都可以 JDK版本:JDK1.8以上都可以 开发工具:IDEA、Ecplise、Myecplise都可以 数据库: MySQL5.7以上都可以 Maven:任意版本都可以

    塑料架注射模具设计.rar

    塑料架注射模具设计.rar

    基于json文件数据驱动的的接口测试框架.zip

    基于json文件数据驱动的的接口测试框架

    铁丝缠绕包装机设计-缠绕盘设计.rar

    铁丝缠绕包装机设计-缠绕盘设计.rar

    Linux操作系统及常用命令详解.zip

    linux

    圆柱体相贯线焊接专机工作台设计.rar

    圆柱体相贯线焊接专机工作台设计.rar

    硬币分拣机设计.rar

    硬币分拣机设计.rar

    【机器学习与数据挖掘】行业级机器学习软件开发经验与教训:从LIBSVM和LIBLINEAR看算法部署及软件设计挑战

    内容概要:本文探讨了开发行业级机器学习和数据挖掘软件的经验与教训,指出当前研究界与工业界之间的脱节问题。作者分享了开发LIBSVM和LIBLINEAR的经验,强调了用户需求的重要性。大多数用户并非机器学习专家,期望简单易用的工具来获得良好结果。文章还详细介绍了支持向量机(SVM)的实际应用案例,包括数据预处理(如特征缩放)、参数选择等步骤,并提出了为初学者设计的简易流程。此外,作者讨论了在设计机器学习软件时应考虑的功能选择、选项数量、性能优化与数值稳定性等问题,强调了软件开发与实验代码的区别以及鼓励研究人员参与高质量软件开发的重要性。 适合人群:对机器学习软件开发感兴趣的科研人员、工程师及从业者,尤其是那些希望了解如何将学术研究成果转化为实际可用工具的人士。 使用场景及目标:①帮助非机器学习专家的用户更好地理解和使用机器学习方法;②指导开发者在设计机器学习软件时考虑用户需求、功能选择、性能优化等方面的问题;③促进学术界与工业界之间的合作,推动高质量机器学习软件的发展。 其他说明:本文不仅提供了具体的开发经验和技巧,还呼吁建立激励机制,鼓励更多研究人员投入到机器学习软件的开发中,以解决当前存在的研究与应用脱节的问题。

    pandas学习代码,jypyter格式

    一天入门pandas代码

    joblib-0.12.0-py2.py3-none-any.whl

    该资源为joblib-0.12.0-py2.py3-none-any.whl,欢迎下载使用哦!

    深度学习基于PyTorch==2.6.0和Transformers==4.48.0的XTuner环境配置:AI模型开发与优化依赖库列表

    内容概要:本文档《xtuner_requirements.txt》列出了用于支持特定项目(可能是机器学习或深度学习项目)运行所需的所有Python包及其版本。其中不仅包括常见的数据处理和科学计算库如numpy、pandas,还包括了与深度学习密切相关的库如torch、transformers等。值得注意的是,文档中还特别指定了NVIDIA CUDA相关组件的具体版本,确保了GPU加速环境的一致性和兼容性。此外,文档中也包含了从GitHub直接安装的xtuner库,明确了具体的提交哈希值,保证了代码来源的精确性。 适合人群:对机器学习、深度学习领域有一定了解并需要搭建相应开发环境的研发人员,尤其是那些希望复现特定实验结果或基于已有模型进行二次开发的研究者和技术爱好者。 使用场景及目标:①帮助开发者快速搭建完整的开发环境,确保所有依赖项正确无误;②为研究人员提供一个稳定的实验平台,以便于重复实验和验证结果;③作为项目协作的基础,确保团队成员之间的环境一致性,减少因环境差异带来的问题。 阅读建议:由于该文档主要为技术性依赖列表,在阅读时应重点关注所需安装的库及其版本号,特别是CUDA相关组件和自定义库(如xtuner)的安装方式。对于非技术人员而言,可能需要额外查阅相关资料来理解各库的作用。同时,在实际操作过程中,建议按照文档中的顺序逐一安装依赖,避免版本冲突等问题的发生。

    vault_side_on_ominous.png

    j

Global site tag (gtag.js) - Google Analytics