全队穿一样的制服,一眼分清类和属性
为本体中的概念定义命名约定,并严格遵照这些约定,不仅能让本体更容易理解,还能帮助避免一些常见的建模错误。
命名概念有很多种方案,通常没有特别的理由去选这一种而不是那一种。但是,我们需要:
为类和属性定义一套命名约定,并遵守它。
知识表示系统的下面这些特性,会影响命名约定的选择:
winery 的类和一个叫 winery 的属性?Winery 和 winery)当作不同的名字?举例来说:Protégé-2000 为它所有的框架维护单一的名字空间,并且区分大小写。因此我们不能同时有一个 winery 类和一个 winery 属性;但可以有 Winery 类(注意大写 W)和 winery 属性。
CLASSIC 则相反:它不区分大小写,并且为类、属性、个体维护各自独立的名字空间。因此从系统角度看,把类和属性都命名为 Winery 没有任何问题。
首先,如果我们对概念名使用大小写一致的规则,本体的可读性会大幅提升。比如一个常见的做法是:类名首字母大写,属性名全小写(前提是这个系统区分大小写)。
当一个概念名包含多个单词时(比如 Meal course,一道菜),我们需要分隔单词。可能的做法有:
| 做法 | 例子 |
|---|---|
| 用空格 | Meal course(包括 Protégé 在内的很多系统允许概念名里有空格) |
| 连写并每个新词首字母大写 | MealCourse |
| 用下划线、短横线或其他分隔符 | Meal_Course、Meal_course、Meal-Course、Meal-course |
如果知识表示系统允许名字里有空格,用空格对很多本体开发者来说可能是最直观的方案。 不过,考虑一下你的系统可能与之交互的其他系统,也很重要。如果那些系统不用空格,或者你的展示媒介处理空格不好,那用另一种方法可能会有用。
一个类名代表的是对象的集合。 比如 Wine 类实际上代表所有的酒。因此,对某些设计者来说,把类叫 Wines 而不是 Wine 可能更自然。两种选择没有谁比谁更好(尽管实践中单数形式的类名用得更多)。但无论选哪种,都必须贯穿整个本体保持一致。有些系统甚至要求用户事先声明将使用单数还是复数,并且不允许违背这个选择。
始终使用同一种形式,还能防止设计者犯下这类建模错误:建了一个 Wines 类,然后又建了一个 Wine 类做它的子类(见 4.1 节)。
Wine 是 Wines 的子类时,你自己就会觉得别扭——这就是 4.1 节那个“单数不能是复数的子类”错误的第一道防线。有些知识库方法论建议在名字里用前缀和后缀约定来区分类和属性。两种常见做法是给属性名加 has- 前缀、或者加 -of 后缀:用 has- 约定,属性变成 has-maker、has-winery;用 of- 约定,属性变成 maker-of、winery-of。这种做法让任何人看一眼术语,就能立刻判断它是类还是属性。 不过代价是:术语名会变得稍长一些。
定义命名约定时,还有几件事要考虑:
Cabernet Sauvignon 而不是 Cab)。Wine 类建两个子类来表示红酒和白酒,这两个子类名要么是 Red Wine 和 White Wine,要么是 Red 和 White,但不能是 Red Wine 和 White。Red Wine 和 White 并排放着,读者会本能地觉得“白”是个更小的东西——因为两个名字暗示的抽象层级不一样。命名的不对称,会让人误读出结构的不对称。