第三部分:XDE中模式的高级话题
在前面的部分中,我们具体介绍了XDE的使用方法,但是XDE中关于模式的概念有很多,有一些很直接,而有一些却比较的隐讳。这一部分的内容,将对XDE中的一些高级概念作初步的阐释,并给出了一些小的例子。希望能够帮助大家更在对XDE本身,以及XDE所提倡的模式驱动的开发方法有更多,更为深入地了解。假如没有看过前几期的读者,还是最好找来看看,直接看着一期的内容,理解起来可能会有一些困难。
1. 代码模版(Code Template)
模式,或者说设计模式,很大程度上是对对象结构上的描述。也就是说,模式最终的实现以及生成的代码,也大多数是属于框架性质的--只有类,属性或者方法的定义,类之间的引用,继续等等之类的代码,而对于具体的方法中的代码,它往往无能为力。这也是大多数正向工程工具都欠缺的一个部分。
实际上,假如只是一些简单的语义,比如对象的创建,固定方法的调用而没有涉及复杂的交互的,我们也是能够从模型的语义中生成具体的代码。在XDE中,通过代码模版,来完成一些简单方法的参数化的代码生成。
如同模式一样,代码模版也是可以拥有参数并在具体生成的时候进行替换绑定的。在代码模版中,可以使用两种类型的参数:strings和model elements。
Strings:简单的字符串,在代码生成的时候XDE会用具体的字符串来替换所有的这些字符串参数。
Model elements:一个模型元素。XDE中提供了一个简单的编程模型,可以通过对模型元素API的调用(比如得到一个类的所有公有方法)来完成给位复杂的代码定制。和模式联系在一起的时候,Model Elements类型的参数可以是模式中的一个模版参数,在模式展开的时候,会用具体的模版参数值来替换这个代码模版中参数。
XDE代码模版的形式很像jsp或者ASP中使用的形式。你假如对Jsp的机制很了解的话,那么你也可以很轻易的理解代码模版的机制了。
在一个代码模版中,代码被分为两个部分,一部分是直接输出的,不经过任何的处理。另外一个部分是在<%和%>这两个标号之间的脚本内容,通过对参数或者其它元素的处理之后再进行输出。假如Jsp或Asp一样,它也是用简单的<%=var%>来进行变量的输出(var是一个变量)。所有<%和%>之间的内容,是使用脚本语言来编写的。现在XDE中的代码模版只支持javascript语言。
下面的一个代码模版的例子选自XDE的在线文档,用以在调试的时候打印对象的当前状态。每一个应用了这个代码模版的方法,将会在调用方法前在控制台输出对象的状态,供调试使用。
<%
// assume: myClass is "this" Class with debug operation
function debugStatements(myClass) {
var attributeCollection = myClass.GetAttributeCollection();
var attributeCollection1= Interfaces.queryInterface(attributeCollection, "com.rational.rms.IRMSElementCollection");
var attributeCount = attributeCollection.getCount();
debugStatements = "";
for (i=1; i<=attributeCount; i++) {
var rmsAttribute = attributeCollection1.GetElementAt(i);
var attrName = rmsAttribute.getName();
%>
System.out.println( "<%=attrName%>" );
<%
}
}
//assume: myOperation is debug operation
function debugOperation(myOperation) {
var thisOperation = Interfaces.queryInterface(myOperation, "com.rational.uml70.IUMLOperation");
var thisClass = thisOperation.GetContainer();
var myClass = Interfaces.queryInterface(thisClass, "com.rational.uml70.IUMLClass");
debugStatements(myClass);
}
var myOperation = Interfaces.queryInterface(thisElement, "com.rational.uml70.IUMLOperation");
debugOperation(myOperation);
// end
%>
在上面的代码模版中,定义了两个方法debugStatements和debugOperation,debugOperation接受当前元素作为参数,并由其得到debugStatements的参数--一个包含了这个方法的对象,并在debugStatements中输出:System.out.println( "<%=attrName%>" );
以在控制台输出对象的状态。
在代码模版中,可以用一个"thisElement"的标准的预定义变量来代表代码模版被应用的元素,在当前版本的XDE中,只能够在类中的方法上应用代码模版。
当然,代码模版的一个最大的作用,就是同模式的模版参数一起来使用了。一个最简单的例子,比如说,假如我创建了两个模版参数,设为tp1和tp2,分别代表了两个类。我需要在tp1代表类的方法op1()中创建tp2所代表类的一个对象,并把它赋给一个tp2类型的引用。那么我们可以为代码模版中定义一个参数codetp,类型为String,并为其赋值为<%=tp2%>。则在为op1()所创建的代码模版中,我们可以这样写:
<%=codetp%> a<%=codetp%>Object=new <%=codetp%>();
假设tp2最后被绑定到一个名为ClassTP的类上,代码模版被展开后的结果就是:
ClassTP aClassTPObject=new ClassTPObject();
这样就完成了我们想要的功能。
这只是一个最为简单的功能。实际上,XDE中的代码模版的功能是非常强大的,通过Javascript脚本语言和XDE内建的编程模型,我们可以创建非常复杂的代码模版,使得代码的生成率大大提高。