多个类

时间:2015-06-26 06:31:53

标签: ruby-on-rails ruby oop trailblazer

我有以下情况:

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

我有很多这种情况。就像,我的应用程序中有大约40个IdenticalDescendent类。我喜欢这种模式,它允许我调用A::IdenticalDescendentB::IdenticalDescendent或其他任何内容来访问不同域中的某些相关行为(由AB指定)。出于原因,我不能通过重新设计行为聚类来完全抽象问题。

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

class A < CommonParent
  include CommonBehaviour

  ... some code ...
end

module CommonBehaviour
  ... what ...
end

我无法弄清楚如何编写CommonBehaviour以允许IdenticalDescendent从包含类中继承。

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

3 个答案:

答案 0 :(得分:1)

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

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

这给了我想要的设计!

答案 1 :(得分:0)

我相信您可以使用回调(挂钩)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会触发inherited klass => Descendent,导致创建Descendent的匿名子类等,导致“堆栈级别太深异常“。

答案 2 :(得分:-1)

我建议分离后代类和方法生成。当然,你可以把所有东西都扔进class_eval区块(这将会积极地发现)。

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

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

module CommonDescendantMethods
end

class A < CommonParent
  extend CommonDescendants
end