Online Book Reader

Home Category

Beautiful RIA [6]

By Root 423 0
。作为 web应用前端的表示层使用了 Eclipse RAP来开发。RAP项目主页 把它描述称为一个为开发人员提供了下述功能的框架:

案例研究:Eclipse富 Ajax开发平台在 CAS Software AG项目中的应用

通过使用 Eclipse开发模型、基于 Eclipse工作台扩展点的插件以及用 SWT API(以及 JFace)开发的组件工具箱来构建基于 Ajax技术的富 web应用 .... RAP非常像 Eclipse RCP,但是它不是在桌面计算机上启动,而是运行在一台服务器上,可以被标准浏 览器访问。这主要是因为它提供了一套特殊实现的 SWT(一个 SWT API的子集)。 (http://www.eclipse.org/rap/about.php)

下面是 Eclipse RCP和 Eclipse RAP的一个简单架构对比图。

CAS PIA用 Elipse RAP在表示层中构建用户界面有以下原因:

 用户感观 - Elipse RAP可以构建出非常符合人体工程学而且可切换主题的富用户界面, 已经非常类似于胖客户端的感受。

 开发效率 - AJAX和 JavaScript被包装成对开发者透明的组件,从而使得程序员可以用他 们熟悉的 Java类库和 IDE来开发。

 易于扩展 尽管 RAP使程序员可以不直接使用 JavaScript、HTML和 CSS来开发,但是它 也提供了足够的可扩展性,使定制的组件和风格可以毫无问题的加入到应用当中。

 工程质量 - Elipse和它的产品族拥有最好的软件设计和体验,RAP也不例外。

 单一代码库 - RAP能够被编译为 AJAX或者 RCP应用程序。

表示层也包含了 OSGi运行时环境,这为它在别的 CAS产品中的使用提供了良好的模块性和 复用性。CAS选择 Eclipse Equinox项目作为他们实现 OSGi的工具,定义如下:

案例研究:Eclipse富 Ajax开发平台在 CAS Software AG项目中的应用

...一个 OSGi R4核心框架规范的实现,即一组实现了若干可选的 OSGi服务和其它架 构的软件包,可以运行在基于 OSGi的系统上。

总的来说, Equinox项目的目标是成为一流的 OSGi社区和使 Eclipse成为界面组件 视觉化的开发工具。

通过利用 Equinox提供的分离机制,CAS已实现了自己的核心模块,这些模块包含了许多软 件包,这些包可以作为通用组件应用到不同的应用程序中。每个模块都提供了一些扩展点, 通过这些点,根据所开发的不同应用的需求,可以实现不同的特定的行为。例如,用户管理 组件可以用在许多应用程序当中,而联系人管理模块就比较特殊,只会被用到 CRM相关的 应用中。OSGi提供的这种扩展性使模块很容易被扩展,比如在构建和部署阶段。

CAS PIA 的另一部分是商业逻辑和典型的服务器端相关功能,即服务核心或者 EIM(企业信 息管理)。设计和开发 EIM是把它作为 CAS整个产品线的核心。服务核心提供了通过 Sun JAX-WS、RMI和 REST服务来远程访问的功能,核心同样也利用 Spring框架设计成组件化的 风格,都是可以被扩展的。

持久层用了 MySQL数据库,同时也包含了 CAS特别开发的定制组件。定制组件包含了一个 可扩展的数据模型、一套定制的查询语言(CAS-SQL)和一个权限管理组件。该权限管理组 件利用 ACEGI框架来进行用户鉴权,也对数据库层的每个对象都提供了 ACL(访问控制列表)。 这套权限管理系统和 Oracle的 OLS比较类似,而该系统还支持 MySQL之外的其它数据库, 从而使 CAS可以在别的产品上使用它。

RAP Eclipse RAP的单元测试

单元测试在任何软件开发中都是非常重要的一个环节,即使是在软件的客户端也不例外。很 多时候,应用程序的界面开发人员发现很难对代码做单元测试。通常,这是因为表示层和应 用逻辑紧密耦合从而使得单元测试代码的开发非常复杂和难于维护。CAS的程序员们设法把 尽量多的逻辑都放在服务器端,从而使单元测试(代码)非常健壮。然而,不是所有的东西 都可以放到服务器端,而这也是为什么好的 UI设计成为一个很重要因素的原因。

通过用通用设计模式比如 MVC、表示层模型(Presentation Model)、模型视图代理(Model View Presenter)等等来实现用户界面,将视图从逻辑当中解耦出来,从而使单元测试变得相对容 易。即便进行了良好的设计,也还是有很多的问题需要面对, 尤其是 RAP用户界面的测试。 首先,RAP UI组件包含了一个 Java层和一个 JavaScript层,这意味着有两个部分的代码需要 测试。Qooxdoo, 即 RAP使用的 Ajax应用程序框架,提供了类似于 JUnit和 JSUnit的单元

案例研究:Eclipse富 Ajax开发平台在 CAS Software AG项目中的应用

测试工具。CAS利用这些工具来对组件的 JavaScript层进行测 试,用 JUnit来测试 Java层。 下面是 CAS提供的一个单元测试代码,展示了对定制组件 JavaScript层的测试。

/**

* Memory leak test.

* * Creates and disposes an objects, and checks if there are some leaking instances. *

* @type member

* @return {void}

*/

testMemoryLeak : function() {

var ms1 = de.tests.MemoryLeakUtil.getMemorySnapshot(); // create

var dc = new de.cas.qx.ui.widget.calendar.datechooser.DateChooser();

qx.ui.core.Widget.flushGlobalQueues();

// dispose

dc.dispose();

var ms2 = de.tests.MemoryLeakUtil.getMemorySnapshot();

var msg = de.tests.MemoryLeakUtil.checkMemoryLeak(ms1, ms2);

this.assertEquals("", msg, "There are some leaking objects!");

},

这个特定测试试图找到由 DateChooser组件引起的潜在的内存泄露(DateChoose是 CAS开发 的定制组件中的一个)。MemoryLeakUtil类是一个CAS创建的定制工具类,它使用了Qooxdoo 提供的一些功能,比如列出内存中的所有对象。通过 Qooxoo提供的功能,他们可以轻易的 对内存泄露问题来做测试,而这类问题是在 JavaScript组件开发中很常见的。在测试 RAP用 户界面时需要面对的另外一个问题是处理 UI的异步和动态的状态。有一些工具可以用来记 录用户界面并且可以把这个过程存储起来,从而可以反复运行。这种类型的测试有助于检查

案例研究:Eclipse富 Ajax开发平台在 CAS Software AG项目中的应用

UI 的行为和交互,仿佛是有用户在真正使用它,但是它们也有局限性。在 CAS对 web应用 程序测试工具做的大致评估中,他们还没有发现一款工具可以处理异步和非基于页面的用户 界面,如遇到基于 Ajax的应用程序,它的内容是动态装载的的而非改变整个页面。

单元测试中有时也会遇到的一个问题是对服务器和 /或数据层进行测试。通常单元测试代码 直接与服务器、数据库等直接通信来完成它们的测试。这种类型的测试有 其缺陷,CAS的 开发者们也遇到过,单元测试由于需要和其他层的通信而变得很慢。一个通常的的解决办法 是用假对象,在测试中用假对象来代替“真对象”。在 java中有很多假对象的框架,包括 Mockito、EasyMock和 JMock,它们用来简化假对象的创建过程。对 JavaScript来说,也有这 样的假对象框架比如 JSMock和 Mock4JS。

之前您看到了用于测试 JavaScript层的单元测试代码,之后您将会看到一段测试 Java层的例 子。对 Eclipse 1.1来说,这个框架框架基本上包含了相当于 JUnit的测试的功能,不同的是 它可以使需要 OSGi环境的测试正常运行。如果您需要执行期间更新 UI的单 元测试,您可 以非常简单地从 org.eclipse.rap.junit.RAPTestCase扩展。但是,如果对单元测试来说不需要更 新用户界面,那么相应地,你可以扩展 JUnit的 org.junit.TestCase类。下面是一个关于包含 了用户界面交互的 RAP的测试用例:

public class RapJUnitTest extends RAPTestCase {

public void testOpenView() {

try {

IWorkbenchPage page = getPage();

page.showView( "org.eclipse.rap.demo.DemoTreeViewPartI" );

} catch( PartInitException e ) {

e.printStackTrace();

}

assertEquals( 1, getPage().getViewReferences().length );

getPage().hideView(

Return Main Page Previous Page Next Page

®Online Book Reader