问题域包含大量命名的snark。有些嗤之以鼻。
至少有两种方法可以对此进行建模:
// as a property: class Snark { string name; bool is_boojum; }; // as a list: class Snark { typedef long Id; Id id; string name; }; tree<Snark::Id> boojums;
看起来很直观,如果我们确定snarks是男性和女性,我们会在snark类定义中添加“sex”属性;如果我们确定除了五个狙击手之外的所有掠夺者都被征服了,我们就会列出皇室成员。
是否存在可以应用的原则,还是建筑偏好的问题?
答案 0 :(得分:6)
你想解决什么问题?
如果记录snarks的版税的目的是在GUI中在他们的头上显示一个表冠,那么它仅仅是一个属性是有意义的。 (或者,可能有一个RoyalSnark子类,带有重写的Render方法。)
如果目的是快速找到所有的皇家狩猎,那么列表更合适 - 否则你需要查看每个狙击并检查其属性。
答案 1 :(得分:2)
作为派生类:
class Snark
{
virtual void Approach(Creature& approacher) {};
};
class Boojum : public Snark
{
virtual void Approach(Creature& approacher)
{
approacher.softlySuddenlyVanishAway();
}
};
答案 2 :(得分:2)
我认为与分类相关的信息熵可以作为使用哪种方法的指南。低熵分类(即大多数对象具有相同的值)建议跟踪特殊情况的列表实现,而高熵分类(您不能对对象将具有哪种分类做出任何非常好的预测)建议属性实现。
答案 3 :(得分:1)
在所有情况下,这样做的自然方式似乎都是属性。
您可以使用列表来提高性能,或者优化空间。这两个原因都将我视为过早优化,破坏封装和/或存储冗余数据的潜在案例,从而导致缺乏完整性的风险(因为我仍然可以查询对象本身以查明它是否为皇室 - 我不应该不得不知道此属性是出于性能原因以特殊方式处理的。我可以设想隐藏getter后面的列表实现,使其表现为属性。
此外,如果这些对象存储在数据库中,性能问题就会消失,因为数据库层可以在运行时使用查询创建列表。
答案 4 :(得分:0)
如果您询问数据库建模,那么将is_boojum
视为表Snarks
中的属性列最为直接。如果您需要搜索所有的boojums,查询很简单:
SELECT * FROM Snarks WHERE is_boojum = 1
这给出了逻辑上正确的答案,并且很容易建模。它可能不会那么快,因为索引具有低选择性的列(许多行具有相同的值)不是非常有效,并且可能根本不会从索引中受益。
但你的问题是关于建模,而不是优化。
答案 5 :(得分:0)
嗯。我的第一个想法是,确实,Boojum是Snark的子类型。但是规范似乎反对它,因为“你知道,”这只是一种嘘声。“好吧,这意味着snark is_a Boojum,这将使继承图循环。不能那样。
另一方面,我认为没有迹象表明Snark可以成为一个Boojum;无论是Boojum还是不是。
我想你可能想要一个Boojum mixin -
abstract class Snark { /*...*/ };
class PlainSnark extends Snark {/*...*/};
class RoyalSnark extends Snark implements Boojum {/*...*/};