一个典型的开发周期涉及到分析和捕获业务目标的业务分析(Business Analysis)模型的创建,然后将其转换为一个软件体系结构模型。IBM Rational Software Architect中的Business Process-to-Service Model SOA转换特性有助于您创建这一模型。本文提供了一个入门示例,向您详细演示如何创建一个自定义的过程分解(process decomposition),用于将您的业务处理过程转换为一个服务模型。本文所面向的是那些对如何创建转换扩展比较熟悉的读者。
Business Process-to-Service Model转换特性概述
IBM Rational Software Architect中的Business Process-to-Service Model 转换特性包括主体转换和三个默认的扩展。
主体转换创建一个统一建模语言控件(Unified Modeling Language Component)来描述服务提供者(Service Provider)。转换还通过端口对组件进行组装,每一个表现界面或者是被服务所提供,或者是被服务所需要。最终,一个CollaborationUse元素被创建出来,它将体系结构模型中的服务所表现的组件同业务分析模型(Business Analysis Model)中的协作(Collaboration)链接起来。组件上的每一个端口都将被绑定到适当的角色。CollaborationUse元素,同端口和角色绑定一起,表现为一个协议验证段。该合同确认允许跟踪到业务分析(Business Analysis),确认组件按照业务分析模型中所指定的处理过程得以实现。
图1. 转换工具的主要输出包括:端口、协议验证段、CollaborationUse元素以及角色绑定。
主体转换并不提供它所生成的组件的任何内部分解。其原因就在于这些细节依靠执行和配置域的决定和约束。
创建内部分解的任务落到了主体转换的扩展肩上。每一个扩展都创建其自己的业务处理过程的分解,并且描述它的内部工作。尽管很少有这样的扩展被提供,但是您能够通过创建和注册自定义的扩展来创建不同的服务分解,从而满足这些特定的需要。
自定义扩展场景
在这个例子中,假设您已经为新的服务创建了一个业务分析(Business Analysis)模型,并且将遗产服务综合到解决方案之中。这一模型描述了通过共同工作来创建一个Medical Marketplace一族服务。这个Medical Marketplace呈现出各种各样的医疗服务。提供服务的每一个客户请求都将被处理,并且一个适当的服务将被选中来提供给客户端。当服务被执行时,付款将被收集,并且客户反馈将被提交到市场数据库(请参见图2所示)。
图2. Medical Marketplace的Business Analysis Model的业务处理过程。
我们来关注以下付款收集(Payment Collector)服务,它负责在医疗服务被提供之后开列账单以及收集付款。它要求某些种类的簿记保存有关交易的记录。它将日志(Logger)服务用于这些目的。这些服务的目的是有效利用现已存在的Java?代码。
假设现有遗传下来的账单(Billing)和日志(Logging)服务。账单(Billing)服务表现了一个被称作Billing的Java接口。这里有一个通过com.acme.billing.MedicalBilling Java类的具体执行。MedicalBilling使用由另一个遗产库所定义的日志(Logging)服务:com.acme.logging(请参见图3所示)。
图3. Java遗产库包含了Billing和Logging服务的Java执行。
完整的SOA解决方案被配置在服务组件定义语言(Services Component Definition Language,SCDL)中。自定义扩展的目的是生产一个被连接到基于Java的遗产库的SCDL模块。
将业务处理过程扩展为一个服务模型所需要的基本步骤
·创建一个Eclipse插件程序项目。
·创建一个转换类(请参见列表1中的例子)。
列表1. 创建一个转换类的代码。
package com.ibm.xtools.transform.cfm.example.transform;
import com.ibm.xtools.transform.cfm.example.rules.MyPopulateComponentRule;
import com.ibm.xtools.transform.core.Transform;
public class MyTransform
extends Transform {
//id of the transformation
public static final String TRANSFORM_ID =
“com.ibm.xtools.transform.cfm.example.transform.MyTransformid”;
public MyTransform() {
super(TRANSFORM_ID); // instantiate transformation using id
add(new MyPopulateComponentRule());//program transformation with this rule
}
}
注释:
当创建一个扩展号的时候,请尽量做到唯一性。这一点是非常重要的,这是因为当转换配置指明一个处理过程应当使用一个扩展号被转换的时候,具有那个扩展号的扩展将被选中,并且被用于转换该处理过程。
将功能性编入MyPopulateComponentRule的代码。列表2中的代码强调了这一规则的关键功能。
列表2. 用于MyPopulateComponentRule的代码。
public class MyPopulateComponentRule extends ModelRule {
/*
* canAccept method asserts wither or not the extension is applicable
*/
public boolean canAccept(ITransformContext context) {
// the rule will be invoked if the current node on the source side is
// an instance of UML Collaboration and the node on the target side
// is instance of UML Component
return context.getSource() instanceof Collaboration
& context.getTarget() instanceof Component;
}
/*
* createTarget method will perform additional (to main) transformation of the
Collaboration(service) in the source
* model to the elements in the target model
*/
protected Object createTarget(ITransformContext context) throws Exception {
Component collaborationComponent = (Component) context.getTarget();
Component java_adapter = createJavaConverter(collaborationComponent);
assert (java_adapter != null);
Property attribute = collaborationComponent.createOwnedAttribute(
“java_adapter”, java_adapter);
for (Iterator e = collaborationComponent.getOwnedPorts().iterator(); e.hasNext();) {
Port port = (Port) e.next();
// there will only one port that provides interface to the outside.
if (!port.getProvideds().isEmpty()) {
Port in_port = java_adapter.createOwnedPort(“in_” + port.getName(), null);
Interface anInterface = (Interface) port.getProvideds().get(0);
addProvidedInterface(anInterface, in_port);
createConnector(collaborationComponent, port, in_port, null, attribute,
ConnectorKind.DELEGATION_LITERAL);
} else if (!port.getRequireds().isEmpty()) {
Interface anInterface = (Interface) port.getRequireds().get(0);
Type type = createUsage(java_adapter, anInterface);
Port out_port = java_adapter.createOwnedPort(“out_” + port.getName(), type);
createConnector(collaborationComponent, out_port, port, attribute, null,
ConnectorKind.DELEGATION_LITERAL);
}
}
return collaborationComponent;
}
/*
* auxiliary method – creates java adapter component for the role,
which represents Collaboration (service) itself
*/
private Component createJavaAdapter(Component collaborationComponent) {
for (Iterator e = collaborationComponent.getOwnedPorts().iterator(); ehasNext();) {
Port port = (Port) e.next();
if (!port.getProvideds().isEmpty()) {
return (Component) collaborationComponent..createPackagedElement (port.getName() +
”Adapter”,UMLPackage.Literals.COMPONENT);
}
}
return null;
}
…
}
create the extension condition class:
/**
* com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition
*/
public class MyExtensionCondition
extends TransformCondition {
public MyExtensionCondition() {
super();
}
protected boolean isContextSatisfied(ITransformContext context) {
return (context.getSource() instanceof Collaboration)
& CommonConfigUtil.getExtensionIdFor(
(Collaboration) context.getSource(), context).equals(
MyTransform.TRANSFORM_ID);
}
}
该条件将在运行时被使用,来断定一个业务处理过程是否使用您自定义的转换被配置、被转换。
将您的扩展注册到一个XML插件程序文件中。列表3显示了一个声明自定义扩展的例子。
列表3. 一个声明自定义扩展的XML插件程序文件的代码示例。
<?xml version=”1.0″ encoding=”UTF-8″?>
<?eclipse version=”3.2″?>
<plugin>
<extension
point=”com.ibm.xtools.transform.core.transformationExtensions”>
<TransformationExtension
author=”you”
description=”my custom extension”
document=”optional”
enabled=”true”
id=”com.ibm.xtools.transform.cfm.example.transform.MyTransformid”
name=”My custom extension”
targetTransformation=”com.ibm.xtools.transform.cfm.wbm.transforms.MainTransform”
version=”1.0.0″>
<TransformDefinition
acceptCondition=”com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition”
class=”com.ibm.xtools.transform.cfm.example.transform.MyTransform”
id=”com.ibm.xtools.transform.cfm.example.transform.MyTransformid”/>
<ExtendTransform
targetTransform=”com.ibm.xtools.transform.cfm.wbm.transforms.OwnedBehaviorTransform”>
<AddTransform id=”com.ibm.xtools.transform.cfm.example.transform.MyTransformid”/>
</ExtendTransform>
</TransformationExtension>
</extension>
</plugin>
这一例子自定义扩展的目标是Business Process-to-Service Model主体转换:
com.ibm.xtools.transform.cfm.wbm.transforms.MainTransform
它也指定了那些扩展条件需要被用来决定扩展的能力:
com.ibm.xtools.transform.cfm.example.condition.MyExtensionCondition
最后,它指定了转换的分支,哪一个转换将通过这个扩展被扩展:
com.ibm.xtools.transform.cfm.wbm.transforms.OwnedBehaviorTransform
配置自定义的扩展
·配置转换。
·在您完成前述各个步骤之后,将您的插件程序导出到您的插件程序目录下,并且重新启动Rational Software Architect。
您的自定义扩展将可以用于从Configuration UI(用户接口)中进行选择,如图4中所示。
图4. 配置一个带有自定义扩展的转换。
·配置一种处理过程,用来使用自定义的扩展。
·保存配置,并且运行转换。
·处理输出、继续建模、授权到遗留代码(请参见图5所示)。
图5. 被转换的付款收集器(Payment Collector),使用自定义的扩展分解。
为了自定义的扩展而被创建的分解如图5中所示。现在,可以继续下一步的操作。
授权调用Java库的服务
Java适配器的作用是授权到Java库的调用。以建模:
·通过键入BillingComponent为付款收集器(Payment Collector)创建第二个属性(部分),并且添加两个端口:
向myRoleAdapter添加第一个端口,设置被需要的接口为:
com.acme.billing.Billing
向Billing组件添加第二个端口,设置其类型为:
com.acme.billing.MedicalBilling (请参见图6所示)。
·连接两个端口。
图6. 将扩展适配到遗留代码。
注释:
账单(Billing)服务需要另外一种被称作日志(Logger)的服务。如果Logger服务的执行同Billing一样可用的话,那么您就能够以同样的方式建模Logger和Billing。否则的话,它就被作为myRoleAdapter组件的一部分功能被建模。
这一模型现在能够被SOA转换来使用,创建配置产品。SOA Transformation将把Payment Collector组件转换到一个IBM?WebSphere?Integration Developer业务集成模型项目中。用于Java适配器和Medical Billing的部分将被修改到那个模块内部的一个Service Component Architecture(SCA)组件中。为MedicalBilling而创建的SCA将把组件实现参考内容指向Java遗留库。
总结以及第3部分内容展望
正如您从本文中所学到的,Business Process-to-Service Model转换特性支持在WebSphere Business Modeler中的业务分析建模和UML中的设计建模之间搭建的桥梁。具有特定配置域和执行域需求的业务,能够适应这一转换来满足它们的需要。由转换所创建的产品能够在Rational Software Architect中被进一步的建模。它还能够通过使用由Rational Software Architect所提供的SOA转换工具被转换到一个WebSphere Integration Developer项目中。
您能够在本系列文章的下一部分(第3部分:UML到SOA)中找到更多关于SOA转换的信息。那篇文章详细解释了如何使用包含在Rational Architect Version 7.0.0.2及其以后版本中的UML-to-SOA转换工具从软件服务的UML模型转换到特定域的SOA实现。这一工具将把用于特定软件执行和运行时间的不同转换扩展汇集到一起。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
如何建立自己的UML图库
没有适当的沟通,想法和计划的执行就会出错,或者被遗忘。统一建模语言经常用于各种睡吧样的蓝图中,来映射出系统计划。事实上,UML已经成为许多软件开发人员选项。
-
心态决定统一建模语言成败
太过于追逐流行软件,对开发人员的职业生涯百害而无一利,有些专家这些说。虽然编程语言来来去去,但确实有一些技能和属性需要磨练,这可以带来一份薪水丰厚的工作。
-
前期设计够用就好
前期做完整设计的瀑布模型时代已经结束了吗? 本文建议前期做足够的架构设计,以便提供项目启动所需的结构,统一团队愿景以及评估可能的风险。
-
软件架构:开发人员必知的五件事
软件开发这一行业要么是突飞猛进,要么是深陷囹圄。一方面,我们推动它向前发展,重塑我们构建软件的方式。另一方面,我们不断忘记过去的好。