多个相同的继承模式 类
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::IdenticalDescendent
或 B::IdenticalDescendent
或其他任何东西来访问不同域中的某些相关行为(由 A
或 B
指定)。由于某些原因,我不能通过重新设计行为聚类来完全抽象问题。
所以我的问题的一般形式是如何在所有这些中自动生成 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
的创建将触发 inherited
和 klass => Descendent
,导致创建 Descendent
的匿名子类,等等,导致 "stack level too deep exception."
我有以下情况:
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::IdenticalDescendent
或 B::IdenticalDescendent
或其他任何东西来访问不同域中的某些相关行为(由 A
或 B
指定)。由于某些原因,我不能通过重新设计行为聚类来完全抽象问题。
所以我的问题的一般形式是如何在所有这些中自动生成 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
的创建将触发 inherited
和 klass => Descendent
,导致创建 Descendent
的匿名子类,等等,导致 "stack level too deep exception."