我将我的问题抽象为以下情况。
# /somewhere/build_ability/car.rb
module BuildAbility
module Car
def build_car
build_component
end
def build_component
# Specific designed for build car, not common used
# Totally different from build_component in BuildAbility::Ship
end
end
end
# /somewhere/build_ability/ship.rb
module BuildAbility
module Ship
def build_ship
build_component
end
def build_component
# Specific designed for build ship, not common used
# Totally different from build_component in BuildAbility::Car
end
end
end
# /somewhere/omni_factory.rb
class OmniFactory
include BuildAbility::Car
include BuildAbility::Ship
def build_component
# common used method
end
end
将BuildAbility::Car
添加到OmniFactory
的目的是介绍build_car
,而不想介绍build_component
。
build_component
中的BuildAbility::Car
是专为build_car
设计的,它仅适用于build_car
,在其他地方无用。因此,当OmniFactory
包含BuildAbility::Car
时,无需引入build_component
。
BuildAbility::Ship
中的相同情况。
那么我应该将build_component
放在car.rb
中以达到目的?
我认为这可能发生在宝石中,宝石可能不希望某些低级基本功能暴露给用户,并且只在gem文件中使用。
以下代码是解决方案之一,就像关闭一样,但我认为这种方式太难看了,还有其他一些解决方案吗?
# /somewhere/build_ability/car.rb
module BuildAbility
module Car
build_component = lambda {
# Specific designed for build car, not common used
# Totally different from build_component in BuildAbility::Ship
}
define_method :build_car do
build_component.call
end
end
end
# /somewhere/build_ability/ship.rb
module BuildAbility
module Ship
build_component = lambda {
# Specific designed for build ship, not common used
# Totally different from build_component in BuildAbility::Car
}
define_method :build_ship do
build_component.call
end
end
end
# /somewhere/omni_factory.rb
class OmniFactory
include BuildAbility::Car
include BuildAbility::Ship
def build_component
# common used method
end
end
答案 0 :(得分:3)
您可以将build_component
作为模块方法,当您include
模块时,不会继承该模块。
这是一个有效的例子:
# /somewhere/build_ability/car.rb
module BuildAbility
module Car
def build_car
Car.build_component
end
def self.build_component
p "car"
end
end
end
# /somewhere/build_ability/ship.rb
module BuildAbility
module Ship
def build_ship
Ship.build_component
end
def self.build_component
p "ship"
end
end
end
# /somewhere/omni_factory.rb
class OmniFactory
include BuildAbility::Car
include BuildAbility::Ship
def build_component
p "omnifactory"
# common used method
end
end
OmniFactory.new.build_component
OmniFactory.new.build_car
OmniFactory.new.build_ship
输出:
"omnifactory"
"car"
"ship"
通过这种方式,OmniFactory
build_component
方法不会干扰任何事情。此外,self.build_component
中的BuildAbility::Car
方法不会包含在OmniFactory
中。
另一种方法(有点脏),让build_component
成为一个类的成员。
# /somewhere/build_ability/car.rb
module BuildAbility
module Car
def build_car
CarStrategy.build_component
end
class CarStrategy
def self.build_component
p "car"
end
end
end
end
但是,对我来说,这个解决方案看起来并不像模块方法那么简单明了。