摘要:本文首先介绍了标准的MVC体系构架,同时也介绍了最常见的一类MVC模式的变种。之后,文章重点介绍了MVC结构在gef框架中的体现与应用,以及gef是如何综合利用工厂模式、命令模式等设计模式来辅助MVC结构的实现。例如gef成功利用命令模式分担了控制器的部分责任。
前言
GEF全称Graphical Editor Framework。它是一个基于eclipse的图形化编辑框架。通过它,开发人员可以方便的以图形化的方式(而非文本的方式)展示和编辑模型。GEF是一种很有价值的工具,很多著名的应用都采用了gef框架,其中包括现在最流行的开源工作流jbpm的定制工具。Gef是按照标准的mvc模式实现的,其中还使用到了工厂模式、命令模式,Policy模式等一些设计模式。
MVC结构
MVC是"Model-View-Controller"的缩写,即”模式-视图-控制器"。MVC结构强制将一个应用分为模型层、视图层以及控制器。通过三者之间的协调共同响应完成用户的请求,即交互过程。
它们之间的协作关系如图:
上图为mvc模式最标准也是最常见的一种形态。从上图可以看出,模型与视图不直接打交道,而是通过控制器,即控制器完全分离了视图与模型。这是mvc模式的最大特点之一。
在现实开发中,由于实际需要,开发设计人员通常会对标准的mvc模式进行一些修改。屏弃其中的某些特性,而加入新的特性。其中最常见的变化形式如下图所示:
可以看到,控制器并没有完全分离视图与模型。即它不再负责根据模型修改视图,这一过程是让模型与视图双方“面对面”直接进行。这样做虽然增强了视图与模型之间的耦合,但是减轻了控制器的负担。
另外,在通常情况下,为了进一步解耦合,层与层之间的数据通过一种叫做DTO即数据传输对象的介质进行传递。DTO的时间通常很简单,只有若干属性和属性对应的get/set方法,是一个标准的纯java对象,即pojo。例如基于mvc结构的struts中的actionFrom即为一个DTO。
视图
视图层的作用主要有两个:
l接收用户输入,将输入信息传递给控制层。
l负责展示数据,它将模型层中的具体数据以一定的形式展示给用户。
模型和视图之间是一个多对多的关系,一个模型可以对应多个视图,一个视图也可以关联多个模型。
控制器
控制层接收到视图层传递过来的请求后,分析请求信息,根据请求内容选择相应的模型,并修改模型的具体数值。
同时当模型发生变化的时候,将会通知控制器,以更新视图。
模型
模型是行为与状态的双重抽象,即封装了数据与方法。当模型发生变化时,相应的视图会根据新的模型数据重新绘制展现内容。
优点
使用mvc结构的应用有如下有点:
l便于分工。Mvc机构将程序分为’M-V-C’三层,这三层各司其职。这样便于分工协作。例如,传统结构的应用将业务逻辑和界面显示混杂在一起,这样美工很难对页面进行美化。而mvc结构的应用,将应用分层,视图层只有展现代码便于美工美化页面。
l提高了代码的可重用性。多个视图能共享一个模型,多个模型也能共享一个视图,提高了代码的可重用性。
l便于维护更新,由于mvc的解耦合特性。使得维护和变更相对变得比较容易。因此可以方便地改变应用程序的业务数据和业务规则,迁移数据库等等。不会牵一发而动全身。
Gef中的mvc实现
Gef完全按照标准的mvc体系结构完成。
模型
Gef模型的规约十分宽泛——任何java类都可以作为gef的模型。也就是说,gef在模型层是非侵入式的。这一点使得gef的应用更加广泛,灵活。
但是为了能够让控制器知道模型的变化,我们需要一种机制——让模型发生变化的时候通知控制器。由于灵活性的需要,gef并没有把这种机制实现在框架层。但是我们通常会在模型层中添加PropertyChangeSupport类型的成员变量,用来触发事件,通知控制器。例如:
public class AbstractModel {
private PropertyChangeSupport listeners = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
listeners.addPropertyChangeListener(listener);
}
public void firePropertyChange(String propName, Object oldVal, Object newVal) {
listeners.firePropertyChange(propName, oldVal, newVal);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
listeners.removePropertyChangeListener(listener);
}
}
视图
视图是模型图形方式的表现,它以某种方式展示模型。Gef是一个图形编辑框架,所以gef的视图主要是将模型以图形化的方式显示出来。虽然任何实现IFigure
接口的类都可以作为视图,但是GEF使用Draw2D可视图形(figure)。Draw2d是SWT平台上的图形库,你可以用它定制属于自己的、不依赖于特定操作系统本地组件的上层组件。
那么视图又是如何显示的呢。这要用到AbstractEditPartViewer,它负责将视图安装到同一个SWT Control上。
控制器
在gef中,控制器又称为编辑部件,是模型和视图之间的桥梁,也是gef最重要的部分。所有的Gef控制器都需要继承EditPart类。
根据mvc体系结构,控制器的功能主要有两个。
l监听模型的变化,根据变化修改视图。
l当用户编辑视图时,把编辑的结果反映到对应得模型中。
创建——工厂模式
Gef在控制器的生成中,使用了工厂模式。通常每一个模型都对应一个控制器,所以gef要求提供一个EditPartFactory,该对象负责通过给定的模型创建与之对应的控制器。
当模型被创建的时候,EditPartFactory将会被调用,创建出模型对应的控制器。
监听模型变化
控制器需要监听模型的变化,从而根据新的模型数据重新显示视图。那么就需要将控制器注册成为模型的监听者。例如下面的代码
public void activate() {
if (isActive()) {
return;
}
super.activate();
((Node) getModel()).addPropertyChangeListener(this);
}
public void deactivate() {
if (!isActive()) {
return;
}
super.deactivate();
((Node) getModel()).removePropertyChangeListener(this);
}
方法activate的作用是当被激活的时候,把自己注册成为模型的监听。Deactivate相反,当失活的时候,将自己从对应的模型的监听者中删除。
由于模型层使用了PropertyChangeSupport类,所以,控制器需要实现PropertyChangeListener接口。PropertyChangeListener要求实现propertyChange方法。
public interface PropertyChangeListener extends java.util.EventListener {
void propertyChange(PropertyChangeEvent evt);
}
当模型发生变化时,对应控制器的propertyChange方法将会被调用。要说明的是,在gef应用中,控制器通常负责根据模型数据修改视图显示,而非简单的通知视图重画。
修改模型——策略与命令
当用户进行编辑操作的时候,控制器还需要解析这些操作并修改相应的模型。这通常是一系列负责的操作,可能会使得控制器非常庞大。Gef通过进入请求编辑策略与命令模式很好大分担了控制器的本身的负担。也达到了解耦合的目的。其中编辑策略用于解析用户编辑请求,命令用于修改模型。
同时引入命令模式的另外一个目的就是“回退”功能,一个好的图形编辑器“回退”功能是必不可少的。命令模式通过“redo”和“undo”等操作可以很多好的支持“重做”以及“回退”的功能。
当控制器接收到用户的编辑请求后,会根据请求对象中的角色信息寻找处理该请求的编辑策略。要说明的是,编辑策略需要事先被注册安装到控制器中,并对应相应的角色。角色是gef框架抽象出来的一个标识。控制器EditPart就是通过角色标识找到处理请求的策略的。
编辑策略接收到请求后,分析请求信息。根据分析的结果选择创建相应的命令,并且初始化命令的相关参数。
由gef框架负责执行编辑策略产生的命令。命令将会修改相应的模型。同时gef框架会记录下执行的命令,以备“重做”“后退”等功能使用。
用户编辑请求响应过程
综上所述,在gef框架中,用户编辑请求的相应过程如下:
1.当用户进行编辑操作时,gef框架将操作封装成一个请求对象,并将其传递给控制器。
2.控制器根据角色选择相应的编辑策略处理请求。
3.编辑策略分析请求数据,创建并初始化命令对象。
4.命令执行的过程就是修改模型的过程。
5.当模型被修改后,将会触发事件,告知其监听者——该模型对应的控制器。
6.控制器根据模型数据修改视图显示。
结束语
Gef是一个完全基于MVC体系构架搭建的图形编辑框架。正是MVC体系构架的进入,使得模型层与视图层解耦合。那么模型层的约束就得到了极大的解放。这意味着gef可以适用于更广泛的业务。也正是MVC体系结构的进入,使得基于gef框架开发的应用结构更加清晰,更加有利于分工开发与后期维护。
同时gef引入了请求编辑策略与命令模式成功分解了gef控制层的负担。其中命令模式的引入也使得应用支持“重做”“回退”等功能。
转自:http://www.iteye.com/topic/788210
相关推荐
6. **可扩展性**:GEF的插件体系结构允许开发者通过扩展点定制编辑器功能,满足不同项目的特殊需求。 在Android ADT中,GEF的作用主要体现在可视化布局编辑器上,它允许开发者通过拖放的方式设计XML布局文件,实时...
Eclipse的插件体系结构允许开发者通过安装插件来扩展其功能,GEF就是这样的插件之一,专注于图形编辑领域。 **使用GEF-SDK-3.7.0开发步骤**: 1. **环境准备**:首先需要安装Eclipse IDE,并确保它包含PDE(Plug-in...
GEF插件开发涉及创建模型、视图和控制器(MVC)组件,其中模型定义数据结构,视图负责显示,而控制器处理用户的交互。开发者需要理解Eclipse插件开发的基本流程,包括创建插件项目、定义扩展点、编写实现类等步骤。 ...
1. **Eclipse插件体系结构**: - 插件是Eclipse的核心组成部分,它们通过OSGi模块系统相互交互。 - 每个插件都是一个独立的Java项目,包含了代码、资源和元数据(plugin.xml)。 - 插件之间通过声明依赖关系来...
1. **Eclipse插件体系结构**: Eclipse是一个开放源码的集成开发环境(IDE),它采用插件架构,允许通过添加或扩展插件来实现不同的功能。开发者可以创建自己的Eclipse插件来满足特定的需求,如代码编辑、调试、...
Eclipse RCP的体系结构由Eclipse Plugin体系发展而来,更专注于企业级应用。Plugin是IDE的基础,而RCP是构建复杂应用的平台。Eclipse RCP的核心组件包括Display、Shell、Workbench、Advisor、View、Editor和...
- **可扩展性**: GEF的插件体系使得扩展和集成其他Eclipse组件变得容易,例如,可以结合EMF(Eclipse Modeling Framework)进行数据建模。 - **灵活性**: GEF支持多种布局策略,可以根据需要选择或编写自定义布局...
7. **MVC架构**:GEF遵循模型-视图-控制器(MVC)设计模式,分离了数据模型、用户界面和控制逻辑,使得代码更易于维护和扩展。 8. **API和工具支持**:ECLIPSE GEF提供了丰富的API,方便开发者构建和定制图形编辑...
- **MVC模式**:GEF采用了MVC(Model-View-Controller)设计模式,将应用程序分为三个核心部分,即模型(Model)、视图(View)和控制器(Controller),这种分离有助于提高代码的可维护性和重用性。 - **GEF中的...
GEF使用MVC(模型-视图-控制器)设计模式,分为模型层(Model)、编辑器层(Editor)和表示层(Presentation)。模型层负责定义应用程序的数据和业务逻辑,编辑器层负责处理用户交互,而表示层则负责将模型层的数据...
EMF的核心理念是将数据结构转换为Java类,这些类能够直接在代码中使用,也可以通过XML或其他序列化格式进行持久化。这种模型-视图-控制器(Model-View-Controller, MVC)的设计模式允许开发者分离业务逻辑和用户界面...