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

问题描述 投票:1回答:1

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

类变量对我来说是一个坏主意,因为它们在继承链中的任何地方都可用。所以我尝试用类实例变量做一些事情。完美的是,除了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做点什么,不是吗?

ruby inheritance factory class-method
1个回答
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}
© www.soinside.com 2019 - 2024. All rights reserved.