- 浏览: 800750 次
- 性别:
- 来自: 广州
最新评论
-
mixture:
语句int num1, num2;的频度为1;语句i=0;的频 ...
算法时间复杂度的计算 [整理] -
zxjlwt:
学习了。http://surenpi.com
[问题解决]Error: ShouldNotReachHere() [整理] -
Animal:
谢谢 楼主 好东西
算法时间复杂度的计算 [整理] -
univasity:
gaidandan 写道缓存失败,,模拟器上可以缓存,同样代码 ...
[开发总结]WebView使用中遇到的一些问题&解决 -
blucelee2:
那么麻烦干吗,而且这种方法会导致,当拉太小的时候样式会丢掉,整 ...
[SWT]SashForm中固定单侧大小(&实现面板隐藏)
内容提要:
本文简要的介绍了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哦。
尽管理论上可能很清晰,但实践带来的复杂性是惊人的。这正是软件开发的问题,太多的细节困扰这开发者对大局的把握。本文接下来,将结合最后这种设计思想,给出一个完整的设计实例。帮助大家从实践的角度理解运用这一模式。敬请大家期待。
发表评论
-
对Java的I/O流理解
2011-02-19 23:04 1913这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
A*寻路(J2ME实现)
2011-02-19 23:00 1239这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
J2ME上检测是否支持特定的API
2011-02-19 22:59 1459这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
J2me paint[转]
2011-02-19 22:58 1382这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看. ... -
[JSR-184][3D编程指南(译文)]第一部分:快速进入移动JAVA 3D编程世界
2011-01-23 00:37 1653[英文原文&源码下载] ... -
[JSR-184][3D编程指南]Part V: Heightmap terrain rendering using M3G
2011-01-22 23:13 1836<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part IV:M3G built-in collision,light physics and camera perspec
2011-01-22 23:04 2068<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part III: Particle systems and immediate mode rendering (2)
2011-01-22 22:56 1495<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part III: Particle systems and immediate mode rendering (1)
2011-01-22 22:48 2176<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part II: Light 3D theory and orientation
2011-01-22 22:29 1473<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]Part I: Quick jump into the world of Mobile Java 3D programming
2011-01-22 22:07 2267<!-- 整理收集自网络,收藏以便日后查阅 --> ... -
[JSR-184][3D编程指南]目录索引
2011-01-22 21:25 1367Series of 3D programming tutori ... -
[Kuix][转]Kuix的事件处理机制
2009-10-08 18:19 1616原文连接 kuix这 ... -
[积累]getResourceAsStream()返回null的问题
2009-03-13 22:04 2539getResourceAsStream()可以获取JAR包内的 ... -
[资料]根据J2ME(MIDP)虚拟机对程序编写的优化方式
2009-02-27 09:39 14001、关于虚拟机 我认为 ... -
[资料]MIDP2.0中如何通过代码画半透明的圆和椭圆
2009-02-27 09:10 1550最近在做一个小Demo时,需要画一个半透明的圆,看遍M ... -
[资料]MIDP设计模式之集结贴[JavaME]
2009-02-23 22:07 13131: 架构性宣言: MI ... -
[资料]基于MVC模式的J2ME应用程序框架设计
2009-02-23 21:24 2807原文:http://www.mcu123.com/ ... -
[资料]线程在J2ME应用中的使用
2009-02-22 17:05 1554简要说明: 非常好的一篇文章,谈论到了线程各个方面的问题 ... -
[JSR-135][资料]渐进式下载
2009-02-22 16:17 1853Progressive download ...
相关推荐
基于MVC模式的J2ME应用程序框架设计
j2me手机程序mvc模型设计,让你清楚知道mvc在j2me程序中怎么运用的
内容提要: 本文简要的介绍了MVC模式的思想,并分析了MVC模式的利弊,最后结合MIDP平台给出几种常见的MVC模式实践。相信此文对任何一个使用midp平台的商务程序开发者都或多或少的有所帮助。 版权声明: 本文同时...
基于mvc架构的j2me版本的通讯录,基于mvc架构的j2me版本的通讯录,基于mvc架构的j2me版本的通讯录
NIIT第三模块考试试题J2ME很好的资源,值得信赖。不是所有的题目都有答案。请谅解。 mvc3
j2me实现mvc的框架源码j2me实现mvc的框架源码j2me实现mvc的框架源码j2me实现mvc的框架源码
NIIT MVC4 MT2 J2ME试题与答案 NIIT MVC4 MT2 J2ME试题与答案
MVC(Model-View-Controller 模型-视图-控制器)是用户界面设计中最经典的 一种设计模式。MVC 模式提供了一种方法,将应用程序(或者应用程序的一部分)分解成三个部分:①模型,它是应用程序的主要部分,包括商业逻辑...
本文简要介绍了MVC模式思想并分析了MVC模式利弊最后结合MIDP平台给出几种常见MVC模式实战相信此文 对任何个使用midp平台商务开发者都或多或少有所帮助
1 J2ME应用程序框架的现状 Sun公司在1999年6月推出了J2ME(Java 2 MicroEdition,Java 2袖珍版)。J2ME是专门为那些使用有限电源、有限网络连接以及有限图形用户界面能力的设备开发的,满足了消费电子和嵌入式设备...
J2ME的MVC模式例子 + javame的手机端UI框架j4me的使用演示代码
在J2ME中运用MVC模式,建立了一个完整的电话通讯录
LWUIT实现了MVC架构,是J2ME程序中UI设计的一个JAR包。该文档是LWUIT帮助文档的CHM版
移动通信是当今发展最快、最前沿的通信领域,从手机短信、彩信、GPRS、CDMA 无 线上网到企业无线和移动应用解决方案,无线...信息收发的实时性特征,程序设计上还运用了基于MVC 的应用程序框架,增加了程序的可 读性
基于MVC模式的移动设备屏幕导航系统的设计与实现,刘伟,范博文, 通过对MVC设计模式的研究,本文为移动设备屏幕导航功能设计并实现了一个具备可扩展性的系统架构。该架构结合了MVC和J2ME技术。MVC模�