A question similar to this has been asked before, but I am asking specifically about using composition as an alternative to using module mixins.
class Helper
def do_somthing
end
end
If I need to 'use' a class but not inherit it , I would simply compose it and use it.
class MyStuff
def initialize
helper = Helper.new
helper.do_something
end
end
Why would I like to create a module for this:
module Helper
def do_something
end
end
class MyStuff
include Helper
end
The only difference I see is there wont be many Helper
objects lying around if I use modules. But I don't see anything with more objects lying around vs less bigger objects.
Moreover, I don't know if I need to subclass it in the future. So how do I decide if the users of my library want to use a module mixin, or would want to use composition?
When the relationship between Helper
and the MyStuff
class is one of ownership, use composition. This is known as a "has-a" relationship. For example, let's say you have Person
class and a Car
class. You would use composition because a person has a car:
class Person
def initialize
@car = Car.new
end
end
class Car
def accelerate
# implementation
end
end
When Helper
"acts like" MyStuff
, use a module mixin. Helper
, in this case, takes on the role of MyStuff
. This is a bit different than a "is-a" relationship, which would imply that you should use traditional inheritance. For example, let's say we have a Person
class and a Sleeper
module. A person takes on the role of a sleeper sometimes, but so do other objects--instances of Dog
, Frog
, or maybe even Computer
. Each of those other classes represent something that can go to sleep.
module Sleeper
def go_to_sleep
# implementation
end
end
class Person
include Sleeper
end
class Computer
include Sleeper
end
Sandi Metz's Practical Object-Oriented Design in Ruby is an excellent resource for these topics.
That is a matter of “Duck Typing”. If you want your class to behave like a Helper
, you do include
. Whether you are to encapsulate Helper
behaviour, the right choice is require
.
Mixing Enumerable
in, you give your class the huge load of methods by implementing the only each
method. Wrapping Array
you may hide iteration from others and use it for holding your data only. And vice versa.
Modules mixin is more like multiple inheritance, so follow the usual inheritance vs composition rule — is-a or has-a. By the way, it's include Helper
, not require 'Helper'
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With