【问题标题】:When to use Ruby DelegateClass instead of SimpleDelegator? (DelegateClass method vs. SimpleDelegator class)何时使用 Ruby DelegateClass 而不是 SimpleDelegator? (DelegateClass 方法与 SimpleDelegator 类)
【发布时间】:2012-10-17 18:46:52
【问题描述】:

可能我遗漏了一些简单的东西,但我不明白如何使用 Ruby 的 DelegateClass 方法,我的意思是何时使用它而不是 SimpleDelegator 类。例如,以下所有的工作似乎几乎相同:

require 'delegate'

a = SimpleDelegator.new([0])
b = DelegateClass(Array).new([0])
c = DelegateClass(String).new([0])
a << 1
b << 2
c << 3
p a # => [0, 1]
p b # => [0, 2]
p c # => [0, 3]

请注意,将哪个类传递给DelegateClass 似乎并不重要。

【问题讨论】:

  • 在考虑了一段时间之后,整个委托模式在我看来就像一个快速肮脏的黑客:)。您发送一条消息,但您不知道哪个班级将负责回答。委托人在不知道是否以及如何回答的情况下传递它无法识别的所有消息(否则它可以实现为子类,或者使用组合,不是吗?)。原来的类不再真正控制任何东西,甚至不知道它和世界其他地方之间有一个委托人。

标签: ruby design-patterns delegation


【解决方案1】:

如果您想要一个对象既具有自己的行为又在其生命周期内委托给不同的对象时,请使用子类 SimpleDelegator。

本质上说,当您创建的类不会获得不同的对象时,请使用 DelegateClass。 Ruby 中的TempFile 只会装饰一个 File 对象 SimpleDelegator 可以在不同的对象上重复使用。

Example:

require 'delegate'


class TicketSeller
  def sellTicket()
    'Here is a ticket'
  end
end


class NoTicketSeller
  def sellTicket()
    'Sorry-come back tomorrow'
  end
end


class TicketOffice < SimpleDelegator
  def initialize
    @seller = TicketSeller.new
    @noseller = NoTicketSeller.new
    super(@seller)
  end
  def allowSales(allow = true)
    __setobj__(allow ? @seller : @noseller)
    allow
  end
end

to = TicketOffice.new
to.sellTicket   »   "Here is a ticket"
to.allowSales(false)    »   false
to.sellTicket   »   "Sorry-come back tomorrow"
to.allowSales(true)     »   true
to.sellTicket   »   "Here is a ticket"

这是另一个很好的解释a-delegate-matter

【讨论】:

  • 您不应该为不同的类型对象重复使用SimpleDelegator,尽管可以重复使用不同的实例the docs 明确提及 #__setobj__:“重要的是要注意,这不会导致 SimpleDelegator 的方法发生变化……您可能只想将委托更改为与原始委托相同类型的对象。”
猜你喜欢
  • 2016-12-13
  • 2012-06-29
  • 2014-04-18
  • 2021-11-21
  • 1970-01-01
  • 2013-08-12
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多