内容


使用 Rational Modeling Extension for Microsoft .NET 对 C# 应用程序进行建模,第 3 部分

对 C# 数组、指针、局部及通用类型进行建模

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用 Rational Modeling Extension for Microsoft .NET 对 C# 应用程序进行建模,第 3 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用 Rational Modeling Extension for Microsoft .NET 对 C# 应用程序进行建模,第 3 部分

敬请期待该系列的后续内容。

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# 数组
使用 <<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# 指针模型
使用 <<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# 局部类型的模型
使用 <<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# 指针和数组类型的概念。在阅读了本篇文章后,您应该学会建立分部及通用类型的模型,和使用映射模型来设计源代码的文件系统概览。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=345481
ArticleTitle=使用 Rational Modeling Extension for Microsoft .NET 对 C# 应用程序进行建模,第 3 部分: 对 C# 数组、指针、局部及通用类型进行建模
publish-date=10132008