4

问题域以大量命名的蛇为特征。有些蛇是boojums。

至少有两种方法可以对此建模:

// 作为属性:
    类蛇{
      字符串名称;
      布尔 is_boojum;
    };  

// 作为一个列表:
    类蛇{
      typedef 长 ID;
      身份证号码;
      字符串名称;
    };  

    树<Snark::Id> boojums;

看起来很直观,如果我们确定 snark 分为男性和女性,我们将在 snark 类定义中添加“sex”属性;如果我们确定除了 5 条蛇以外的其他人都是被征服的臣民,我们就会列出一份皇室成员名单。

是否有可以应用的原则,或者是架构偏好的问题?

4

6 回答 6

6

你想解决什么问题?

如果记录蛇的版税的目的是在 GUI 中显示他们头上的王冠,那么它只是一个属性是有意义的。(或者,可能有一个 RoyalSnark 子类,带有一个重写的 Render 方法。)

如果目的是快速找到所有皇家蛇,那么列表更合适 - 否则您需要查看每个蛇并检查其属性。

于 2008-12-23T00:21:05.580 回答
2

作为派生类:

class Snark 
{
   virtual void Approach(Creature& approacher) {};
};

class Boojum : public Snark
{
   virtual void Approach(Creature& approacher) 
   { 
      approacher.softlySuddenlyVanishAway(); 
   }
};
于 2008-12-23T00:38:33.207 回答
2

我相信与分类相关的信息熵可以指导使用哪种方法。低熵分类(即大多数对象具有相同的值)建议使用列表实现来跟踪例外情况,而高熵分类(您无法很好地预测对象将具有哪种分类)建议使用属性实现。

于 2008-12-23T04:43:27.610 回答
1

在所有情况下,这种自然的方式似乎都是一种属性。

您可以使用列表来提高性能或优化空间。这两个原因都让我觉得过早优化、破坏封装和/或存储冗余数据的潜在情况会导致缺乏完整性的风险(因为我仍然应该能够查询对象本身以查明它是否是皇家的——我应该'不必知道出于性能原因以特殊方式处理此属性)。我可以假设将列表实现隐藏在 getter 后面,以使其表现为属性。

此外,如果这些对象存储在 DB 中,性能问题几乎就消失了,因为 DB 层可以在运行时使用查询来创建列表。

于 2008-12-23T00:29:53.240 回答
0

如果您要询问数据库建模,那么将其is_boojum视为 table 中的属性列是最直接的Snarks。如果你需要搜索所有 boojums,查询很简单:

SELECT * FROM Snarks WHERE is_boojum = 1

这给出了逻辑上正确的答案,并且很容易建模。它可能不会那么快,因为索引具有低选择性的列(许多行具有相同的值)效率不高,并且可能根本无法从索引中受益。

但是您的问题是关于建模,而不是优化。

于 2008-12-23T00:31:48.460 回答
0

嗯。我的第一个想法是,的确,Boojum 是 Snark 的一个子类型。但规范似乎反对它,因为“你看,蛇是一个boojum”。好吧,这意味着 snark is_a Boojum,这将使继承图循环。不能这样。

另一方面,我认为没有任何迹象表明 Snark 可以变成Boojum。要么是 Boojum,要么不是。

我想你可能想要一个 Boojum mixin——

abstract class Snark { /*...*/ };
class PlainSnark extends Snark {/*...*/};
class RoyalSnark extends Snark implements Boojum {/*...*/};
于 2008-12-23T02:45:11.280 回答