指南:封装体
本指南描述封装体的实时软件概念。
关系
主要描述

主题

端口

因为端口在封装体的边界上,应该从封装体外部和内部都可以看见它们。从外部观察时,所有端口呈现相同的不能通过的对象接口并且无法加以区分(除非根据它们的标识以及它们在其协议中所扮演的角色)。但是,从封装体内部观察时,可以发现端口可以是两种类型之一: 中继端口终止端口。它们在内部连接上是不同的 - 中继端口连接到子封装体,而终止端口连接到封装体的状态机。一般说来,中继端口负责有选择地导出内部子封装体的“接口”,而端点端口则是封装体状态机的边界对象。中继和终止端口都可能出现在封装体的边界上,并且如上所述,无法从外部加以区分。

中继端口

中继端口是简单地让所有信号通过的一种端口。它们在封装体的封装外壳上提供了一个“开口”,子封装体可以通过它来与外界通信,同时又不会将自身向外界暴露(反之亦然)。中继端口通过接口连接到子封装体上,并且通常也从外部连接到其他“同级”封装体上。它们接收来自任一方的信号,并简单地将该信号中继至另一方(保持信号流的方向)。除非没有连接器连接到另一方,否则完成此操作不会延迟或丢失信息。在没有连接器的情况中,将丢失信号。

中继端口实现从封装体到子封装体的直接(零开销)信号委托,不需要封装体的状态机的干涉。中继端口只能出现在封装体的边界上,因此总有公用可视性。

端点端口

为了发挥作用,必须在与状态机通信的终止端口中最终终止连接器链。 终止端口是封装体的状态机的边界对象(虽然如将在下文中看到的,某些终止端口也作为封装体的边界对象)。终止端口是封装体发送的所有信号的最终源和接收器。这些信号由封装体的状态机生成。为发送信号,状态机调用其某个终止端口上的发送或呼叫操作。然后通过相连接的连接器中继该信号,可能通过一个或多个中继端口和链接的连接器,直到该信号最终遇到另一个终止端口(通常在不同的封装体中)。因为基于信号的通信可以是异步的,终止端口有一个队列,用来保存已接收但状态机尚未处理的消息(即,作为一个邮箱)。信号的接收和接收状态机的分派由状态机按照标准 UML 语义执行。

与中继端口类似,终止端口可能在封装体的边界上以公用可视性出现。这些端口称为公用终止端口。此类端口是状态机和包含封装体的边界对象。但是,终止端口也可能完全出现在封装体内部,作为其内部实施结构的一部分。状态机使用这些端口与其子封装体或外部 实施支持层通信。因为具有保护的可视性,这些内部端点端口称为保护的端点端口

注意端口类型完全由其内部连接和封装体外的可视性决定;各种术语(中继端口、公用终止端口和专用终止端口)仅仅是易记的术语。没有内部连接的公用端口将成为中继端口或终止端口,这取决于它以后连接的方式,或它可能保持不连接并作为进入信号的接收器。

端口可视性

从外部来看,端口就是端口;不可能甚至不希望确定该端口是中继端口还是终止端口。但是,当显示封装体的分解图时,可以看见封装体的里面,就可以用图形方式表示终止端口和中继端口的区别,如下所示。

附带文本中描述的图。

端口表示法 - 通信图(内部视图)

基于端口的触发器

实际上,经常发生以下情况:相同封装体的两个或多个端口使用相同协议,但语义上不同。另外,相同信号可能出现在封装体的不同端口所支持的多个协议角色中。在这两种情况中,可能有必要区分接收当前信号的特定终止端口。这使得应用程序能够根据该信号源以及状态以不同方式处理相同信号。这种类型的触发器称为 基于端口的触发器。在 UML 中通过使用检查特定源端口的警戒条件对基于端口的触发器建模。

状态机

使用标准 UML 状态机完成封装体的状态机部分的规范以及有效协议序列的规范。

时间服务

如所期望的一样,在大多数实时系统中,时间是要考虑的首要问题。通常,需要对两种基于时间的情形建模:在特定时间触发任务的能力,以及从给定时间点经过一定时间间隔后触发任务的能力。

大多数实时系统需要显式且直接可访问(可控制)的计时工具 - 时间服务。可以通过标准端口(服务访问点)访问该服务,该服务将时间转换成事件,然后就可以按照与处理其他基于信号的事件相同的方法处理它。例如,当使用这种服务时,状态机可以请求:当到达一天中的某个特定时间或经过某个特定的时间间隔时,用“超时”事件向它发出通知。

封装体分类法

封装体作为一个概念,可以许多不同方式加以使用。为反映此情况,可以描述封装体的层次结构和分类法以涵盖封装体的常见用途。

角色模型实现 分类角色模型 分类角色实现 角色实现 封装体 角色模型 角色类型 附带文本中描述的图。

显示泛化关系层次结构的封装体分类法

基本封装体分类法为:

  • 封装体

    基本封装体(缺少端口、内部结构或行为)不是很有意义 - 不能完成很多工作。可以使用这样的封装体来定义抽象封装体,从该抽象封装体派生其他封装体。由于没有定义端口、结构或行为,这种封装体类型只用于定义将在随后加以改进的“占位符”。

  • 角色类型

    “角色类型”封装体包含一个封装体定义,它定义了一个拥有一个或多个端口的抽象封装体,但没有定义结构和行为。如果需要同时定义一组封装体的“接口”(端口),就可以使用这类封装体,而这些接口的特定实现则由“角色类型”封装体的子类型来定义。

  • 角色模型

    “角色模型”封装体包含一个封装体定义,其内部结构(由规范协作来定义)包括嵌套封装体,还可能包括互连封装体,也可能包括一个或多个端口。这类封装体用于定义系统结构的“模板”,模板的“详细信息”委托给所包含的封装体。如果角色模型封装体有端口,则这些端口定义了封装体的“接口”。

    未指定“角色模型”的行为(未定义状态机);必须由该封装体的子类型定义此行为。

  • 角色实现

    “角色实现”封装体定义了封装体的行为(通过状态机),但没有定义内部结构和接口。它实际上为所有派生封装体提供了行为的抽象定义,然后这些派生封装体必须定义它们自己的内部结构和接口。可以将行为定义看成“设计声明”,所有从“角色实现”封装体派生的封装体必须满足该行为定义。

这些基本类型有三种很有用的混合使用方式,表示基本定义的混合使用:

  • 分类角色实现

    此类型的封装体定义了接口和一组封装体的行为,但没有限制派生封装体的内部结构。需要“角色实现”封装体进一步定义接口。

  • 分类角色模型

    此类型的封装体定义了接口和一组封装体的结构,但没有限制这些封装体的行为。这么做的好处是定义了接口和结构的模板,随后可以由派生封装体按需要作专门指定。

  • 角色模型实现

    此类型的封装体定义了封装体的内部结构及其抽象行为,但没有定义接口。此类型的封装体用在有大量封装体共享大量的内部结构和行为、但有不同接口的情况中。

剩下的封装体类型“分类角色模型实现”定义了结构和接口,并以抽象方式(用于接口)和特定方式(用于内部结构)定义行为,该类型很复杂且可能难以理解,更别说是正确实施了。提到它是因为存在需要将封装体上的单元测试定义为该封装体自身的一部分、因此有两个不同状态机的情况。在大多数情况中,最好避免此构造。

UML 2.0 表示

注意封装体的当前 RUP 表示基于 UML 1.5 表示法。该表示法的大部分内容可以在 UML 2.0 中使用概念:结构化类表示。

关于更多信息,请参阅UML 1.x 和 UML 2.0 之间的区别