IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Rational  >

使用 Rational Modeling Extension for Microsoft .NET 对 C# 应用程序进行建模,第 3 部分: 对 C# 数组、指针、局部及通用类型进行建模

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

英文原文

英文原文


级别: 中级

Rajeshwari Rajendra, 软件工程师, IBM India

2008 年 10 月 13 日

本文面向于 Microsoft® .NET 应用程序开发人员。 它详细说明了如何使用 IBM® Rational® Modeling Extension for Microsoft .NET 所扩展的 Rational 建模工具中的建模功能来建模 .NET C# 应用程序。 此扩展可以与 IBM® Rational® Software Modeler,IBM® Rational® Systems Developer 和 IBM® Rational® Software Architect 一起使用。 本文假定,您熟悉使用 Rational 建模工具的基本 UML 建模概念。

IBM®Rational®Modeling Extension for Microsoft®.NET 是对 Rational 建模工具的扩展,以帮助 .NET 应用程序开发员设计他们的应用方案。 在写这篇文章时,Rational Modeling Extension for Microsoft .NET 支持 C# 应用程序的建模。这篇文章的前两部分解释了C# 应用程序建模的基本概念。本文,是此系列的第三篇文章,将描叙如何使用 Rational Modeling Extension for Microsoft .NET 建模如下 C# 概念的步骤。

  • 数组
  • 指针
  • 局部类型
  • 通用类型

本篇文章将讨论映射模型的使用方法,控制代码自动产生到除默认文件之外的其它文件。

简介

本篇文章包括了 C# 应用程序开发员的高级建模概念。 文章假设的前提是,您已熟知基本 C# 建模概念,这在本系列其他文章中已有所涉及,也就是使用 Rational Modeling Extension for Microsoft .NET 建模 C# 应用程序的第一及第二部分,参见参考资源。以下所有章节都要求您已经建立一个模型并引进一个 C# 配置,如第一部分中所说明的。





回页首


建模 C# 数组

C# 数组可以是单维的、多维的,甚至多重数组。 当您建立一个数组类型时,数组的大小并不确定。为建立一个数组模型,在 UML 属性及 UML 方式参数中使用 <<CSharp Array>> 模板。一旦应用了该模板,您就可以确定 rank_specification 原型属性的值,这将决定建立的数组是单维的,还是多维的,或者是多重数组。

为了更好的理解,建立一个名为 ArraysExample 的 UML 类型,该类型有三个属性以代表单维、多维及多重数组。按照以下步骤以完成该项。

  1. 建立一个 UML 类,并将其命名 ArrayExample。确定 C# 配置被应用于 UML 模型中。
  2. 创建一个 UML 属性,并将其命名 singleDimArray。将它的 Type 设置为 C# <Primitive Type>。 int 及其 Default Valuenew int[5]
  3. 应用<<CSharp Array>>模板,并设定该模板的属性 rank_specification[ ]
  4. 类似的,建立一个名为 multiDimArray 的 UML 属性,并使其 Default Valuenew int [ 6, 4],设置模板属性 rank_specifications 为 [ , ]
  5. 以同样的方式,建立一个名为 jaggedArray的 UML 属性,并使其 Default Valuenew int[3][ ],设置模板属性 rank_specifications 为 [ ] [ ],如图 1 所示。

图1. 使用 <<CSharp Array>> 原型建模 C# 数组
使用 <<CSharp Array>> 原型建模 C# 数组




回页首


建模 C# 指针

在 C# 中, 指针可被应用于非安全环境。非安全环境,可以通过使用 unsafe 修饰符得以标记,在建立一个类型或成员时。为了建立 UML 中不安全内容的模型,设置 unsafe 模板属性为 true 模板属性 unsafe在可应用于UML类型、内表、属性及操作的模板中是可利用的。例如,为了在不安全的内容中使用指针,您可以设置在<<CSharp Class>>, <<CSharp Interface>>, <<CSharp Method>>, <<CSharp Field>>, <<CSharp Indexer>> 中的修饰符 Unsafetrue

例如,您可以为一个二进制树建立类型 Node 两个指针指向左右子节点。根据以下步骤以完成该项。

  1. 建立一个 UML 类型并将其命名为Node。您需要用到修饰符 unsafe,应用 <<CSharp Class>> 模版并设定 unsafe 模版属性值为 true
  2. 现在为一个类填加一个属性并将其命名为 left,设其值 TypeNode。应用模版<<CSharp Pointer>>并设其属性值 indirection_specification 为*
  3. 以相同的方式,添加另一个属性值并将其命名为 right。您已建立了两类型型的指针 Node *,如图 2 所示。

图2. 使用 <<CSharp Pointer>> 模板建立 C# 指针模型
使用 <<CSharp Pointer>> 模板建立 C# 指针模型




回页首


C# 建模局部类型

在 C# 中,给出类型、内表及跨越不同文档结构的部分定义是可能的。基本上,局部类型的概念允许您(作为应用程序开发员)定义跨越多个文档的一个类型的莫个部分,通过在每个定义中使用关键字,partial通过使用局部类型的概念,开发员在不同文档的某个对象上封装不同的属性(数据或行为)。最后得到的实际类型是所有不同定义的组合。您可以参考 C# 语言教程以获得关于局部类型的更多信息。

本篇文章将向您展示怎样在 Rational Modeling Extension for Microsoft .NET 中定义局部类型。在定义局部类型的开始,在要求的栏目中创建相应的 UML 类型(类型或内表)。您可以在 UML 类型中使用 <<CSharp Struct>> 模板,如果您定义一个 partial struct。该 UML 类型和其相关的 C# 结构有着相同的名字,但是没有任何的属性和操作。

基本上,该类型有空定义。为了对局部类型进行个人定义,您可以创建和定义数目一样多的 UML 类型,并给它们起一些任意但有意义的名字。其名字与它们各自的代表分部定义的 UML 类型无关。这些类型中每一个都包括属性、操作及与代表它们的分部定义的相关内容。最后,您需要创建一个UML dependency ,与 <<CSharp Partial>> 一样的关系模板, 从其各自定义开始到一个空定义的 UML 类型(类型的名字与 C# 局部类型相同,但是其定义是空的)。

为了更好地理解这个概念,从两个视角建立一个 ATM 机器的模型(一个视角是用户的,另一个是银行的),将此两种视角建立为两种分类定义的模型

如果您是从用户的视角出发来定义这个 ATM 机器,您或许会考虑到诸如以下的操作。

  • 插入 ATM 卡
  • 获得 PIN 密码
  • 取款

而另一方面,如果您是从银行的视角出发来定义这个 ATM 机器,您或许会考虑到诸如以下的操作:

  • 验证卡的有效性
  • 验证 PIN 密码有效性
  • 减少用户帐户上的存款额

两种视角都定义了 ATM 机器,但是是从两个不同的角度。因此,该ATM机器总体上拥有从两个视角出发所有的操作功能。现在,您可以看一下,建立 ATM 机器分部定义的模型需要哪些步骤。

  1. 建立一个 UML 类型,并将其命名为 ATM_Machine
  2. 建立一个 UML 类型,并将其命名为 ATM_UserPerspective。下一步,建立该属性与属性 ATM_Machine 的从属关系。 同时,对该从属关系应用模板 <<CSharp Partial>>。 这意味着 ATM_UserPerspective 是类 ATM_Machine 部分定义中的一个。
  3. 添加诸如 insertCard(String cardNumber), enterPIN(int PIN), enterAmount(long amount), disburseCash( ), ATM_UserPerspective 之类的 UML 操作。
  4. 添加另一个 UML 类型并将其命名为 ATM_BankPerspective,将其也与类 ATM_Machine 建立 UML 从属关系。 对此从属关系应用模板 <<CSharp Partial>> ,这意味着 ATM_BankPerspective 是类 ATM_Machine 的另一个分部定义中的一个。如图 3 所示。
  5. 现在添加诸如 validateCard( ), checkAccountBalance( ), reduceBalance(String accountNumber, long amount) 以及 ATM_BankPerspective 之类的 UML 操作。

    注意:当您对一个模型限制分部类型运行 UML 至 C# 转变时,每一个分部定义将将产生 在一个文档中,并且文档的名字与分部定义的名字相同。但是该文档的实际类型将有与其相关分部类型的名字(即 UML 从属关系终止处空 UML 类型的名字)带有关键字partial。为了在不同文档中重新指导个人定义的代码生成, 可使用映射模型(详述见以下章节)。

图3.使用 <<CSharp Partial>>模板建立 C# 局部类型的模型
使用 <<CSharp Partial>>模板建立 C# 局部类型的模型




回页首


建立 C# 模型的通用类型

在 C# 中,您(作为一名开发员)可以定义类型、内表、结构、代表及方法的通用类型。本篇文章将结合实例讨论怎样去建立这些模型。但是,在您进行之前,您需要明白 C# 通用类型申明及通用类型实例的两个方面。

一个通用类型的申明仅仅定义了类型、代表或一种方法的模板。 通用类型的使用需要通过向通用类型(或模板)参数赋值来提供实例

为了理解这个概念,考虑一个例子。试着建立一个拥有一定数量书架的简单图书馆系统的模型,每一个书架拥有一些按其名字排序的书籍。listsorted lists可被用作储存一些信息,您可以把它们建立为通用类型的模型并用作储存相关信息(书籍)。为了建立该模型,您将定义一个通用类型表并将它用作定义一个排序表。该排序后的表将用作储存关于书籍的相关信息。

在以上例子中出现的代码将在表1中显示出来。


表1.使用通用类型建立图书馆系统模型的范例代码
				
using System;

public class List<T>
{
    public bool isEmpty()
    {
        return true;
    }
    public int getSize()
    {
        return 0;
    }
    public T get(int index)
    {
        return null;
    }
}
public class SortedList<X> : List<X>
{
    public void sort(bool ascendingOrder)
    {
    }
}
public class Book
{
}
public class Shelf
{
    SortedList<Book> sortedBooks;
}

public class Library
{
    List<Shelf> shelves;
}

您创建一个图书馆系统的模型(表1)所需采取的步骤如下所示。

  1. 建立一个类型并将其命名为List。在此类上右击并添加一个名为T的模板参数。添加诸如isEmpty():bool ,getSize():int之类的操作。
  2. 您也需要创建一个用到该模板参数的方法。添加一个名为get()的方法。在此方法中,使其返回类型为模板参数 T(如图 4 所示),然后输入参数名字 index,其类型为 int

您也可以使用模板参数 T 来定义一个属性类型,用同样的方式它也可以用作定义该种方式的回转类型。


图4.选择作为方法返回类型的模板参数
选择作为方法返回类型的模板参数
  1. 同样的,建立另一个类型并将其命名为 SortedList,然后添加一个模板参数 X。因为您需要 SortedList 扩展为List,并且使用 List 您需要建立一个类 List 的例子,建立一个占位符类。

该占位符类可以通过将模板参数 T 与模板参数 X 绑定来实例化。为了完成该项,创建一个名为 ListBase 的类型并添加 一个从 ListBaseListbinding 关系 ,并将参数 T 与 X 相绑定,如图表 5 所示。


图5.绑定模板参数
绑定模板参数
  1. 对 SortedList 添加一个诸如 sort(ascendingOrder:bool) 的方法,对 SortedList 建立对 ListBase 的生成关系,如图 6 所示。

使用绑定关系将通用类型实例化
diagram with List, ListBase, and SortedList
  1. 建立一个 UML 类型并将其命名为 ShelfBook
  2. 现在,建立一个书架分类书籍收集模型, 建立一个绑定类型 SortedBooksList,通过设置 Book 的 X 值,将其与 SortedList 联系起来。建立一个从 Shelf 到 SortedBooksList 的单向联系,并给其起一个以 sortedBooks 结尾的名字。这代表了属性声明 SortedList<Book>sortedBooks;,参见列表 1
  3. 建立一个绑定类型模板并将其命名为 ShelvesList 通过设定参数值 T 为 Shelf经其与类 List 联系起来。 这代表 List<Shelf>
  4. 最后,建立一个Library类型,使其与 ShelvesList 联系起来,将此联系起一个以 shelves结尾的名字。这代表了属性声明 List<Shelf>shelves; 在表 1 中的 Library 类中。

上一个例子包括了通用类型的申明及实例化。通过对 UML 操作中添加模板参数,相似的可以建立通用类型的模型





回页首


映射模型

在调试 C# 程序时可使用映射模型。当您想要控制您源代码的物理结构时,它是很实用的 ,使用映射模型可能与默认方式不同。 例如,默认方式下 UML 到 C# 在一篇文档中以同样的名字产生一个类型。但是如果您想在同一篇文档中存在两个或更多的类型,您就需要使用映射模式以显示源文件的等级及内容。

另外,当您使用局部类型时,应用映射模式基于您的需要,可以指导局部类型的每个定义成为一篇文档。基本上,映射模式仅仅是一种获取源代码物理组织结构信息的另一种 UML 模型,该模型包含一些包、资源,及从应用程序逻辑设计模型获得的 UML 模型的公告

映射模型的 UML 包代表一个文件系统的文件夹,而 UML 包中的 UML 资源代表了这些文件夹中的源文件。该资源应该给源文件以.cs结尾的扩展名,每个资源拥有一个或多个公告,这取决于包含在那个文件夹中类型的数量。

例如,在上面章节讨论过的图书馆系统中,假设您想做以下调试:

  • 名为 LibrarySystem.cs 的单个文件中的类 Library,Shelf 和 Book
  • 名为 Library 的文件夹中的 LibrarySystem.cs 文件
  • 所有的通用类型(List, SortedList)产生于名为 LibraryGenerics.cs 的文件中。
  • 该文件位于文件层 library/generics/collections 下

为了完成本项,建立以下映射模型:

  1. 在模型中建立一个名为 Library 的 UML 包。这代表了文件夹 library 位于 C# 根项目之下。
  2. 建立一个名为 LibrarySystem.cs 的标志,在包library之下。这代表了文件 LibrarySystem.cs 在文件夹 library 之下。
  3. 在应用程序的逻辑设计模型中,对创建先于 UML 类 Library、Shelf 和 Book 的标志,创建三个声明关系。
  4. 建立一个 UML 包并将其命名为 generics 在包 library 之下。 这意味着文件夹 library/generics 在 C# 项目之下。
  5. 建立一个 UML 包并将其命名为 collections 在包 generics 之下。 这代表了文件夹 library/generics/collections 在 C# 项目之下。
  6. 在包 collections 下建立一个标志并将其命名为 LibraryGenerics.cs
  7. 在逻辑设计模型中,在以上标志和类 List 和 SortedList 之间创建两个声明关系。

您可以在转变调试编辑器中指定模型为映射模型。在代码生成过程中它将用于 UML 到 C# 的转变,以决定源代码的目录结构,而且,当 C# 到 UML 转变运行时,该模型也将被优化。





回页首


您学到了什么

本篇文章讨论了高级 C# 建模的话题。它概括了 C# 指针和数组类型的概念。在阅读了本篇文章后,您应该学会建立分部及通用类型的模型,和使用映射模型来设计源代码的文件系统概览。



参考资料

学习

获得产品和技术

讨论


关于作者

Rajeshwari Rajendra

Rajeshwari Rajendra 是 IBM 印度软件实验室的一名软件工程师,工作于 Rational Systems Developer 团队。 她专长于 XML 查询技术,例如 XPath 和 XQuery,以及 UML 建模和转换(特别是 C# 和 C++)。 她拥有印度班加罗尔大学的硕士学位(MCA)。




对本文的评价










回页首


Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. 其他公司、产品或服务的名称可能是其他公司的商标或服务标志。

IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款