目录
1、名称
2、操作
3、关系
4、理解接口
5、常用建模技术
5.1、对系统中的接缝建模
5.2、对静态类型和动态类型建模
5.2.1、对静态类型建模
5.2.2、对动态类型建模
使接口易于理解和易于访问
接口在关于一个抽象做什么的描述与关于这个抽象如何做的实现之间定义了一条界线。接口是一组操作的集合,其中的每个操作用于描述类或构件的一个服务。
用接口对系统中的接缝进行可视化、详述、构造和文档化。类型和角色提供了在特定的语境下为抽象与接口之间的静态和动态一致性进行建模的机制。
结构良好的接口能够清楚地把抽象的外视图与内视图分开,这样就使理解和访问抽象成为可能,而不必探究它的实现细节。
把房屋设计得每次重新粉刷墙壁都要毁坏建筑物,这是没有道理的。类似地,人们也不愿意生活在这样的地方:每当要换一个灯泡时,都要为这幢房子重接电线。大厦的主人更不高兴这样的情况发生:每当一个新的房客入住时,都要移动门或更换所有的电器和电话插座。
在UML中,用接口对系统中的接缝建模。接口是一组操作的集合,其中的每个操作用于描述类或构件的一个服务。通过声明一个接口,可以陈述对一个抽象所要得到的与其实现无关的行为。客户能够对照接口进行建造,你可以自己建造或购买接口的实现,只要接口的实现能满足接口所指定的职责和合约即可。
接口(interface)是一组操作的集合,其中的每个操作用于描述类或构件的一个服务。类型(type)是类的一个衍型,用于描述一组对象的域以及作用于对象的操作(不是方法)。角色(role)是一个参与特定语境的实体的行为。
在图形上,
把接口画成一个衍型化的类,以显露它的操作和其他性质。为了表示类和其接口之间的联系,提供了一种特殊的表示法。
把供接口(provided interface)(表示类提供的服务)表示为与类框连接在一起的小圆圈。
把需接口(required interface)(表示类需要的别的类的服务)表示为与类框连接在一起的半个小圆圈。
1、名称
每个接口都必须有一个有别于其他接口的名称。名称(name)是一个文字串。单独的一个名称称作简单名(simple name),路径名(path name)是以接口所在的包的名称为前缀的接口名。绘制接口时可以仅显示接口的名称,如图所示。
在一个包中的各接口的名称必须是唯一的
2、操作
接口是一组已命名的操作,其中的每个操作用于描述类或构件的一个服务。接口不同于类或类型,它不描述任何实现(因此不包含任何实现操作的方法)。像类一样,接口可以有一些操作。这些操作可以用可见性、并发性、衍型、标记值和约束来修饰。
在声明一个接口时,把接口画成衍型化的类,并在合适的分栏列出它的操作。可以仅显示操作的名称,也可以显示出操作的全部特征标记和其他特性,如图所示。
3、关系
像类一样,接口也可以参与泛化、关联和依赖关系。此外,接口也可以参与实现关系。实现是两个类目之间的语义关系,其中一个类目描述了另一个类目保证实现的合约。
用两种方式来表现一个元素实现一个接口。
第一种方式可以用简化形式,即把接口和它的实现关系画成一条位于类框和小圆(用于供接口)或者半圆(用于需接口)之间的连线。当要简单地显露系统的接缝时,这种形式是有用的,这通常是首选的形式。然而,这种方式的局限性是不能直接地对接口提供的操作或信号进行可视化。
第二种方式是使用展开的形式,即把接口表示成衍型化的类,这种方式允许对接口的操作和其他的特性进行可视化,然后画一个从类目或构件到接口框的实现关系(用于供接口)或依赖(用于需接口)。在UML中,把实现关系画成一条带有空心三角箭头并指向接口的有向虚线。这种表示法是泛化和依赖的混合。
4、理解接口
在处理一个接口时,首先看到的是一组操作,该组操作描述了类或构件的服务。看得更深些,会看到这些操作的全部特征标记,连同它们的各项具体特性,如可见性、范围和并发语义等。
首先,可以为各个操作附上前置和后置条件,以及为整个类或构件附上不变式。通过这样做,需要使用接口的客户就能理解接口做什么以及如何使用它,而不必深究其实现。若要求是严格的,可使用 UML 的OCL 形式化地描述其语义。
其次,给接口附上一个状态机。用状态机详述接口操作的合法的局部命令。最后,可以为接口附上协作。通过一系列的交互图,可以用协作详述接口的预期行为。
5、常用建模技术
5.1、对系统中的接缝建模
识别系统中的接缝涉及到识别在系统体系结构中的明确的分界线。在这些分界线的每一边,都会发现一些可独立变化的构件,只要在分界线两边的构件遵循由接口描述的合约,在一边变化的构件就不会影响另一边的构件。
下图展示了取自一个财务系统的构件Ledger周围的接缝。这个构件提供(实现)了3个接口:IUnknown、ILedger和IReports。在图中以展开形式显示了IUnknown;另外两个接口以简单形式(棒棒糖形式)显示。这3个接口由Ledger实现,并向要使用它的其他构件引出。
该图还表示,Ledger需要(使用)两个接口,即IStreaming和ITransaction,后者以展开形式显示。Ledger构件为其适当的操作而需要这两个接口。因此,在一个运行系统中,必须提供实现这两个接口的构件。通过识别诸如 ITransaction 这样的接口,已经有效地减弱了接口每一边的构件耦合,允许使用任何符合接口要求的构件。
像 ITransaction 这样的接口并不只是一堆操作。这种特殊的接口有一些关于其操作应被调用的次序的假设。可以向该接口附加用况,并枚举它的常用方式,虽然这里并未显示出来。
5.2、对静态类型和动态类型建模
5.2.1、对静态类型建模
对象的静态性质建模可以在类图中进行可视化。然而,当对业务对象这样的事物建模时,这些对象在整个工作流中会自然地变化它们的角色,显式地对对象类型的动态性质建模有时是有用的。在这种情况下,对象在它的生存期内能获得或丢弃类型。也可以用状态机为对象的生存期建模。
5.2.2、对动态类型建模
通过把每一个类型表示为类(若该抽象需要结构和行为)或接口(若该抽象仅需要行为)来详述对象可能的各种不同类型。
对象类在任何时间点上可能扮演的角色建模。可以用«dynamic»衍型(这不是一个预定义的UML衍型,但是可以增加这种衍型)来标记它们。
在交互图中,适当地表示每个被动态类型化的类的实例。在对象名下面的括号中指明实例的类型,就像一个声明一样
描述了类Person的实例可以是3种类型(Candidate、Employee或Retiree)中的任何一种