驱动开发网:XDE中模式驱动的设计和开发( 3)

  第 3部分:XDE中模式高级话题

  在前面部分中我们详细介绍了XDE使用思路方法但是XDE中有关模式概念有很多些很直接而有些却比较隐讳部分内容将对XDE中些高级概念作初步阐释并给出了些小例子希望能够帮助大家更在对XDE本身以及XDE所提倡模式驱动开发思路方法有更多更为深入地了解如果没有看过前几期读者还是最好找来看看直接看着内容理解起来可能会有些困难

  1. 代码模版(Code Template)

  模式或者说设计模式很大程度上是对对象结构上描述也就是说模式最终实现以及生成代码也大多数是属于框架性质--只有类属性或者思路方法定义类的间引用继承等等的类代码而对于具体思路方法中代码它往往无能为力这也是大多数正向工程工具都欠缺个部分

  实际上如果只是些简单语义比如对象创建固定思路方法而没有涉及复杂交互我们也是能够从模型语义中生成具体代码在XDE中通过代码模版来完成些简单思路方法参数化代码生成

  如同模式代码模版也是可以拥有参数并在具体生成时候进行替换绑定在代码模版中可以使用两种类型参数:s和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;
%>
.out.prln( "<%=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和debugOperationdebugOperation接受当前元素作为参数并由其得到debugStatements参数--个包含了这个思路方法对象并在debugStatements中输出:.out.prln( "<%=attrName%>" );

  以在控制台输出对象状态

  在代码模版中可以用个"thisElement"标准预定义变量来代表代码模版被应用元素在当前版本XDE中只能够在类中思路方法上应用代码模版

  当然代码模版个最大作用就是同模式模版参数起来使用了个最简单例子比如说如果我创建了两个模版参数设为tp1和tp2分别代表了两个类我需要在tp1代表类思路方法op1中创建tp2所代表类个对象并把它赋给个tp2类型引用那么我们可以为代码模版中定义个参数codetp类型为String并为其赋值为<%=tp2%>则在为op1所创建代码模版中我们可以这样写:

  <%=codetp%> a<%=codetp%>Object= <%=codetp%>;

  假设tp2最后被绑定到个名为ClassTP类上代码模版被展开后结果就是:

  ClassTP aClassTPObject= ClassTPObject;

  这样就完成了我们想要功能

  这只是个最为简单功能实际上XDE中代码模版功能是非常强大通过javascript脚本语言和XDE内建编程模型我们可以创建非常复杂代码模版使得代码生成率大大提高

  2.模式小脚本(Scriptlets)

  小脚本是种可执行代码片断实际上在上面对代码模版介绍中我们已经接触到这种小脚本<%=var%>就是种简单小脚本小脚本不仅能够应用在代码模版中还可以使用在模型其它地方比如类属性或者思路方法名字元素属性值模型文档注释关联端点名等等几乎在任何可以使用地方都可以使用小脚本这种小脚本语法很简单: <%=scriptlet text%>使用javascript脚本语言还可以在<%和%>标记的间加入其它片断

  小脚本在模式被展开时候被运行并用运行结果串来替代这段脚本最为普遍个使用方法是用来动态替代模版参数名字比如如果在模式中定义了个名为tp1模版参数那么小脚本<%=tp1%>在模式被展开时被替换成tp1所绑定参数值名字如果tp1帮定到个类名为TPClass类上那么最后所有<%=tp1%>都被替换成TPClass

  复杂比如我们可以在对这个类文档中使用这个小脚本:

Name Length: <%= tp1.getName.length%>
Name Sub: <%= tp1.getName.sub(0, tp1.getName.length-1)%>
  这样最后文档也完成了

  在脚本中使用具体API在Rational尚未公布但是可以使用如下个小窍门技巧来得到个模型元素API首先定义

function show_props(obj, obj_name) {
var result = "";
for (var i in obj) {
EAEventData.AddOutputMessage(obj_name + "." + i + " = " + obj[i]);
}
}
  然后再它:

show_props(tp1, "tp1");  这样这个脚本能够在XDE输出窗口中输出给定模型元素可以被使用API

  3. 值源(Value Source)和值集

  在创建个参数时候你可以选择指定这个参数个值源来指明这个参数所接受输入思路方法这些思路方法有如下 3种:

  · User:缺省值在选择了这种参数输入思路方法后意味着在应用模式时用户必须从现有模型中选择个类型相符元素来作为传递给这个参数

  · Generated:这个值意味着在应用模式时参数值将被自动创建用户只需要提供串作为生成参数值名字即可

  · Collection:从个给定元素中派生出个值或者值集来为目标参数赋值这个给定元素被称为Collection宿主元素(Owning Element)它可以是任何模型元素在指定了宿主元素名称后可以为其创建过滤器来选择需要从中派生内容即Collection个简单例子你可以选择个类所有公有属性作为个Collection然后将这些属性值传递给目标参数

  这些思路方法可以被单独使用也可以被组合使用来给用户提供多种选择思路方法

  XDE中为某些类型模版参数提供了种值集机制来限定模版参数取值比如可以为Integer类型模版参数提供个值集在应用模式时候这个模版参数取值就只能够从给定集合中选取有些时候这种窍门技巧是很有用可以约束用户取值范围不会出现不合法结果

  4. 用约束创建可选元素

  XDE中可以通过约束来创建个可选元素这个元素是否在模式展开时候被生成取决于给定约束值:如果约束值为true它就会被生成;反的就不会被生成这种约束可以被应用到模型中任何元素上约束条件通常取决于某元素属性取值比如判断个类可见性是不是public什么也可以通过ANDORNOT来连接单个属性判断来构造更为复杂约束

  例如下面表达式:

  Model1::Package2::Class1.Visibility = "PUBLIC"

  就是个约束用来判断Model1::Package2::Class1可见性(可以是PUBLICPRIVATEPROTECTED或者PACKAGE)是否为PUBLIC如果是约束表达式返回值为true否则返回值为false如果 Model1::Package2::Class1不存在表达式指出有存在

  在XDE模式定义中可以有两种约束存在:

  1、 属性约束(Property constras):是对模型元素元模型属性约束上面例子即为属性约束

  2、 关系约束(Relationship constras):用来判断模型元素的间特定关系例如两个类的间继承关系类和接口的间实现关系等等

  你可以不用去记得到底某个类型元模型中到底有哪些属性某两个类的间到底有哪些思路方法在XDE中个约束编辑器来帮助你构建约束所有工作只需要用鼠标选择即可

  5. Callouts

  模式Callouts用来响应些事件比如在应用模式的前或者在应用模式的后分别对应着PreApply和PostApply这两个Callouts在发生这些事件时候相对应Callout中定义脚本被

  并非所有模式都需要使用到Callouts它只是用来对付些用模式机制难以解决问题Callouts 能够定义在模式或者模版参数上 如下图:

  

  在创建个Callout时候通常需要使用到Javascript来进行些处理在XDE中个全局EAEventData对象它提供对模式引擎以及XDE中其它部分编程接口但是有关它细节文档不全我们尚未得知估计在以后XDE版本中会有披露个简单例子如下:

EAEventData.AddOutputMessage("Test message");  在EAEventData对象AddOutputMessage思路方法可以在output视图中添加串数据

  Callouts提供了对模式引擎和XDE借口理论上来讲它可以来完成任何模式引擎能够完成功能因而它是非常强大但是我们还是应当尽量避免使用它它太复杂而且具体接口尚未被标准化在考虑使用Callouts的前应该先查找模式设置其它地方看看是否已经被实现了

  6. 模式组合

  很多时候模式并不是单独使用例如在使用抽象工厂模式(Abstract Factory)时候我们往往需要将抽象工厂定义为个单件只允许由个抽象工厂例子存在这样我们就需要使用到另外个创建型模式:单件模式(Singleton)这样模式组合例子其实很多XDE中个简单使用办法就是先应用次抽象工厂模式再在模式展开基础上应用次单件模式但XDE还提供了更为强大也更为复杂思路方法:将模式组合在创建个新模式--就上面例子我们姑且称其为工厂单件模式吧这样我们只用这个应用模式就可以得到很好效果

  这样实现在XDE中其实并不难只需要在定义模式结构时在引入以定义好模式即可比如在定义抽象工厂模式时候假设现在所有抽象工厂参和者和模版参数都已经建立好了要引入单件模式只需要简单在上下文菜单中选择就如同在般情况下应用模式将抽象工厂中参和者ConcreteFactory指定为单件模式中Singleton模版参数参数值然后应用单件模式即可这种模式组合为更大更复杂问题提供了解决方案

  整理总结

  Rational XDE确实是个非常强大功能本文对其在模式建模及应用方面话题作了详细讨论基本上涉及了XDE中模式方方面面相信大家对XDE中基于模式开发概念应该有了个比较清楚地了解而实际上模式功能只是XDE中个小部分还有很多其它功能也是非常强大比如正向/逆向工程

  但是在现阶段XDE还只能被称为是个很有潜力产品尚不能称为个成熟产品方面它所提倡开发模式和开发思路方法还不是非常流行方面产品本身Bug也比较多参考资料也比较少我们再利用XDE进行开发时候虽然为其强大性能所折服但也总是有些小毛病让人很烦不过XDE正处在不断完善过程中相信其下个基于Eclipse2.0版本会更加优秀



  参考文献:

  1. UML参考手册 机械工业出版社

  2. UML用户指南 机械工业出版社

  3. 设计模式:可复用面向对象软件Software基础机械工业出版社

  4. Rational XDE在线文档其中可以得到XDE使用大部分介绍

  5. Rational.net开发者网站WebSite:www.rational.net有许多有关XDE功能详细文档



Tags:  驱动程序开发网 领域驱动设计 驱动开发 驱动开发网

延伸阅读

最新评论

发表评论