This isn't a really good example of composition because the GUI doesn't make use of internal state. If you did something like this, that would be a more clear case of composition:
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
With this code, each instance of computer has its own instance of GUI, with its own bound behavior (the value of the prompt text).
This could also be done with modules, as follows:
module GUI
def get_input
puts @prompt
gets.chomp
end
end
class Computer
include GUI
def initialize
@prompt = "enter text"
end
end
As to why the class implementation might be considered better than the module one - well, there are pros and cons. With the module, the Computer class can be shorter and doesn't need to define the get_input
method itself because it's included from the mixin. However, the class approach is more explicit and probably more maintainable in the long run.
There are at least two reasons for this. First of all, GUI defines its dependencies explicitly. Initialize will raise an error if the wrong number of arguments are passed. But instance variables will be nil
if they are unset, so if GUI gets used somewhere else, that detail could be missed. Second, defining wrapper methods like def get_input; @ui.get_input; end;
might seem redundant but can actually be useful sometimes. It gives you a way to make Computer#get_input
slightly different than GUI#get_input
, if you so desired.
Bringing back your original example here. Like I said, it's not really a good use of composition. Since the GUI class has no dependencies or internal state, it can be self-contained and doesn't need to be instantiated either:
class GUI
def self.get_input
gets.chomp
end
end
class Computer
def get_input
GUI.get_input
end
end
Note that you can change the class GUI
to a module and it would have the same effect. You could also use module_method
instead of def self.
as described here: https://idiosyncratic-ruby.com/8-self-improvement.html