如何在Ruby中专门化一个只能通过工厂实例化的类?

时间:2013-11-24 14:26:44

标签: ruby inheritance instantiation factory

我有一个来自库的 L 类,只能通过工厂方法 L.factory 进行实例化。我希望能够通过继承来专门化它。所以我们有:

class L
  attr_accessor :g

  def self.factory
    l = L.new
    l.g = "magic"
    l
  end
end

class S < L
  def self.new
    allocate
    l = L.factory
    # is there a way to return a class S object here with data from l?
  end

  def g2
    "my #{g}"
  end
end

s = S.new
s.g       #==>  "magic"
s.g2      #==>  fails because s.class is L

2 个答案:

答案 0 :(得分:1)

在我看来,如果你不能修改L中的代码,你可以做的就是从L到S的丑陋“复制和粘贴”代码。由于代码重复,它很难看。

class L
  attr_accessor :g

  def self.factory
    l = L.new
    l.g = "magic"
    l
  end
end

class S < L
  def self.new
    obj = allocate
    obj.g = "magic" #copy and paste from L
    obj
  end

  def g2
    "my #{g}"
  end
end

s = S.new
s.g       #==>  "magic"
s.g2      #==>  "my magic"

更新

@dbenhur确实提出了一个很好的建议。以下代码是根据他的建议实施的。

require 'delegate'

class L
  attr_accessor :g

  def self.factory
    l = L.new
    l.g = "magic"
    l
  end
end

class S < SimpleDelegator
  def initialize
    super(L.factory)
  end

  def g2
    "my #{g}"
  end
end

s = S.new
p s.g       #==>  "magic"
p s.g2      #==>  "my magic"

答案 1 :(得分:0)

要使这种东西有效,你不能对类名进行硬编码。

class Parent
  def self.factory
    allocate
  end
end

class Child < Parent
  def self.new
    factory
  end
end

p Parent.new
p Child.new