【问题标题】:Class design for two objects that derive from the same class but share no common methods派生自同一个类但不共享公共方法的两个对象的类设计
【发布时间】:2012-03-14 19:42:44
【问题描述】:

我有一组表示文件中字体格式存储的类。每种字体都定义了一组字形(一种映射到 UTF32 代码的形状)。

字形可以用轮廓(在我的例子中是一组贝塞尔曲线)或位图来表示。

我的第一个想法是,这会导致 GlyphOutline 和 GlyphBitmap 类继承自 Glyph。

这种设计唯一的问题是没有通用的方法。为了对这两个类做任何有用的事情,我需要使用 rtti(我宁愿避免)。

我的问题是:您能想出一种更好的方式来表示字形/是否有一些设计模式可以处理这种情况?

我试图让这种语言不可知,但如果有什么不同,我会用 c++ 编写。

编辑:

我考虑过使用泛型,其中 Glyph 包含对一些/许多 GlyphRepresentations 的引用,其中 T 将是 Outline 或 Bitmap 或您可以用来表示字形的任何其他内容。我实际上非常喜欢这个作为解决方案,因为它解决了由 Outline 和 Bitmap 表示的字形问题。但是它会强制使用 rtti。

这可能是我在使用 c# 时会选择的解决方案明白我很想避免

编辑:

在回答 oli 时,我同意你的观点,但是 isa 关系(如 GlyphOutline 中的 Glyph 是一个 Glyph,并且可以做一个字形可以做的所有事情)是存在的,我认为这意味着应该有继承?我不确定这一点,似乎两种方式都有很好的论据。

到目前为止,我首选的解决方案是访问者模式,但这只是评论而不是答案,我想再等一会儿,看看是否有其他解决方案浮出水面。

【问题讨论】:

  • 你不能在上面做模板,没有继承吗?对于那些你想使用 RTTI 的情况,为什么它们不能是虚拟成员函数?
  • 如果我们更多地了解Glyph 实例的使用方式,将会有所帮助。你没有做多态性,这……很奇怪。
  • 如果你没有共同的行为,那么从一个共同的基类派生可能没有意义。
  • 查看访客模式。这可能是避免 rtti 的方法。
  • 你绝对应该有一个接口,比如说 IGlyph,这两个类都会实现。 IGlyph 将提供将对象视为一组贝塞尔曲线的方法。您可以为此目的使用纯抽象基类。

标签: c++ oop


【解决方案1】:

听起来像drawOnScreen()getMetrics()getCodePoint() 这样的方法很适合多态行为。

【讨论】:

  • 我同意,但这并不能真正解决区分位图字形和轮廓字形的问题。
  • 回顾我提出的问题,并且在编写代码方面不那么糟糕,我现在认为这个答案应该让我在正确的轨道上思考。我只是不明白你当时在开什么车。谢谢
【解决方案2】:

好吧,如果我理解正确的话,你可以像下面这样使用 Builder 设计模式:

可以定义一组字形。每个 Glyph 都将实现 IGlyph 接口,该接口将允许 Font 类的实例访问贝塞尔曲线集。

class OutlineGlyph : public IGlyph
class BitmapGlyph : public IGlyph

然后实例化其中一些并通过它们的具体接口设置它们中的每一个。

OutlineGlyph og;
og.Method(...)

然后应该实例化 FontBuilder 类。

FontBuilder fontBuilder;
fontBuilder.AddGlyph(og);
fontBuilder.AddGlyph(bg);

Font* font = fontBuilder.CompileFont()

【讨论】:

  • BitmapGlyph 提供了一组贝泽曲线?您的回答暗示确实如此。如果我误解了,请纠正我。
  • 对不起,我第一次阅读您的帖子时没有注意到 BitmapGlyph 和 OutlineGlyph 有不同的表示形式。无论如何,IGlyph 将包含 BitmapGlyph 和 OutlineGlyph 通用的方法。例如绘图代码等
  • 这里的重点是,可以通过在单独的工作流阶段区分具体对象的工作来避免使用 rtti 和访问者模式
  • 我看不出这如何避免使用任何一个。我现在如何从您的示例中的字体指针获得 UTF32 代码 123 的位图表示?据我了解你的代码我会收到一个 IGlyph*,我不能确定它是否包含没有某种形式的 rtti 的位图。
  • 说明 Font 类的职责列表很重要。也许有一个接口IFont会更好。然后,您可以创建一个实现 IFont 并提供获取与其关联的位图的功能的 BitmapFont 类。
【解决方案3】:

我为模板和接口投票!!不能使用继承,因为没有共同的行为。而且我真的不明白为什么你应该避免 RTTI 它是该语言的更好特性之一。如果您当前使用 RTTI 的设计模式解决了问题,为什么要更改?

【讨论】:

  • 使用 RTTI 代替虚拟成员函数的多态性只是一个坏主意(c)
  • 导致代码被 if(dynamic_cast(p)) else ... 乱扔的代码比 this->some_virtual_method() 更易于维护和阅读。它喜欢人们在JAVA中滥用instanceof,这意味着他们根本不了解虚拟重载的概念。
  • 抱歉,您的评论措辞令人困惑。你的意思是远可维护吗?我宁愿看到:this->some_virtual_method() 而不是:if(dynamic_cast(p)) else
  • 我想我应该/更多/更少抱歉。当然,它比虚拟通话更难管理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
相关资源
最近更新 更多