Noob在这里,寻求帮助干掉这个。我们假设module DoAThing
看起来像这样:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::EXPORT_DEFAULTS)
end
end
end
然后我想添加一个完全相同的模块,除了生成报告之外,我想传递一个不同的常量,所以像这样:
module DoASlightDifferentThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
end
end
end
我怎样才能优雅地干这个?字面上,我需要做的就是传递一个不同的常量,即我想交换EXPORT_DEFAULTS
DIFFERENT_EXPORT_DEFAULTS
答案 0 :(得分:4)
这通常被称为“依赖注入”,互联网上有很多关于这个主题的文章。主要方法是在调用#perform
方法中接受一个参数:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(report)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
end
end
并称之为:
DoManyDifferentThings::ExportNames.perform(
::ClassAwesome::EXPORT_DEFAULTS
)
报告方法是否应该具有预定义的签名,可以使用类继承:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(self.class.constant_get('REPORT'))
end
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_1
end
class ExportNames1 < ExportNames
REPORT = ::ClassAwesome::EXPORT_DEFAULTS_2
end
end
或者,作为替代方案,可以声明一个方法在后代中被覆盖:
module DoManyDifferentThings
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(report)
end
protected
def report
raise "DO NOT CALL ME DIRECTLY"
end
end
class ExportNames1 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_1
end
end
class ExportNames2 < ExportNames
def report
::ClassAwesome::EXPORT_DEFAULTS_2
end
end
end
答案 1 :(得分:2)
您可以将此常量作为参数移动,也可以使用ihneritance。
提供默认值作为参数
module DoAThing
class ExportNames
def initialize(names, limit = 1000, defaults = ::ClassAwesome::EXPORT_DEFAULTS)
@names = names
@limit = limit
@defaults = defaults
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(@defaults)
end
end
end
不是调用DoASlightDifferentThing :: ExportNames,而是执行:
DoAThing::ExportNames.perform_now(names, 1000, ::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)
<强> Ihneritance 强>
或者您可以使用ihneritance添加一个将被覆盖的默认方法:
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(defaults)
end
def defaults
::ClassAwesome::EXPORT_DEFAULTS
end
end
end
module DoASlightDifferentThing
class ExportNames < DoAThing::ExportNames
def defaults
::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS
end
end
end
答案 2 :(得分:0)
如果两个类的命名空间可以相同,那么通过重写这样的代码来清理代码
module DoAThing
class ExportNames
def initialize(names, limit = 1000)
@names = names
@limit = limit
end
def perform(value)
awesome = ::ClassAwesome.sort_names(names, per_page: @limit)
awesome.generate_export(value)
end
end
end
现在我打电话给
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::EXPORT_DEFAULTS)
DoAThing::ExportNames.new('your names').perform(::ClassAwesome::DIFFERENT_EXPORT_DEFAULTS)