9.开发方法
在这一章,我们会给你我们开发方法在更高层次的总览。一般,我们会遵从一种敏捷,迭代的过程来构建TimeTracker。一种可选择的方法会使用瀑布方法。在全部应用是设计优先,然后编码,测试,并且最终部署。因而,瀑布方法天生具有更大的风险正逐渐的不被人们所使用。与瀑布方法不同,迭代方法允许我们很快的看到我们辛苦工作的结果,并且尽可能尽早的作必要的修正。
根据敏捷开发的精神,我们会在几个迭代中构建TimeTracker。在第一个迭代,我们会设计和构建搜索功能。这会包括一个完整的垂直应用程序的薄片。在以后的迭代中,我们会实现创建、提交和审批timecard的功能。
另一个重要的敏捷方法的方面是测试驱动开发,建议你在写产品代码前写测试代码,并且来完成测试,这种测试定义了你的应用的需求并且强迫你写必须的代码,因而减少不必要的工作。另外,你现在有一系列的测试用力,能被用来作为回归测试你的应用之用。作为一个例子,从我们的原型考虑搜索屏幕,要支持这个屏幕,服务层只需要提供两个功能:
1. 获得所有用户列表来填写搜索的下拉列表
2. 获得匹配特定搜索条件的所有的时间卡的列表
我们首先处理获取所有用户的这个需求:
1. 应用足够的模型来写“get all users”测试
2. 从模型中生成实体和服务接口
3. 写单元测试来测试服务方法。第一次尝试运行这个测试显然会失败,因为服务还没有实现。
4. 在服务层实现“get all users”逻辑
5. 重新测试确保测试通过
6. 实现前台界面的下拉列表,会使用刚刚创建的服务来完成
在第二个功能-“get timecards for the specified search criteria”会使用相同的的过程来实现。
10.开始应用程序
在这一章中,我们会使用AndroMDA插件创建一个起始应用。我们随后会在这个应用上增量的构建,来增加time tracking功能。当你的版本有问题时,我们建议你手头上有已经完成的程序(从上一章下载)。
在我们开始前有一个注意的地方-请小心和精确的跟随下面所有的指引。DO NOT不要走任何捷径,因为这样做会浪费你的时间。Ok,我们准备开始。下面的步骤创建了起始的应用。
1. 打开命令提示符窗口,把目录转换到你要创建应用程序的目录。在这个例子,我们选择了C:/目录,这个应用会创建在C:/timetracker。注意:如果你决定创建在不同的位置,确保在路径中没有空格,否则Maven会有构建问题。
2. 现在,执行下面的命令来生成起始应用。准确的回答下面的问题。你也可以在第一个问题输入自己的名字。J
C:/>mvn org.andromda.maven.plugins:andromdapp-maven-plugin:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'andromdapp'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [andromdapp:generate] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [andromdapp:generate]
INFO [AndroMDA] discovered andromdapp type --> 'richclient'
INFO [AndroMDA] discovered andromdapp type --> 'j2ee'
Please choose the type of application to generate [richclient, j2ee]
j2ee
Please enter the location in which your new application will be created
(i.e. f:/java/development):
C:/
Please enter your first and last name (i.e. Chad Brandon):
Naresh Bhatia
Which kind of modeling tool will you use? [uml1.4, uml2, emf-uml2]:
Use the list below to enter the correct choice:
ArgoUML: uml1.4
MagicDraw 9.x: uml1.4
MagicDraw 11.5: uml2
RSM 6: emf-uml2
uml1.4
Please enter the name of your J2EE project (i.e. Animal Quiz):
TimeTracker
Please enter an id for your J2EE project (i.e. animalquiz):
timetracker
Please enter a version for your project (i.e. 1.0-SNAPSHOT):
1.0-SNAPSHOT
Please enter the root package name for your J2EE project
(i.e. org.andromda.samples.animalquiz):
org.andromda.timetracker
Would you like an EAR or standalone WAR? [ear, war]:
ear
Please enter the type of transactional/persistence cartridge to use
[hibernate, ejb, ejb3, spring, none]:
spring
Please enter the database backend for the persistence layer
[hypersonic, mysql, oracle, db2, informix, mssql, pointbase,
postgres, sybase, sabdb, progress, derby]:
mysql
Will your project need workflow engine capabilities?
(it uses jBPM and Hibernate3)? [yes, no]:
no
Please enter the hibernate version number
(enter '2' for 2.1.x or '3' for 3.0.x) [2, 3]:
3
Will your project have a web user interface? [yes, no]:
yes
Would you like your web user interface to use JSF or Struts? [jsf, struts]:
struts
Would you like to be able to expose your services as web services? [yes, no]:
no
-------------------------------------------------------------------------------------
G e n e r a t i n g A n d r o M D A P o w e r e d A p p l i c a t i o n
-------------------------------------------------------------------------------------
Output: 'file:/C://timetracker/app/pom.xml'
Output: 'file:/C://timetracker/app/src/main/application/META-INF/jboss-app.xml'
Output: 'file:/C://timetracker/app/src/main/config/timetracker-ds.xml'
Output: 'file:/C://timetracker/common/pom.xml'
Output: 'file:/C://timetracker/core/target/classes/META-INF/ejb-jar.xml'
Output: 'file:/C://timetracker/core/pom.xml'
Output: 'file:/C://timetracker/mda/pom.xml'
Output: 'file:/C://timetracker/mda/src/main/config/andromda.xml'
Output: 'file:/C://timetracker/mda/src/main/config/mappings/WebMergeMappings.xml'
Output: 'file:/C://timetracker/mda/src/main/uml/timetracker.xmi'
Output: 'file:/C://timetracker/pom.xml'
Output: 'file:/C://timetracker/readme.txt'
Output: 'file:/C://timetracker/web/pom.xml'
Output: 'file:/C://timetracker/web/src/main/properties/messages.properties'
Output: 'file:/C://timetracker/web/target/timetracker-web-1.0-SNAPSHOT/WEB-INF/web.xml'
-------------------------------------------------------------------------------------
New application generated to --> 'file:/C://timetracker/'
Instructions for your new application --> 'file:/C://timetracker/readme.txt'
-------------------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 minutes 45 seconds
[INFO] Finished at: Sat May 20 21:47:51 EDT 2006
[INFO] Final Memory: 9M / 22M
[INFO] ------------------------------------------------------------------------
C:/>
检查由andromdapp插件生成的目录和文件。你会注意到在timetracker目录下的pom.xml文件。这些文件构成了几个Maven项目。实际上,timetracker目录包含下面的目录结构。
timetracker
|
|-- mda
|
|-- common
|
|-- core
|
|-- web
|
+-- app
l timetracker:这是主项目,控制整个构建过程和一般属性。
l mda:mda项目是应用的最重要的子项目。在src/main/uml目录下保存TimeTracker UML模型。mda项目目录也是AndroMDA配置的位置,用来生成组装应用的文件。
l common:common子目录包括被其他子项目共享的资源和类。这些包括value object和embedded value。
l core:core子目录包括资源和类,使用spring框架,Hibernate和/或EJB。这些包括了实体类,数据访问对象DAO,Hibernate映射文件和服务。
l web:web子项目包括构成表现层的资源和类。
l app:app子项目包括要求构建.ear包的资源和类。
你可以在timetracker目录下的readme.txt文件中找到关于这些文件的更多的细节。这个文件中也包括如何使用Maven target的描述。
配置Timetracker应用
我们要对由AndroMDA生成的项目做一些小的配置改变来适应TimeTracker构建,接下来告诉你这样做的原因。
打开在timetracker/mda/src/main/config/andromda.xml的配置文件。进行下面的修改:
1. 搜索叫做enableSpringTransactionsWhenEjbsEnabled的属性,并且把他的值从true改为fals。因为我们要使用EJB,我们不想让spring来控制数据库事务。
2. 搜索叫做bpm4struts的namespace。在这个namespace中,增加一个属性来改默认的日期格式,属性看起来像这样:
<property name=”defaultDateFormat”>MM/dd/yyyy</property>
3. 在bpm4struts的namespace中增加另外一个属性:
<property name=”normalizeMessages”>true</property>
这个特性允许更小的资源包生成,由一个简单的消息描述重复的因素。为了向前兼容,这个优化默认是关闭的。
4. 保存和关闭andromda.xml。
打开根目录的POM文件,位置在timetracker/pom.xml。做下面的修改:
1.
搜索指定jdbd驱动的下面的行:<jdbc.driver.jar>${jboss.home}/server/default/lib/hsqldb.jar</jdbc.driver.jar>
因为我们使用MySQL,修改这一行成下面的样子(保证你的驱动版本正确)
<jdbc.driver.jar>${jboss.home}/server/default/lib/mysql-connector-java-
3.1.13
-bin.jar</jdbc.driver.jar>
2.
搜索指定数据库用户名和密码的下面两行:
<jdbc.username>sa</jdbc.username>
<jdbc.password></jdbc.password>
把这部分修改为下面的内容:
<jdbc.username>timetracker</jdbc.username>
<jdbc.password>timetracker</jdbc.password>
3.
保存和关闭pom.xml。
打开POM文件,mda子目录下面,位置在timetracker/mda/pom.xml并且做从下面的修改
1.
搜索叫做hibernate.db.showSql的属性,并且把他的值从true改为false。这阻止收集的Hibernate消息打印到JBoss控制台上。我们仍然可以从JBoss log文件中找到适当的SQL消息。
2.
保存和关闭pom.xml。
11.UserService
定义
作为基于以上开发方法的讨论,我们的第一个迭代重点得到工作的搜索屏幕。有一个这个模型的屏幕:
要支持这样一个界面,服务层需要提供下面两个功能:
1.
能获得所有用户的列表为了填充搜索下拉列表(Submitter和Approver)
2.
能获得指定搜索条件的所有的时间卡
UserVO Value Object
让我们放大我们第一个功能,例如,获得所有用户列表。让我们决定我们会创建一个叫做UserService的服务,通过下面的方法提供服务。
public interface UserService
{
public UserVO[] getAllUsers();
}
UserVO
是关联User实体的value object。在最低限度,UserVO会需要两个属性用于drop-down来正常工作:用户ID和登陆名。然而,要使UserVO更可用,让我们在上面增加两个更多的属性:用户的first name和last name。基于这个讨论,UserVO能像下面那样建模。
注意:我们标示UserVO的stereotype为ValueObject。这会告诉AndroMDAUserVO是一种ValueObject。Stereotype决定了AndroMDA代码生成模式,这由AndroMDA代码生成模板来决定。
注意我们标识其中的一个属性为Long,三个属性是String。这些类型不能与java类型java.lang.Long和java.long.String类型混淆。在模型驱动架构中,模型保持技术的无关性并且因此所有的模型元素与平台实现类型无关。因此在上下文中的Long和String是平台无关的类型。当我们运行AndroMDA来生成代码时,它会翻译平台无关的类型为平台相关的类型,例如java.lang.Long和java.long.String。如果我们相同的模型生成.Net应用,AndroMDA会翻译Long为long?并且String翻译为System.String, .NET中等同于java.long.Long和java.lang.String。正如你所看到的那样,模型驱动方法的一个关键的优势是你在业务模型上的投资被保护,甚至随着技术的发展。
在额外的UserVO,我们建模了一种类型叫做UserVO[]。这种类型被需要用来表现返回值,从我们的服务方法中。不幸的,在UML中没有标准的方法来定义对象数组,因此我们采用这种技术作为工作环境。关注一些工具,例如MagicDraw,会接受UserVO[]作为方法参数或返回值,并且存储他作为带[]标记的UserVO类型-然而这是非标准的UML,因此不能被使用标准的UML API检索。小心,不要建模你的参数和返回类型。替代的,建模这些圆熟使用上面描述的workaround。
现在,让我们进入有AndroMDA应用插件创建的UserVO的空的模型中。如果你仍然记得,这个模型被创建在timetracker/mda/src/main/uml/timetracker.xml。请使用下面的uml工具。
- ArgoUML (under construction)
- MagicDraw 9.x
- MagicDraw 11.5
- RSM 6
现在,让我们要求AndroMDA来生成UserVO的代码:
1.
打开命令提示符,修改目录到C:/timetracker
2.
执行命令mvn install。确认你看到了BUILD SUCCESSFUL信息。
3.
留着命令提示符窗口以后构建使用。
在Windows Explorer中打开目录
C:/timetracker/common/target/src/org/andromda/timetracker/vo,注意UserVO类生成到了这里。打开类并且浏览他的内容。ValueObject stereotype触发在代码中只有一个产品生成,java类名表示valueobject。后来我们能看到stereotype的以便于触发多个工件的生成。
Eclipse
用户:AndroMDA也在c:/timetracker目录中生成了.project和.classpath文件。要浏览你的代码,看下面的步骤:
1.
启动Eclipse。
2.
选择File菜单的import。
3.
选择”Existing Projects into Workspace”并且点击next。
4.
在import对话框,点击browse
5.
浏览C:/timetracker点击OK。
6.
点击finish。现在timetracker项目可用了。
7.
在package explorer中右击timetracker项目,选择properties。
8.
点击java compiler,然后检查“Enable project specific properties”。
9.
因为我们要使用JDK5.0的特点,设置编译器兼容级别为5.0,点击OK。
10.
Eclipse
现在会要求“Build the project now?”,回答yes。
这个设置过程只要求一次。以后,当你再生成代码时(产生了新的.project和.classpath文件),简单的在timetracker项目上右击,选择refresh。