Bry*_*cke 13 ruby inheritance activerecord ruby-on-rails mixins
A类和B类相同:
class A < ActiveRecord::Base
def foo
puts "foo"
end
end
class B < ActiveRecord::Base
def foo
puts "foo"
end
end
Run Code Online (Sandbox Code Playgroud)
像这样重构与基类之间有什么区别:
class Base < ActiveRecord::Base
def foo
puts "foo"
end
end
class A < Base
end
class B < Base
end
Run Code Online (Sandbox Code Playgroud)
与使用基本模块的情况相比:
module Base
def foo
puts "foo"
end
end
class A < ActiveRecord::Base
include Base
end
class B < ActiveRecord::Base
include Base
end
Run Code Online (Sandbox Code Playgroud)
有一种方式优于另一种方式吗?
小智 24
这两种方法之间存在根本区别,所有其他答案都缺失了,而且是rails的STI实现(单表继承):
http://api.rubyonrails.org/classes/ActiveRecord/Base.html(查找"单表继承"部分)
基本上,如果你像这样重构你的Base类:
class Base < ActiveRecord::Base
def foo
puts "foo"
end
end
class A < Base
end
class B < Base
end
Run Code Online (Sandbox Code Playgroud)
然后,您应该有一个名为"bases"的数据库表,其中包含一个名为"type"的列,其值应为"A"或"B".此表中的列在所有模型中都是相同的,如果您的列只属于其中一个模型,则"基"表将被非规范化.
然而,如果您重构您的Base类,如下所示:
Module Base
def foo
puts "foo"
end
end
class A < ActiveRecord::Base
include Base
end
class B < ActiveRecord::Base
include Base
end
Run Code Online (Sandbox Code Playgroud)
然后将没有表"基地".相反,会有一个表"as"和一个表"bs".如果它们具有相同的属性,则必须在两个表中复制列,但如果存在差异,则不会对它们进行denomarlized.
因此,如果一个优于另一个,是的,但这是特定于您的应用程序.根据经验,如果它们具有完全相同的属性或大的重叠,则使用STI(第一个示例),否则,使用模块(第二个示例).
这两种方法都有效.在决定使用模块或类时,我遇到的问题是类是否适合对象层次结构,或者这些只是我希望重用的方法.如果我只是试图将干扰原因的公共代码分解出来,那听起来像是一个模块.如果真的有一个类适合于自己有意义的层次结构,我会使用一个类.
来自Java背景,我可以选择做出这些决定.
| 归档时间: |
|
| 查看次数: |
5000 次 |
| 最近记录: |