创建与使用模型(一)

模型是某一种业务的抽象,粒度可能很大,也可能很小,相关的业务可能是显而易见的,也可能是隐式的。有些模型是被发现的,而有些模型是被创造的。发现模型的过程是抽象过程,将具体的对象抽象为类或者接口;创造模型的过程是归纳过程,将若干零散的数据归纳在一起,创建一个带有含义的新的类型。

最近在做一个转换程序,将一系列描述动作顺序的数据转换为可视化的图形数据。图形包括泳道(lane),和在泳道中的事件(event),以及事件之间的连接(edge)。表示泳道图元的宽、高、位置,和表示事件的宽、高、位置等都是常量,下面的代码定义了如何生成泳道:

1
2
3
4
5
6
7
8
9
10
11
{
id: item.userName,
shape: "lane",
width: 200,
height: 800,
position: {
x: 60 + 200 * idx++,
y: 20
},
label: item.userName
}

每一个执行动作的用户生成一个泳道,泳道的宽为200,高为800,泳道横向排列,从x坐标为60开始,y坐标为20,我们首先想到的是将这些数值用常量表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const lane_width=200
const lane_height=800
const lane_xStart=20
const lane_xStep=200
const lane_y=20
....
{
id: item.userName,
shape: "lane",
width: lane_width,
height: lane_height,
position: {
x: lane_xStart + lane_xStep * idx++,
y: lane_y
},
label: item.userName
}

这样改造是建模的第一个步骤,将无意义的数值使用有意义的常量名称代替,这样,代码的可读性提高了,也便于修改。然而,这样做还不够,想象一下,如果需要绘制两组不同的泳道,宽、高和其它位置都有变化,该如何处理呢?这些常量就需要作为变量进行处理。我们需要为这些参数创建一个模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

const config = default || {
lane: {
shape: "lane",
width: 200,
height: 800,
xStart: 60,
xStep: 200,
y: 20
}
}
....
{
id: item.userName,
shape: config.lane.shape,
width: config.lane.width,
height: config.lane.height,
position: {
x: config.lane.xStart + config.lane.xStep * idx++,
y: config.lane.y
},
label: item.userName
}

现在,如果将default作为传入参数,就可以很方便地修改图元定义了。

进一步研究模型:

1
2
3
4
5
6
7
8
lane: {
shape: "lane",
width: 200,
height: 800,
xStart: 60,
xStep: 200,
y: 20
}

我们发现,x和y是不对称的,x方向有开始和步长,y方向没有,那么如果y方向也有相应的参数,含义是什么呢?应该是泳道可以纵向排列,我们可以修改模型和最终的生成算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

const config = default || {
lane: {
shape: "lane",
width: 200,
height: 800,
xStart: 60,
xStep: 200,
yStart: 20,
yStep: 0
}
}
....
{
id: item.userName,
shape: config.lane.shape,
width: config.lane.width,
height: config.lane.height,
position: {
x: config.lane.xStart + config.lane.xStep * idx++,
y: config.lane.yStart + config.lane.yStep * idx++
},
label: item.userName
}

在这个例子中,我们将生成模型中的初始化参数抽提出来,创建了一个新的初始参数模型,同时使用这两个模型,可以使代码更容易理解。只通过初始化模型,就可以理解和配置生成模型。