DelegateClass与Ruby中的类继承

时间:2016-08-06 21:44:42

标签: ruby inheritance delegation

有人可以通过DelegateClass(例如Seller < DelegateClass(Person))以及何时在ruby中使用类继承(例如Seller < Person)来提供有关何时使用委派的一些见解?

class Seller < DelegateClass(Person)
  def sales
     ...
  end 
end 

class Seller < Person 
  def sales
     ...
  end 
end 

当我在Github上查看Ruby on Rails源代码时,我发现了很多uses of DelegateClass

2 个答案:

答案 0 :(得分:7)

有一些差异有助于深入了解使用哪种方法。

1)您可以安全地委托给基元(例如String),但不能总是安全地从它们继承

如果您在HashStringFixnum之上构建,则使用DelegateClass(或其他委托人)会更安全。有关原因的更多信息,Steve Klabnik's cautioning是一个很好的起点。)

2)DelegateClass可以轻松地将更通用的对象“转换”为更具体的对象

这样可以更容易地接受一般对象的实例,并使其行为以特定于您的实现的方式运行:

class Message < DelegateClass(String)
  def print
    upcase
  end
end

# […]

def log(message)
  message = Message.new(message) unless message.is_a?(Message)
end

3)问题:DelegateClass子类期望委托类的实例作为new的参数

这可能会使您将要传递给库代码的类“子类化”变得棘手。例如,这是一种相当普遍的做法,它不会与DelegateClass开箱即用:

class MyLogger < DelegateClass(ActiveSupport::Logger); end

Foo::ThirdParty::Library.configure do |c|
  c.logger = MyLogger # no good
end

这不起作用,因为我们的库期望像大多数记录器一样行为并且不带参数进行实例化。这可以通过定义initialize和创建ActiveSupport::Logger的实例来解决,但在这种情况下可能不是正确的解决方案。

答案 1 :(得分:2)

委托根据上下文对Person的不同行为进行建模。例如同一个人可以是一个上下文中的卖方,也可以是不同上下文中的买方。继承更加严格:BearTiger继承自Animal,但Animal的实例永远不需要有时像Bear那样行事,有时也会表现出来像TigerAnimal的后代的实例是一个或另一个。