多个相同的继承模式 类

Identical inheritance pattern in multiple classes

我有以下情况:

class A < CommonParent
  ... some code ...

  class IdenticalDescendent < self
    identical_statement_0
    identical_statement_1
  end
end

class B < CommonParent
  ... some other code ...

  class IdenticalDescendent < self
    identical_statement_0
    identical_statement_1
  end
end

这种情况我经常遇到。比如,我的应用程序中大约有四十个 IdenticalDescendent classes。我喜欢这个模式,它允许我调用 A::IdenticalDescendentB::IdenticalDescendent 或其他任何东西来访问不同域中的某些相关行为(由 AB 指定)。由于某些原因,我不能通过重新设计行为聚类来完全抽象问题。

所以我的问题的一般形式是如何在所有这些中自动生成 IdenticalDescendent。 CommonParent 的后代没有调用此模式,因此该操作可能不应该在那里发生。我想它应该发生在 mixin 或其他东西中,但我发现如果我只是尝试做:

class A < CommonParent
  include CommonBehaviour

  ... some code ...
end

module CommonBehaviour
  ... what ...
end

我不知道如何编写 CommonBehaviour 以允许 IdenticalDescendent 从包括 class.

帮助我 Whosebug,你是我唯一的希望。

我建议将后代 class 和方法生成分开。当然,您可以将所有东西都扔进 class_eval 方块中(这肯定会散发出臭味)。

类似于以下内容(完全未经测试)

module CommonDescendants
  Descendant = Class.new(self) do 
    include CommonDescendantMethods
  end
end

module CommonDescendantMethods
end

class A < CommonParent
  extend CommonDescendants
end

我一直在寻找的答案是在 self.included 回调中对 Class.new 使用块表示法。我现在有这个:

module CommonDescendant
  def self.included(base)
    descendant_class = Class.new(base) do
      ... put my desired common behavior here ...
    end

    base.const_set :Descendant, descendant_class
  end
end

class A
  include CommonDescendant

  ... unique behavior ...
end

class B
  include CommonDescendant

  ... unique other behavior ...
end

这给了我们我想要的设计!

我相信您可以使用回调(挂钩)使您的模式自动化 Class#inherited:

class CommonParent
  def self.inherited(klass)
    return unless klass.superclass == CommonParent
    klass.const_set(:Descendent, Class.new(klass) do
      def x
        puts "in x"
      end
    end)
  end
end

class A < CommonParent
  def a
    puts "in a"
  end   
end

d = A::Descendent.new #=> #<A::Descendent:0x007f99620172e8> 
d.a                   #   in a
d.x                   #   in x

class B < CommonParent
  def b
    puts "in b"
  end
end

d = B::Descendent.new #=> #<B::Descendent:0x007f99618b18f0> 
d.b                   #   in b
d.x                   #   in x
d.a                   #=> NoMethodError:... (as expected)

请注意,没有:

return unless klass.superclass == CommonParent

A::Descendent 的创建将触发 inheritedklass => Descendent,导致创建 Descendent 的匿名子类,等等,导致 "stack level too deep exception."