Ran Wei / SysML v2 系列 / 模块 8
EN
SysML v2 — Ran Wei

模块 8:变体与配置

如何定义变体点、声明可选变体并配置产品线 — 让一个模型就能刻画整个系统配置族。

KerML → SysML:可变性概念

SysML v2 的可变性建立在 KerML 的使用变体(usage variation)变体成员关系(variant membership)机制之上。variation 使用声明一个可变点 — 该特征必须恰好绑定到其允许的备选项之一。变体点内的每个 variant 都是一个独立的成员选项。在 KerML 层面,这些都通过使用上的特征成员关系与子集关系来建模。

SysML v2 概念(L2)底层 KerML 构造(L1)SysML 增加了什么
variation(作用于使用)isVariation = true 的 Usage把某个特征标记为变体点;在任何完整配置中都必须解析为恰好一个变体
variantVariantMembership(一种 OwningMembership在变体点内声明一个具名备选项;每个变体都是该变体使用的子集
variation part defisVariation = truePartDefinition其使用天然即为变体点的定义 — 每次使用都必须被解析
variant(位于变体定义内)拥有某个使用的 VariantMembership在变体定义中充当一个选项的使用
配置绑定把变体解析到某个具体变体的 BindingConnector固定该选择;产出一个完整解析的产品实例
filter 表达式FilterExpression(作用于元数据的布尔表达式)依据元数据条件从包或命名空间中挑选元素
产品线包混合了变体与非变体内容的 Package把共享平台元素与产品族的变体点组织在一起
表 0 — 模块 8 的 SysML v2(L2)可变性概念到 KerML(L1)起源的映射
说明

在 KerML 中,isVariation 是任意 Usage 上的布尔属性。当它为 true 时,该使用即成为变体点,其带 VariantMembership 的自有成员就是允许的选项。SysML v2 用 variationvariant 关键字为这套机制提供了语法糖。

1

变体点

KerML 起源:variationisVariation = true 的 Usage

变体点是模型中代表一次选择的特征 — 不同配置正是在这里产生差异。在 SysML v2 中,给使用加上 variation 前缀即可声明变体点。变体使用本身并不是具体元素,而是一个占位符:在任何完整配置中,它都必须被解析为某一个变体。

类比

可以想象一份餐厅菜单。菜单上的「主菜」这一栏就是变体点 — 每位客人必须且只能选一项。具体的菜品(牛排、鱼、意面)则是变体。菜单定义结构,而每位客人点的那一单就是一个配置。

零件使用上的变体

最常见的变体形式作用在零件定义内的零件使用上。variation 关键字声明该特征是一个可变点,variant 成员则声明允许的备选项:

1part def Vehicle {
2 part engine : Engine;
3
4 // Variation point: transmission type
5 variation part transmission : Transmission {
6 variant part manual : ManualTransmission;
7 variant part automatic : AutomaticTransmission;
8 variant part cvt : CVTTransmission;
9 }
10}

在这个模型中,每个 Vehicle 实例都必须恰好有一套变速器 — 手动、自动或 CVT 三者取一。变体点不是可选项,它强制要求作出选择。

属性使用上的变体

变体点并不限于零件。你可以把它用在属性、端口或任何其他种类的使用上:

1part def Display {
2 // Variation point: screen resolution
3 variation attribute resolution : ScreenResolution {
4 variant attribute hd : HD; // 1280x720
5 variant attribute fhd : FHD; // 1920x1080
6 variant attribute uhd : UHD; // 3840x2160
7 }
8}
常见误区

变体点必须至少包含一个 variant 成员。声明一个没有任何变体的 variation 使用属于语义错误 — 因为根本无从选择。工具应把它标记为不完整。

2

变体定义

KerML 起源:variantVariantMembership(一种 OwningMembership

变体是变体点内的一个具体备选项。每个变体都是完整规定的元素 — 它带有自己的特征、约束和子结构。当某个配置选中一个变体时,在解析后的模型中,该变体的完整定义就取代了原来的变体点。

内联变体定义

变体可以直接内联定义在变体点里,并带上各自特有的特征:

1part def Powertrain {
2 variation part motorType : Motor {
3 variant part ice : ICEMotor {
4 attribute displacement : ISQ::VolumeValue;
5 attribute cylinders : ScalarValues::Integer;
6 }
7 variant part electric : ElectricMotor {
8 attribute peakPower : ISQ::PowerValue;
9 attribute batteryCapacity : ISQ::EnergyValue;
10 }
11 variant part hybrid : HybridMotor {
12 attribute displacement : ISQ::VolumeValue;
13 attribute peakPower : ISQ::PowerValue;
14 }
15 }
16}

引用外部的变体定义

变体也可以引用单独定义的零件定义。当同一个变体出现在模型中多个变体点里时,这种写法很有用:

1part def ManualTransmission :> Transmission {
2 attribute gearCount : ScalarValues::Integer;
3}
4
5part def AutomaticTransmission :> Transmission {
6 attribute modes : DriveMode[1..*];
7}
8
9part def Vehicle {
10 // Variants reference externally defined part defs
11 variation part transmission : Transmission {
12 variant part manual : ManualTransmission;
13 variant part automatic : AutomaticTransmission;
14 }
15}

变体定义(定义级)

你也可以用 variation part def 把整个定义标记为变体。这意味着该定义本身是抽象的 — 它不能被直接实例化,而必须解析为它的某个变体成员:

1variation part def DriveMode {
2 variant eco : EcoMode;
3 variant sport : SportMode;
4 variant normal: NormalMode;
5}
说明

要区分作用在使用上的 variation 与作用在定义上的 variation。变体使用是一个必须在上下文中被解析的具体特征;变体定义则声明类型本身就是一个变体 — 该定义的每一次使用都继承变体点语义。

3

配置管理

KerML 起源:配置绑定 → 把变体解析到某个具体变体的 BindingConnector

配置是对模型中全部变体点的一次具体解析。它为每个变体点恰好选定一个变体,从而产出一个完整规定的产品实例。在 SysML v2 中,配置通过特化产品定义、并把每个变体使用绑定到所选变体来建模。

通过特化创建配置

标准做法是新建一个零件定义或使用,特化那个可变的产品,并绑定每一个变体点:

1// Base product with variation points
2part def Vehicle {
3 part engine : Engine;
4 variation part transmission : Transmission {
5 variant part manual : ManualTransmission;
6 variant part automatic : AutomaticTransmission;
7 }
8 variation part infotainment : Infotainment {
9 variant part basic : BasicInfotainment;
10 variant part premium : PremiumInfotainment;
11 }
12}
13
14// Configuration: Sport Edition
15part def SportEdition :> Vehicle {
16 // Resolve transmission to manual
17 part transmission redefines Vehicle::transmission = transmission::manual;
18 // Resolve infotainment to premium
19 part infotainment redefines Vehicle::infotainment = infotainment::premium;
20}
21
22// Configuration: Economy Edition
23part def EconomyEdition :> Vehicle {
24 part transmission redefines Vehicle::transmission = transmission::automatic;
25 part infotainment redefines Vehicle::infotainment = infotainment::basic;
26}

部分配置

并非每个配置都必须解析全部变体点。部分配置只解析其中一部分,其余保持开放。这在为产品档次或区域变体建模时很有用 — 某些选择已经固定,另一些仍需灵活:

1// Partial configuration: European variant (fixes transmission, leaves infotainment open)
2part def EuropeanVehicle :> Vehicle {
3 part transmission redefines Vehicle::transmission = transmission::manual;
4 // infotainment variation point remains unresolved
5}
6
7// Full configuration: European Sport (resolves remaining variation)
8part def EuropeanSport :> EuropeanVehicle {
9 part infotainment redefines Vehicle::infotainment = infotainment::premium;
10}
提示

可以用部分配置搭建分层的配置体系:从基础产品出发,先做区域级或档次级的部分配置,再在叶节点做完全解析的配置。这与汽车主机厂在实践中管理产品线的方式一致。

4

过滤与选择

KerML 起源:filterFilterExpression(作用于元数据的布尔表达式)

过滤表达式提供一种查询机制,可依据元数据条件从命名空间中挑选元素。与直接的变体绑定不同,过滤器可以跨包工作,并能同时选中多个元素。它与元数据注解配合使用时尤其强大。

基本过滤语法

filter 表达式是施加于包内元素的布尔谓词。只有满足该谓词的元素才会出现在过滤后的视图中:

1// Metadata for tagging elements
2metadata def Region {
3 attribute name : ScalarValues::String;
4}
5
6metadata def Tier {
7 attribute level : ScalarValues::String;
8}
9
10package AllFeatures {
11 part heatedSeats : HeatedSeats {
12 @Region { name = "EU"; }
13 @Tier { level = "premium"; }
14 }
15 part airCon : AirConditioning {
16 @Region { name = "ALL"; }
17 @Tier { level = "basic"; }
18 }
19 part sunroof : PanoramicSunroof {
20 @Region { name = "US"; }
21 @Tier { level = "premium"; }
22 }
23}

应用过滤表达式

过滤表达式依据元数据从包中挑选元素。被过滤的包充当一个视图 — 它并不复制元素,而是给出一个受限的子集:

1// Select only premium-tier features
2package PremiumFeatures {
3 import AllFeatures::**;
4 filter @Tier and Tier::level == "premium";
5}
6
7// Select only EU-region features
8package EUFeatures {
9 import AllFeatures::**;
10 filter @Region and (Region::name == "EU" or Region::name == "ALL");
11}
说明

过滤表达式作用于元数据注解。它们不会修改底层模型 — 只是产出一个仅含匹配元素的模型视图。这在概念上类似数据库查询:数据本身没变,只是结果集被收窄了。

把过滤器与变体结合使用

过滤器与变体点是互补机制。变体点定义的是强制选择(必须选一个);过滤器定义的是可选纳入(满足条件才纳入)。设计良好的产品线两者兼用:

常见误区

不要用过滤器替代变体点。过滤器是从既有集合中挑选,变体点则声明一次强制选择。如果每个产品都必须在若干备选中恰好取一个,请用 variation/variant;如果某项功能是依据元数据有条件地纳入,才用 filter

5

产品线建模

KerML 起源:产品线 → 混合了变体与非变体内容的 Package

产品线是一族共享同一平台、但在具体功能上有所差异的产品。SysML v2 通过共享定义(平台)、变体点(可配置的部分)与配置(已解析的产品)三者的组合来支持产品线建模。

平台 + 变体策略

推荐的模式把模型分为三层:

  1. 平台包 — 共享定义、不变结构与公共约束
  2. 可变性包 — 变体点与变体定义
  3. 配置包 — 绑定了全部变体点的完整产品
1package Platform {
2 // Shared across all products
3 part def Chassis { attribute wheelbase : ISQ::LengthValue; }
4 part def BrakeSystem { part frontBrakes : DiscBrake; part rearBrakes : DiscBrake; }
5 part def SteeringSystem { attribute ratio : ScalarValues::Real; }
6}
7
8package Variability {
9 private import Platform::*;
10
11 part def ProductVehicle {
12 part chassis : Chassis; // from platform (invariant)
13 part brakes : BrakeSystem; // from platform (invariant)
14 part steering : SteeringSystem; // from platform (invariant)
15
16 // Variable aspects
17 variation part body : BodyStyle {
18 variant part sedan : SedanBody;
19 variant part suv : SUVBody;
20 variant part truck : TruckBody;
21 }
22 variation part powertrain : Powertrain {
23 variant part petrol : PetrolPowertrain;
24 variant part diesel : DieselPowertrain;
25 variant part electric : ElectricPowertrain;
26 }
27 }
28}
29
30package Configurations {
31 private import Variability::*;
32
33 part def SedanPetrol :> ProductVehicle {
34 part body redefines ProductVehicle::body = body::sedan;
35 part powertrain redefines ProductVehicle::powertrain = powertrain::petrol;
36 }
37
38 part def SUVElectric :> ProductVehicle {
39 part body redefines ProductVehicle::body = body::suv;
40 part powertrain redefines ProductVehicle::powertrain = powertrain::electric;
41 }
42}

约束在变体间的传播

定义在平台或基础产品上的约束适用于全部配置;变体特有的约束则可以加在变体层级上:

1part def ProductVehicle {
2 // Platform constraint: applies to ALL configurations
3 assert constraint maxWeight {
4 chassis.totalMass <= 2500[kg]
5 }
6
7 variation part body : BodyStyle {
8 variant part truck : TruckBody {
9 // Variant-specific constraint: only applies when truck is selected
10 assert constraint towingCapacity {
11 payloadCapacity >= 1000[kg]
12 }
13 }
14 }
15}
提示

三层模式(平台、可变性、配置)具有良好的可扩展性:平台包可由平台工程团队维护,可变性包由产品管理负责,配置包则由各产品团队负责。每一层从下一层导入内容。

6

完整示例

下面的模型整合了本模块的全部概念:一条车辆产品线,包含轿车、SUV 与皮卡三种变体,共享同一平台,各自具备动力总成与功能级的可变性,并配有元数据驱动的过滤和完整解析的配置。

1package VehicleProductLine {
2 private import ISQ::*;
3 private import SI::*;
4 private import ScalarValues::*;
5
6 // ── Metadata for filtering ──────────────────────────────
7 metadata def MarketRegion {
8 attribute region : String;
9 }
10 metadata def FeatureTier {
11 attribute tier : String;
12 }
13
14 // ── Shared platform ─────────────────────────────────────
15 part def Chassis {
16 attribute wheelbase : LengthValue;
17 attribute curbWeight : MassValue;
18 }
19 part def BrakeSystem {
20 part frontBrakes : DiscBrake;
21 part rearBrakes : DiscBrake;
22 part abs : ABSController;
23 }
24 part def SteeringSystem {
25 attribute steeringRatio : Real;
26 }
27
28 // ── Body style variants ──────────────────────────────────
29 part def BodyStyle;
30 part def SedanBody :> BodyStyle {
31 attribute doorCount : Integer = 4;
32 attribute trunkVolume : VolumeValue;
33 }
34 part def SUVBody :> BodyStyle {
35 attribute doorCount : Integer = 5;
36 attribute groundClearance : LengthValue;
37 attribute roofRails : Boolean = true;
38 }
39 part def TruckBody :> BodyStyle {
40 attribute doorCount : Integer = 4;
41 attribute bedLength : LengthValue;
42 attribute payloadCapacity : MassValue;
43 }
44
45 // ── Powertrain variants ──────────────────────────────────
46 part def Powertrain;
47 part def PetrolPowertrain :> Powertrain {
48 attribute displacement : VolumeValue;
49 attribute cylinders : Integer;
50 attribute maxPower : PowerValue;
51 }
52 part def DieselPowertrain :> Powertrain {
53 attribute displacement : VolumeValue;
54 attribute maxTorque : ForceValue;
55 }
56 part def ElectricPowertrain :> Powertrain {
57 attribute batteryCapacity : EnergyValue;
58 attribute range : LengthValue;
59 attribute chargePower : PowerValue;
60 }
61
62 // ── Optional feature packages (metadata-tagged) ─────────
63 package FeatureCatalog {
64 part heatedSeats : HeatedSeats {
65 @MarketRegion { region = "ALL"; }
66 @FeatureTier { tier = "premium"; }
67 }
68 part adaptiveCruise : AdaptiveCruiseControl {
69 @MarketRegion { region = "ALL"; }
70 @FeatureTier { tier = "premium"; }
71 }
72 part towHitch : TowHitch {
73 @MarketRegion { region = "US"; }
74 @FeatureTier { tier = "basic"; }
75 }
76 part headlightWashers : HeadlightWashers {
77 @MarketRegion { region = "EU"; }
78 @FeatureTier { tier = "basic"; }
79 }
80 }
81
82 // ── Base product with variation points ───────────────────
83 part def Vehicle {
84 // Platform (invariant across all configurations)
85 part chassis : Chassis;
86 part brakes : BrakeSystem;
87 part steering : SteeringSystem;
88
89 // Variation point 1: body style
90 variation part body : BodyStyle {
91 variant part sedan : SedanBody;
92 variant part suv : SUVBody;
93 variant part truck : TruckBody;
94 }
95
96 // Variation point 2: powertrain
97 variation part powertrain : Powertrain {
98 variant part petrol : PetrolPowertrain;
99 variant part diesel : DieselPowertrain;
100 variant part electric : ElectricPowertrain;
101 }
102
103 // Platform constraint: all variants must satisfy
104 assert constraint maxGrossWeight {
105 chassis.curbWeight <= 3000[kg]
106 }
107 }
108
109 // ── Filtered feature views ───────────────────────────────
110 package PremiumFeatures {
111 import FeatureCatalog::**;
112 filter @FeatureTier and FeatureTier::tier == "premium";
113 }
114 package USFeatures {
115 import FeatureCatalog::**;
116 filter @MarketRegion and (MarketRegion::region == "US"
117 or MarketRegion::region == "ALL");
118 }
119 package EUFeatures {
120 import FeatureCatalog::**;
121 filter @MarketRegion and (MarketRegion::region == "EU"
122 or MarketRegion::region == "ALL");
123 }
124
125 // ── Fully resolved configurations ────────────────────────
126 part def SedanPetrolUS :> Vehicle {
127 part body redefines Vehicle::body = body::sedan;
128 part powertrain redefines Vehicle::powertrain = powertrain::petrol;
129 // Include US-market features from the filtered view
130 }
131
132 part def SUVElectricEU :> Vehicle {
133 part body redefines Vehicle::body = body::suv;
134 part powertrain redefines Vehicle::powertrain = powertrain::electric;
135 // Include EU-market features from the filtered view
136 }
137
138 part def TruckDieselUS :> Vehicle {
139 part body redefines Vehicle::body = body::truck;
140 part powertrain redefines Vehicle::powertrain = powertrain::diesel;
141
142 // Truck-specific constraint override
143 assert constraint towRating {
144 body.payloadCapacity >= 1500[kg]
145 }
146 }
147}

该模型演示了:共享平台(底盘、制动、转向)、两个各含三个变体的变体点(车身形式、动力总成)、带市场区域与档次过滤表达式的元数据标记选装功能、适用于全部配置的平台级约束变体特有约束(皮卡拖挂能力),以及面向不同细分市场的三个完整解析配置

7

模块总结

SysML v2 概念KerML 起源关键规则
variation(作用于使用)isVariation = true 的 Usage把某个特征标记为变体点;必须解析为恰好一个变体
variantVariantMembership在变体点内声明一个允许的备选项
variation part defisVariation = truePartDefinition定义本身即是变体;其每次使用都继承变体语义
配置绑定BindingConnector通过 redefines 把变体使用解析到某个具体变体
部分配置仍有部分变体未解析的特化固定一部分选择,其余留待进一步特化
filter 表达式FilterExpression依据元数据条件从命名空间中挑选元素;产出一个视图
产品线包内容混合的 Package三层模式:平台 + 可变性 + 配置
元数据标记元数据注解为元素标注区域、档次等筛选条件,供过滤使用
表 — 模块 8 的概念及其 KerML 起源
下一模块

模块 9 — 验证与确认 — 如何定义验证用例、把它们绑定到需求、为验证方法建模,并把 V&V 融入系统工程生命周期。