16

我有以下课程:

CachedObject
CachedObjectSource
CachedObjectDbSource < CachedObjectSource
CachedObjectDalliSource < CachedObjectSource

CachedObject 是从第三方 API 提取并存储在本地的非数据库对象。CachedObject 将存储在数据库和 Dalli (memcache) 中,实时代码将 ping Dalli 源以获取对象的副本,如果对象不存在,Dalli 源将搜索数据库源并更新其缓存. 所以它是一个嵌套调用,要求 CachedObjectSource 的每个子类实现相同的一组方法。IE,一个界面。

有没有办法编写 CachedObjectSource 类,使其子类必须实现接口?我会以错误的方式解决这个问题吗?

4

3 回答 3

23

Ruby 不知道类似于 Java 的接口。相反,Ruby 程序通常使用一种称为Duck Typing的方法,这基本上意味着您可以向任何对象发送任何消息,然后该对象可以决定它是否会响应,即每个对象自行决定它具有哪些方法。

您可以获得的最接近“接口”的东西是实现方法但仅引发NotImplementedError类似于此的类(或模块):

class CachedObjectSource
  def my_method
    raise NotImplementedError, "Implement this method in a child class"
  end
end

这样,该方法将存在并在调用时返回一个合理的错误,而不会在子类中被覆盖。然后,您应该编写一些文档以明确必须实现哪些子类才能符合要求。

于 2013-09-11T15:51:22.287 回答
3

您可以使用 gem界面
这个 gem 模拟类似于 Java 接口的接口。
例如:

require 'interface'

MyInterface = interface{
  required_methods :foo, :bar, :baz
}

# Raises an error until 'baz' is defined
class MyClass
  def foo
    puts "foo"
  end

  def bar
    puts "bar"
  end

  implements MyInterface
end

这种与抽象宝石一起有用的宝石。
抽象 gem 提供抽象方法。

于 2015-07-16T20:20:08.443 回答
2

你也可以使用rint

gem 'rint'

附带一个 CLI:

$ rint c CachedObjectSourceInterface my_method

将创建一个接口定义,但您也可以手动将其添加到任何类。然后您可以执行以下操作:

class Instrument 
  implements CachedObjectSourceInterface
end

my_method如果方法没有实现,它会抛出一个有意义的异常。

于 2016-09-05T08:18:12.467 回答