【发布时间】:2015-05-20 00:09:39
【问题描述】:
假设我有一个父类:
class Stat
def val
raise "method must be implemented by subclass"
end
end
还有一个子类:
class MyStat < Stat
def val
#performs costly calculation and returns value
end
end
通过扩展父类,我希望子类不必担心缓存“val”方法的返回值。
这里可以使用很多模式来达到这种效果,我已经尝试了几种尺寸,但没有一个适合我,而且我知道这是一个已解决的问题,所以浪费时间和努力。这通常是如何处理的?
另外,我突然想到我可能问错了问题。也许我根本不应该使用继承,而是使用组合。
任何和所有的想法都表示赞赏。
编辑:
我采用的解决方案可以总结如下:
class Stat
def value
@value ||= build_value
end
def build_value
#to be implemented by subclass
end
end
【问题讨论】:
-
抽象基类不是你在 Ruby 中经常看到的东西,没有标准的方法来声明它们,在
raise中存根是 Ruby 标准的一个非常绝望的举动。通常,您会看到基类实现了 null 情况,或者做的工作尽可能少,文档清楚地表明您的子类必须实现许多事情。对所有方法进行测试是至关重要的,这里没有依赖编译器来捕捉错误。指导人们应该做什么。如果他们不听,不要大惊小怪。 -
@tadman 谢谢,很高兴听到这个消息。我的第一语言是 java,我不禁觉得它对我在其他语言中与设计相关的思维有着有害的影响。红宝石的方式是安静地失败。我只是不禁觉得代码应该是自我记录的,所以如果没有我为它编写的一些冗长的文档,我编写的代码可能没有意义的想法让我感到不安,尽管也许它不应该是。
-
就像学习一种语言的人带有另一种语言的口音一样,编程时也是如此。 Java 方式和 Ruby 方式经常发生冲突,而 Ruby 更为随意。因此,测试是验证是否已实施正确行为的唯一方法。抽象基类只是解决问题的一种方法,但还有其他方法可以实现相同的目标。就我个人而言,我喜欢 meagar 的回答,它是 Ruby 方式,对您的异常要求稍作让步。
标签: ruby oop inheritance design-patterns