面向对象第11章 构件及部署部分的设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
11.1. 1概念与表示法
通常采用UML的构件图进行构件设计。构件图是描述构件、 构件的内部结构和构件之间关系的图。用它表达如何把系统元素 组织成构件,从而支持以构件为单位进行软件制品的实现和发布。 1.构件 设计时将类图中的类分配到需要创建的物理组件上去,以达到逻辑结构
设计向物理结构设计的过渡。组件就是类和接口的集合; 按照UML 2.0的定义,构件( component)是系统中的可替换的
第 14 页
4. 连接件
可以通过端口把构件连接起来。连接的规则为:如果一个构件 的端口上有一个供接口而另一个构件的端口上有一个需接口,且 两者是兼容的,那么这两个端口便是可连接的。连接端口意味着 请求端口要使用提供端口中的操作,以得到所需的服务。设立端 口和接口的优点在于: 两个构件彼此不需要了解对方的内部,只要它们的接口是相 互兼容的即可通过端口通信;如果需要使用新的构件,可以把这 些端口重新连接到其他提供相同接口的构件上。连接件( connector)就是通过端口实例或接口用于构件实例间通信的部件。 用连接件可以把两个平等的构件实例连接起来,也可以把复合 构件(也即由其他构件构成的构件)实例和作为它的内部成分的构件 实例连接起来。为此, UML定义了两种连接件:装配连接件和委 托连接件。
第 18 页
有了上述知识,下面解释图11-7的具体含义。该图展示 了一个具有内部部件和不同种类的连接件的构件。在端口“ 订单登记”的实例上的外部请求被委派给内部构件“接收订 单”的实例的端口实例,接下来这个构件实例通过它的端口 “订单处理请求”的实例对外请求。这个端口的实例用“球 一穴”的图标与构件“订单处理”的实例相连接。构件“订 单处理”的实例与构件“库存”的实例通信,以去库中查询 ,这被描述为一个直接的装配连接件。一旦在库存中找到了 所需要的商品,构件“订单处理”的实例就访问外部的构件 ,以确定信用情况,这通过到“信用处理”端口的实例的委 托连接件来发出请求。如果从外部得到了有关于信用的回应 ,构件"订单处理"的实例就与构件"库存"的实例上的端口" 运输商品"的实例通信。构件"库存"的实例通过端口"发货" 的实例向外部构件的实例请求进行发货。
在面向对象的系统设计阶段的后期,可考虑 如何对系统的构件进行描述、构造和组织,以及 构件如何在节点上进行分布。 UML支持对构件以及构件之间的关系建模, 也支持对构件执行于其上的节点以及节点之 间的 关系建模。本章讲述构件图和部署图,它们分别 用于对系统进行构件设计和部署设计。
第 2 页
11. 1 构件设计
第 20 页
11. 1. 2 构件的内部结构
不但可以用一个或多个供接口和需接口描述构件的外部 规约,而且还可以对实现构件的一组元素建模。本节主要讲 述构件是如何由一个或多个实现其行为的部件组成的。 通过依赖关系可把组成构件的制品与构件关联起来。图 11-8所示的是用依赖关系展示实现构件的内部元素。 还可以在构件的矩形图符上附加分栏来列出其内部组成 元素(如接口、部件和连接件),如图11-9所示。
图11-2 具有分栏结构的构件表示法示例
第 5 页
2 构件的接口
接口由一组操作组成,它指定了一个契约,这个契约必须由实 现和使用这个接口的构件所遵循。进一步地,可以用约束描述接口, 约束可为前置条件和后置条件,也可为对使用接口中的操作而规定 的次序。 构件的供接口是构件实现的接口,这意味着构件的供接口是用 于为其他构件提供服务的。实现接口的构件支持由该接口所拥有的 特征和约束。 构件的需接口是构件使用的接口,即构件向其他构件请求服务 时要遵循的接口。 一个构件依据供接口和需接口,详述了它提供给其他构件的服 务的形式规约,以及它向其他构件请求的服务的形式规约。
在图11-9中,标有« realization» 的分栏说明构件"订单" 有2个内部成分,标有«artifact» 的分栏说明构件"订单"的 物理实现体为Order.jar。 如果需要较为详细地描述构件的角色或实例级的内容, 可以为构件定义由部件实例和连接件组成的内部结构。在 UML中把展示这种内容的图称为组合结构图。图11-10所示 的是在构件图符的内部展示构成构件的元素。
第 21 页
图11-8用依赖关系描述构件的内部成分
<<component>> 订单 <<provided interfaces>> 订单登记 开帐单 <<required interfaces>> 发票 建立(…) 登记费(…) <<realization>> 订单头 排列项 <<artifacts>> Order.jar 图11-9用分栏结构表示构件的内部成分 第 22 页
第 12 页
构件内部的部件能用端口名标识收发消息的端 口,如图11-6所示。
图11-6 构件上的端口与其内部成分的连接
第 13 页
构件"订货"内部的箭线表示它对消息的分发处理,严格 地讲这样的箭线就是下一小节要讲述的连接件。 可用一个显式的对象实现一个端口,它也可能只是一个 虚拟的概念。对于前一种情况,端口的实例随着它们所属的 构件的实例一一起被创建和撤销。一个端口也可以具有多重 性,用于指定在构件实例中该端口的实例的可能数目。虽然 一个端口的多个实例都能接收同种的请求服务,但它们可能 有不同的状态和数据值。可赋予端口的每个实例一个不同的 优先级,具有较高优先级的端口实例优先被满足。
第 15 页
装配连接件是两个构件实例间的连接件,通过它一个构件实例使 用另一个构件实例提供的服务。具体来说,装配连接件用于把一个需 接口或端口实例与一个供接口或端口实例连接起来,在执行时,消息 起源于一个请求端口实例,沿着连接件传递,被交付到一个提供端口 实例。
有两种表示装配连接件的方法。 1) 如果要显式地把两个构件实例衔接在一起,在它们的端口实例之间 画一条线即可。由于不用呈现接口,这适合二者之间的连接更直接、 以后不会有什么变化的情况。 2) 如果两个构件实例相连是由于它们有兼容的接口,则可以使用一个 "球-穴"标记来表示 构件实例之间的连接关系。 图11-7中的构件"接收订单"和"订单处理"的实例间的连接件以及 构件"订单处理"和"库存"的实例间的连接件都是装配连接件。
第 10 页
图11-5 具有两个供接口和三个需接口的构件
第 11 页
构件"售票处"所对应的实际事物是为一些影剧院售票的 代理机构。构件"售票处"的两个端口"正常售票"和"优先售 票",一个为普通用户提供服务,另一个为特殊用户提供服 务。在它们上都附属有名为"售票"的供接口。端口"信用卡 处理"上有一个需接口"信用卡",其中含有要对外请求的处 理信用卡信息的操作。端口"节目收集"上既有供接口也有需 接口。使用接口"订票",构件"售票处"查询有关影剧院是否 需要售票,若需要则进行订购。使用接口"装载节目",剧院 将演出节目的内容及票的信息录入到售票系统的数据库,以 便出售。
一个构件可以通过一个特定端口同另一个构件通信,而且通信完 全是通过由端口支持的接口来描述的。供接口说明了通过端口来提供 服务,需接口说明了通过端口需要从其他构件获得服务。使用端口能 在更大的程度上增加构件的封装性和可替代性。
第 9 页
可以按端口把构件的接口分组,并独立使用。需接口可以 是构件的请求端口的类型,供接口可以是构件的提供端口的类 型。 把一个端口表示成一个跨在构件边上的小方块——它代表 了一个穿过构件的封闭边界的一个窗口。可以把供接口和需接 口附属到端口图符上。每个端口都有一个标识,它与构件名一 起唯一地标定一个特定构件上的端口。 图11-5展示了一个带有端口的构件“售票处” 。这个构件 具有“正常售票”、“优先售票”、“节目收集”和“信用卡 处理”四个端口,它们的类型分别由其上的接口所规定。。
第 6 页
一个给定的构件可以实现多个接口,也可以请求多个接 口。一个接口可以由多个不同的构件实现。 如果一个构件在一个环境中可以执行,且另一个构件遵 从该构件的供接口和需接口,则另一个构件也能在这样的环境 中执行。也即,只要其他的构件能够实现一个构件的供接口且 遵循它的需接口,就可以用这样的构件替换该构件。正是构件 拥有的供接口和需接口,形成了把构件衔接在一起的基础。 可以用两种方式来表示构件和接口之间的关系。第一种 方式是用简略的图符形式表示接口:把供接口表示成用线连到 构件的一个圆,把需接口表示成用线连到构件的一个半圆。在 这两种情况下,都把接口的名字写在图符的旁边,如图11-3 所示。第二种方式是用扩展方式表示接口,这种方式可以展现 出接口的操作。用实现关系把实现接口的构件连接到接口上, 用依赖关系把使用接口的构件连接到接口上,如图11-4所示。
第 7 页
图11-3 具有两个供接口和三个需接口的构件
图11-4 构件与用扩展方式表示的接口
第 8 页
3. 构件的端口
接口对声明一个构件的总的行为来说是有用的,构件的实现仅需 保证要实现供接口中全部操作且遵循所设计的需接口。使用端口(port) 是为了能进一步控制这种实现。 作为构件的一个部件,端口描述了在构件与它的环境之Hale Waihona Puke Baidu以及在 构件与它的内部部件之间的一个显式的交互点。也即,端口是一个封 装构件的显式的对外窗口,所有进出构件的交互都要通过端口。这明 确地指出,构件可以拥有内部结构和形式化其交互点的一组端口。构 件的外部可见行为恰好是它各端口上的行为总和。
第 16 页
图11-7 连接件
第 17 页
委托连接件把外部对构件端口实例的请求分发到构件内部的部件 实例进行处理,或者通过构件端口实例把构件内部部件实例向构件 外部的请求分发出去。注意,必须在两个提供端口实例间或两个请 求端口实例间定义委托连接件。
按照上述定义,委托有这样的含义:具体的消息流将发生在所连 接的端口实例之间,可能要跨越多个层次,最终到达要对消息进行 处理的最终部件实例。这样,可使用委托连接件按照层次分解的方 式对构件的行为建模。 对于源自外部端口实例的消息被委派给内部端口实例,把委托连 接件表示为从源端口实例到处理请求的目标部件实例上端口实例的 箭线。对于源自内部端口实例的消息被委派给外部端口实例,把委 托连接件表示为从发出请求的部件实例上的端口实例到处理请求的 目标端口实例的箭线。图11-7构件"按商品目录销售"有三个委托连接 件负责其内外交互。
模块化部分,它封装了自己的内容;构件利用供接口和需接口定义 自身的行为;它起类型的作用。
构件是软件系统逻辑架构中定义的概念和功能在物理架构中 的实现,对应于组成软件系统的目标文件、可执行程序文件、动 态库文件、数据库文件和HTML文件等开发环境中的实现性文件。
第 3 页
按照这个定义以及UML 2.0对构件的其他规定,构件具有如下的含义: 1)一个构件是系统的一个模块,而且是一个自包含的单元,它封装了其 内部成分。 2)构件通过它的供接口和需接口展现行为。 3)构件是可替换的单元,在设计时和运行时依据接口的兼容性,若一个 构件能提供另一个构件所具有的功能,则前者可替换后者。 4)构件起类型的作用,这意味着构件是可实例化的。 在UML 2. 0中还规定,一个构件可由其他构件构成。按照这种规定, 构件也具有如下的含义: 5)构件是可组装的。 把构件表示为右上角放了一个图标的矩形,该图标由一个矩形加上 在其左侧边放置的两个突出的小矩形组成,如图11-1所示。
第 4 页
也可以把构件表示为标有关键字« component» 的带有分栏的矩形,如图 11-2所示。这意味着可以把接口和操作等列在构件图符的分栏中。
<<component>> 订单 <<provided interfaces>> 订单登记 开帐单 <<required interfaces>> 发票 建立(…) 登记费(…)
第 19 页
通过委托连接件,一个端口实例可以把请求委托给其内 部件实例上的一组端口实例。在这样的情况下,这些内部端 口实例必须提供被委托的功能。图11-6中有源于一个端口实 例的两个委托连接件,只是两个部件的实例上的端口实例没 有显示出来。
从上面的例子中可以看出,不使用连接件也不展示构件 的内部结构时,是在构件的级别上进行建模,而使用连接件 或展示构件的内部结构时,是在构件的实例级别上建模。
通常采用UML的构件图进行构件设计。构件图是描述构件、 构件的内部结构和构件之间关系的图。用它表达如何把系统元素 组织成构件,从而支持以构件为单位进行软件制品的实现和发布。 1.构件 设计时将类图中的类分配到需要创建的物理组件上去,以达到逻辑结构
设计向物理结构设计的过渡。组件就是类和接口的集合; 按照UML 2.0的定义,构件( component)是系统中的可替换的
第 14 页
4. 连接件
可以通过端口把构件连接起来。连接的规则为:如果一个构件 的端口上有一个供接口而另一个构件的端口上有一个需接口,且 两者是兼容的,那么这两个端口便是可连接的。连接端口意味着 请求端口要使用提供端口中的操作,以得到所需的服务。设立端 口和接口的优点在于: 两个构件彼此不需要了解对方的内部,只要它们的接口是相 互兼容的即可通过端口通信;如果需要使用新的构件,可以把这 些端口重新连接到其他提供相同接口的构件上。连接件( connector)就是通过端口实例或接口用于构件实例间通信的部件。 用连接件可以把两个平等的构件实例连接起来,也可以把复合 构件(也即由其他构件构成的构件)实例和作为它的内部成分的构件 实例连接起来。为此, UML定义了两种连接件:装配连接件和委 托连接件。
第 18 页
有了上述知识,下面解释图11-7的具体含义。该图展示 了一个具有内部部件和不同种类的连接件的构件。在端口“ 订单登记”的实例上的外部请求被委派给内部构件“接收订 单”的实例的端口实例,接下来这个构件实例通过它的端口 “订单处理请求”的实例对外请求。这个端口的实例用“球 一穴”的图标与构件“订单处理”的实例相连接。构件“订 单处理”的实例与构件“库存”的实例通信,以去库中查询 ,这被描述为一个直接的装配连接件。一旦在库存中找到了 所需要的商品,构件“订单处理”的实例就访问外部的构件 ,以确定信用情况,这通过到“信用处理”端口的实例的委 托连接件来发出请求。如果从外部得到了有关于信用的回应 ,构件"订单处理"的实例就与构件"库存"的实例上的端口" 运输商品"的实例通信。构件"库存"的实例通过端口"发货" 的实例向外部构件的实例请求进行发货。
在面向对象的系统设计阶段的后期,可考虑 如何对系统的构件进行描述、构造和组织,以及 构件如何在节点上进行分布。 UML支持对构件以及构件之间的关系建模, 也支持对构件执行于其上的节点以及节点之 间的 关系建模。本章讲述构件图和部署图,它们分别 用于对系统进行构件设计和部署设计。
第 2 页
11. 1 构件设计
第 20 页
11. 1. 2 构件的内部结构
不但可以用一个或多个供接口和需接口描述构件的外部 规约,而且还可以对实现构件的一组元素建模。本节主要讲 述构件是如何由一个或多个实现其行为的部件组成的。 通过依赖关系可把组成构件的制品与构件关联起来。图 11-8所示的是用依赖关系展示实现构件的内部元素。 还可以在构件的矩形图符上附加分栏来列出其内部组成 元素(如接口、部件和连接件),如图11-9所示。
图11-2 具有分栏结构的构件表示法示例
第 5 页
2 构件的接口
接口由一组操作组成,它指定了一个契约,这个契约必须由实 现和使用这个接口的构件所遵循。进一步地,可以用约束描述接口, 约束可为前置条件和后置条件,也可为对使用接口中的操作而规定 的次序。 构件的供接口是构件实现的接口,这意味着构件的供接口是用 于为其他构件提供服务的。实现接口的构件支持由该接口所拥有的 特征和约束。 构件的需接口是构件使用的接口,即构件向其他构件请求服务 时要遵循的接口。 一个构件依据供接口和需接口,详述了它提供给其他构件的服 务的形式规约,以及它向其他构件请求的服务的形式规约。
在图11-9中,标有« realization» 的分栏说明构件"订单" 有2个内部成分,标有«artifact» 的分栏说明构件"订单"的 物理实现体为Order.jar。 如果需要较为详细地描述构件的角色或实例级的内容, 可以为构件定义由部件实例和连接件组成的内部结构。在 UML中把展示这种内容的图称为组合结构图。图11-10所示 的是在构件图符的内部展示构成构件的元素。
第 21 页
图11-8用依赖关系描述构件的内部成分
<<component>> 订单 <<provided interfaces>> 订单登记 开帐单 <<required interfaces>> 发票 建立(…) 登记费(…) <<realization>> 订单头 排列项 <<artifacts>> Order.jar 图11-9用分栏结构表示构件的内部成分 第 22 页
第 12 页
构件内部的部件能用端口名标识收发消息的端 口,如图11-6所示。
图11-6 构件上的端口与其内部成分的连接
第 13 页
构件"订货"内部的箭线表示它对消息的分发处理,严格 地讲这样的箭线就是下一小节要讲述的连接件。 可用一个显式的对象实现一个端口,它也可能只是一个 虚拟的概念。对于前一种情况,端口的实例随着它们所属的 构件的实例一一起被创建和撤销。一个端口也可以具有多重 性,用于指定在构件实例中该端口的实例的可能数目。虽然 一个端口的多个实例都能接收同种的请求服务,但它们可能 有不同的状态和数据值。可赋予端口的每个实例一个不同的 优先级,具有较高优先级的端口实例优先被满足。
第 15 页
装配连接件是两个构件实例间的连接件,通过它一个构件实例使 用另一个构件实例提供的服务。具体来说,装配连接件用于把一个需 接口或端口实例与一个供接口或端口实例连接起来,在执行时,消息 起源于一个请求端口实例,沿着连接件传递,被交付到一个提供端口 实例。
有两种表示装配连接件的方法。 1) 如果要显式地把两个构件实例衔接在一起,在它们的端口实例之间 画一条线即可。由于不用呈现接口,这适合二者之间的连接更直接、 以后不会有什么变化的情况。 2) 如果两个构件实例相连是由于它们有兼容的接口,则可以使用一个 "球-穴"标记来表示 构件实例之间的连接关系。 图11-7中的构件"接收订单"和"订单处理"的实例间的连接件以及 构件"订单处理"和"库存"的实例间的连接件都是装配连接件。
第 10 页
图11-5 具有两个供接口和三个需接口的构件
第 11 页
构件"售票处"所对应的实际事物是为一些影剧院售票的 代理机构。构件"售票处"的两个端口"正常售票"和"优先售 票",一个为普通用户提供服务,另一个为特殊用户提供服 务。在它们上都附属有名为"售票"的供接口。端口"信用卡 处理"上有一个需接口"信用卡",其中含有要对外请求的处 理信用卡信息的操作。端口"节目收集"上既有供接口也有需 接口。使用接口"订票",构件"售票处"查询有关影剧院是否 需要售票,若需要则进行订购。使用接口"装载节目",剧院 将演出节目的内容及票的信息录入到售票系统的数据库,以 便出售。
一个构件可以通过一个特定端口同另一个构件通信,而且通信完 全是通过由端口支持的接口来描述的。供接口说明了通过端口来提供 服务,需接口说明了通过端口需要从其他构件获得服务。使用端口能 在更大的程度上增加构件的封装性和可替代性。
第 9 页
可以按端口把构件的接口分组,并独立使用。需接口可以 是构件的请求端口的类型,供接口可以是构件的提供端口的类 型。 把一个端口表示成一个跨在构件边上的小方块——它代表 了一个穿过构件的封闭边界的一个窗口。可以把供接口和需接 口附属到端口图符上。每个端口都有一个标识,它与构件名一 起唯一地标定一个特定构件上的端口。 图11-5展示了一个带有端口的构件“售票处” 。这个构件 具有“正常售票”、“优先售票”、“节目收集”和“信用卡 处理”四个端口,它们的类型分别由其上的接口所规定。。
第 6 页
一个给定的构件可以实现多个接口,也可以请求多个接 口。一个接口可以由多个不同的构件实现。 如果一个构件在一个环境中可以执行,且另一个构件遵 从该构件的供接口和需接口,则另一个构件也能在这样的环境 中执行。也即,只要其他的构件能够实现一个构件的供接口且 遵循它的需接口,就可以用这样的构件替换该构件。正是构件 拥有的供接口和需接口,形成了把构件衔接在一起的基础。 可以用两种方式来表示构件和接口之间的关系。第一种 方式是用简略的图符形式表示接口:把供接口表示成用线连到 构件的一个圆,把需接口表示成用线连到构件的一个半圆。在 这两种情况下,都把接口的名字写在图符的旁边,如图11-3 所示。第二种方式是用扩展方式表示接口,这种方式可以展现 出接口的操作。用实现关系把实现接口的构件连接到接口上, 用依赖关系把使用接口的构件连接到接口上,如图11-4所示。
第 7 页
图11-3 具有两个供接口和三个需接口的构件
图11-4 构件与用扩展方式表示的接口
第 8 页
3. 构件的端口
接口对声明一个构件的总的行为来说是有用的,构件的实现仅需 保证要实现供接口中全部操作且遵循所设计的需接口。使用端口(port) 是为了能进一步控制这种实现。 作为构件的一个部件,端口描述了在构件与它的环境之Hale Waihona Puke Baidu以及在 构件与它的内部部件之间的一个显式的交互点。也即,端口是一个封 装构件的显式的对外窗口,所有进出构件的交互都要通过端口。这明 确地指出,构件可以拥有内部结构和形式化其交互点的一组端口。构 件的外部可见行为恰好是它各端口上的行为总和。
第 16 页
图11-7 连接件
第 17 页
委托连接件把外部对构件端口实例的请求分发到构件内部的部件 实例进行处理,或者通过构件端口实例把构件内部部件实例向构件 外部的请求分发出去。注意,必须在两个提供端口实例间或两个请 求端口实例间定义委托连接件。
按照上述定义,委托有这样的含义:具体的消息流将发生在所连 接的端口实例之间,可能要跨越多个层次,最终到达要对消息进行 处理的最终部件实例。这样,可使用委托连接件按照层次分解的方 式对构件的行为建模。 对于源自外部端口实例的消息被委派给内部端口实例,把委托连 接件表示为从源端口实例到处理请求的目标部件实例上端口实例的 箭线。对于源自内部端口实例的消息被委派给外部端口实例,把委 托连接件表示为从发出请求的部件实例上的端口实例到处理请求的 目标端口实例的箭线。图11-7构件"按商品目录销售"有三个委托连接 件负责其内外交互。
模块化部分,它封装了自己的内容;构件利用供接口和需接口定义 自身的行为;它起类型的作用。
构件是软件系统逻辑架构中定义的概念和功能在物理架构中 的实现,对应于组成软件系统的目标文件、可执行程序文件、动 态库文件、数据库文件和HTML文件等开发环境中的实现性文件。
第 3 页
按照这个定义以及UML 2.0对构件的其他规定,构件具有如下的含义: 1)一个构件是系统的一个模块,而且是一个自包含的单元,它封装了其 内部成分。 2)构件通过它的供接口和需接口展现行为。 3)构件是可替换的单元,在设计时和运行时依据接口的兼容性,若一个 构件能提供另一个构件所具有的功能,则前者可替换后者。 4)构件起类型的作用,这意味着构件是可实例化的。 在UML 2. 0中还规定,一个构件可由其他构件构成。按照这种规定, 构件也具有如下的含义: 5)构件是可组装的。 把构件表示为右上角放了一个图标的矩形,该图标由一个矩形加上 在其左侧边放置的两个突出的小矩形组成,如图11-1所示。
第 4 页
也可以把构件表示为标有关键字« component» 的带有分栏的矩形,如图 11-2所示。这意味着可以把接口和操作等列在构件图符的分栏中。
<<component>> 订单 <<provided interfaces>> 订单登记 开帐单 <<required interfaces>> 发票 建立(…) 登记费(…)
第 19 页
通过委托连接件,一个端口实例可以把请求委托给其内 部件实例上的一组端口实例。在这样的情况下,这些内部端 口实例必须提供被委托的功能。图11-6中有源于一个端口实 例的两个委托连接件,只是两个部件的实例上的端口实例没 有显示出来。
从上面的例子中可以看出,不使用连接件也不展示构件 的内部结构时,是在构件的级别上进行建模,而使用连接件 或展示构件的内部结构时,是在构件的实例级别上建模。