DelegateClass vs Class Inheritance in Ruby
DelegateClass vs Class Inheritance in Ruby
有人可以提供一些关于何时通过 DelegateClass
(例如 Seller < DelegateClass(Person)
)使用委托以及何时使用 class 继承(例如 Seller < Person
)的见解吗? ruby?
class Seller < DelegateClass(Person)
def sales
...
end
end
class Seller < Person
def sales
...
end
end
当我查看 Rails 上 Github 上的 Ruby 来源时,我发现了很多 uses of DelegateClass
.
代表根据上下文为 Person
的不同行为建模。例如同一个人在一种情况下可能是卖方,在另一种情况下可能是买方。继承更加严格:Bear
和 Tiger
继承自 Animal
,但是 Animal
的实例永远不需要有时表现得像 Bear
,有时表现得像像 Tiger
。 Animal
的后代实例是其中之一。
有一些差异可以帮助深入了解使用哪种方法。
1) 您可以安全地委托给基元(例如 String),但不能总是安全地从它们继承
如果您在 Hash
或 String
或 Fixnum
之上构建,您使用 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
subclasses 期望委托 class 的实例作为 new
[=41 的参数=]
这可能会使“subclass”变得棘手 class您要交给图书馆代码。例如,这是一种相当普遍的做法,无法立即使用 DelegateClass
:
class MyLogger < DelegateClass(ActiveSupport::Logger); end
Foo::ThirdParty::Library.configure do |c|
c.logger = MyLogger # no good
end
这行不通,因为我们的库希望像大多数记录器一样运行并且不带参数进行实例化。这可以通过定义 initialize
并创建 ActiveSupport::Logger
的实例来解决,但在这种情况下可能不是正确的解决方案。
有人可以提供一些关于何时通过 DelegateClass
(例如 Seller < DelegateClass(Person)
)使用委托以及何时使用 class 继承(例如 Seller < Person
)的见解吗? ruby?
class Seller < DelegateClass(Person)
def sales
...
end
end
class Seller < Person
def sales
...
end
end
当我查看 Rails 上 Github 上的 Ruby 来源时,我发现了很多 uses of DelegateClass
.
代表根据上下文为 Person
的不同行为建模。例如同一个人在一种情况下可能是卖方,在另一种情况下可能是买方。继承更加严格:Bear
和 Tiger
继承自 Animal
,但是 Animal
的实例永远不需要有时表现得像 Bear
,有时表现得像像 Tiger
。 Animal
的后代实例是其中之一。
有一些差异可以帮助深入了解使用哪种方法。
1) 您可以安全地委托给基元(例如 String),但不能总是安全地从它们继承
如果您在 Hash
或 String
或 Fixnum
之上构建,您使用 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
subclasses 期望委托 class 的实例作为 new
[=41 的参数=]
这可能会使“subclass”变得棘手 class您要交给图书馆代码。例如,这是一种相当普遍的做法,无法立即使用 DelegateClass
:
class MyLogger < DelegateClass(ActiveSupport::Logger); end
Foo::ThirdParty::Library.configure do |c|
c.logger = MyLogger # no good
end
这行不通,因为我们的库希望像大多数记录器一样运行并且不带参数进行实例化。这可以通过定义 initialize
并创建 ActiveSupport::Logger
的实例来解决,但在这种情况下可能不是正确的解决方案。