许多Ruby组合的例子都是这样的:
class GUI
def get_input
gets.chomp
end
end
class Computer
def initialize
@ui = GUI.new
end
def get_input
@ui.get_input
end
end
但是,我认为这可能是
module GUI
module_function
def get_input
gets.chomp
end
end
class Computer
def initialize
@ui = GUI
end
def get_input
@ui.get_input
end
end
太。 那么为什么我们在这里使用Classes而不是模块?
答案 0 :(得分:0)
这不是一个非常好的组合示例,因为GUI没有使用内部状态。如果你做了这样的事情,那将是一个更明确的构成案例:
class GUI
def initialize(prompt)
@prompt = prompt
end
def get_input
puts @prompt
gets.chomp
end
end
class Computer
def initialize
@ui = GUI.new("enter text")
end
def get_input
@ui.get_input
end
end
使用此代码,每个计算机实例都有自己的GUI实例,具有自己的绑定行为(提示文本的值)。
这也可以通过模块完成,如下所示:
module GUI
def get_input
puts @prompt
gets.chomp
end
end
class Computer
include GUI
def initialize
@prompt = "enter text"
end
end
至于为什么类实现可能被认为比模块更好 - 嗯,有利有弊。使用该模块,计算机类可以更短,并且不需要定义get_input
方法本身,因为它包含在mixin中。但是,从长远来看,类方法更明确,可能更易于维护。
至少有两个原因。首先,GUI明确定义了它的依赖关系。如果传递了错误的参数数量,Initialize将引发错误。但是如果未设置实例变量将为nil
,因此如果在其他地方使用GUI,则可能会错过该详细信息。其次,定义像def get_input; @ui.get_input; end;
这样的包装器方法似乎是多余的,但实际上有时可能很有用。如果您愿意,它可以让您Computer#get_input
与GUI#get_input
略有不同。
在此处回顾您的原始示例。就像我说的那样,它并没有很好地利用构图。由于GUI类没有依赖关系或内部状态,因此它可以是自包含的,也不需要实例化:
class GUI
def self.get_input
gets.chomp
end
end
class Computer
def get_input
GUI.get_input
end
end
请注意,您可以将class GUI
更改为模块,它会产生相同的效果。您也可以使用module_method
代替def self.
,如下所述:https://idiosyncratic-ruby.com/8-self-improvement.html