摘要: 本文首先介绍了标准的 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

GEF的MVC体系结构的更多相关文章

  1. Spring MVC体系结构和处理请求控制器

    Spring MVC体系结构和处理请求控制器 一:MVC设计模式: (1.)数据访问接口:DAO层 (2.)处理业务逻辑层:Service层 (3.)数据实体:POJO (4.)负责前段请求接受并处理 ...

  2. Spring MVC体系结构

    [Spring MVC类图]<Spring实战>中:<Spring3.0就这么简单>中:[http://blog.csdn.net/gstormspire/article/de ...

  3. spring MVC体系结构和请求控制器

    MVC处理过程 spring MVC架构模式都进行了分层设计如下 数据访问接口:DAO层 处理业务逻辑层:service层 数据实体:POJO 负责前端请求的接受并处理:servlet 负责前端页面展 ...

  4. Spring MVC 相关资料整理

    来源于:http://www.cnblogs.com/ylhssn/p/4062757.html 1.概述 Spring MVC是一种基于Java实现MVC设计模式的请求驱动类型的轻量级Web框架,即 ...

  5. ASP.NET MVC掉过的坑_MVC初识及MVC应用程序结构

    APS.Net MVC 浅谈[转] 来自MSDN 点击访问 MVC 理论结构 模型-视图-控制器 (MVC) 体系结构模式将应用程序分成三个主要组件:模型.视图和控制器. ASP.NET MVC 框架 ...

  6. Spring MVC 学习笔记(整理)

    SpringMVC学习 1.概述 Spring MVC是一种基于Java实现MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行解耦,基于请求-响应模型帮助我们 ...

  7. ASP.NET MVC Overview

    ASP.NET MVC Overview The Model-View-Controller (MVC) architectural pattern separates an application  ...

  8. .net mvc笔记1_ The MVC Pattern

    1.controller中的每一个public method被称为action method,意味着你可以从web上通过URL来调用它,以此来执行一个action. 2.当我们从action meth ...

  9. Pro ASP.NET MVC –第二章 第一个MVC程序

    学习一个软件开发框架的最有效的方式就是了解并使用它.在本章,你将会创建一个简单基于ASP.NET MVC Framework的数据-实体应用程序.我们会该程序划分成若干小块,每次介绍一个部分,以便你能 ...

随机推荐

  1. Swift - 使用下划线(_)来分隔数值中的数字

    为了增强较大数值的可读性,Swift语言增加了下划线(_)来分隔数值中的数字. 不管是整数,还是浮点数,都可以使用下划线来分隔数字. 1 2 3 4 //数值可读性 let value1 = 10_0 ...

  2. HTTP实现长连接(TTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持Connection: keep-alive)

    HTTP实现长连接 HTTP是无状态的 也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接.如果客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web ...

  3. 发掘ListBox的潜力(二):鼠标拖放插入点提示

    鼠标拖放插入点提示 鼠标拖放是Windows常见的操作,比如拷贝文件就可用拖放方式进行.在我们编写的应用程序中,有时为了方便用户操作需要支持鼠标拖放.对于大部分的VCL控件只要鼠标将DragMode设 ...

  4. cuzysdk购物模块 36kr+本期背景图

    说好的剧透,虽然来的稍微晚不少 cuzysdk(www.cuzy.com) 是一个手机淘宝客sdk,通过使用cuzy,可以获取taobao平台的推广商品数据,移动开发者把推广的商品数据呈现给用户,用户 ...

  5. viewDidLoad、viewDidUnload、viewWillAppear、viewDidAppear、viewWillDisappear 和 -viewDidDisappear的区别和使用

    首先看一下官方解释: - (void)loadView; // This is where subclasses should create their custom view hierarchy i ...

  6. 做SEO推广必须要做的9件事儿

    SEO推广是由网站优化网络运营媒体宣传结合的一种技术,而现在恰好就是媒体最为流行,真因为如此很多的站长之知道利用自媒体推广网站,结果推广了几年网站权重只有2到3而已,导致和谐问题的关键就是没有结合其他 ...

  7. Unable to instantiate activity ComponentInfo或java.lang.ClassNotFoundException: com.ibright.herolegen

    不知道怎么回事,在libs中添加了jar包后,无法给jar包附加上源码,于是采取以下措施: 删除自动生成的依赖: 在Android Dependences目录上右击->Build Path -& ...

  8. Html 内嵌 选择器属性 Dom操作 JavaScript 事件

    HTML标签: 一.通用标签(一般标签) 1.格式控制标签 <font color="#6699aa" face="楷体" size="24&q ...

  9. 注册Dev的帮助文件

    Download the CHM files from… Code: https://www.devexpress.com/Support/Documentation/download.xml?pla ...

  10. 给c++程序员的一份礼物——常用工具集

    给c++程序员的一份礼物——常用工具集 [声明]如需复制.传播,请附上本声明,谢谢.原文出处:http://morningspace.51.net/,moyingzz@etang.com 所谓&quo ...