在基类中实现工厂时,从派生类封装工厂方法的正确方法是什么?

时间:2019-03-27 16:14:00

标签: ruby inheritance factory class-method

我正在尝试创建具有注册派生类以从基类进行创建的能力的简单类。但是,我找不到从后代封装此功能的好方法。

类变量对我来说不是一个好主意,因为它们在继承链中随处可见。因此,我尝试对类实例变量进行操作。完美的是,除了register_as

之外,所有类方法都将不可访问
class A
  @registered = {}
  class << self
    def register_as(name)
      A.registered[name] = self
    end

    def known
      A.registered
    end

    protected
    attr_accessor :registered
  end

  def helpful_method
  end

end

class B < A
  class << self
    def reg_trash
      A.registered[:trash] = :trash
    end
  end
  B.register_as :b
end

B.reg_trash
p A.known

但是仍然可以从B类访问已注册的内容。 当前,似乎唯一可行的选择是将A类拆分为专用的Factory类,并且A类仅包含有用的实例方法。 也许可以通过.inherited和.undef_method进行某些操作,不是吗?

1 个答案:

答案 0 :(得分:2)

  

也许可以通过.inherited和.undef_method做某事,不是吗?

是的,有可能。但是就我而言,这个主意闻起来很香-您将打破可替代性。

如果您不希望“派生”类继承父代的行为,那么为什么要使用继承呢?请尝试合成,并仅混合所需的行为。例如,类似这样的方法可能会起作用(非常肮脏的示例,但我希望您有个主意):

class A
  module Registry
    def register_as(name)
      A.register_as(name, self)
    end
  end

  @registered = {}

  def self.register_as(name, klass)
    @registered[name] = klass
  end

  def self.known
    @registered
  end
end

class B
  extend A::Registry
  register_as :b  
end

class C
  extend A::Registry
  register_as :c
end

A.known # => {:b => B, :c => C}