E
Emiel van de Laar
--mYCpIKhGyMATD0i+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Greetings,
Lately I've been pondering about the trade offs one must make when
implementing classes which maintain internal collections. My question
is, when is it wise to inherit and when to encapsulate. I've attached
some sample Ruby code to demonstrate my thinking. My current issues
are with C# but I believe it to be a general OO issue.
Inheriting from collection classes, i.e. Array, Hash, is simple, fast
and takes relatively little code. However every method available is
exposed to the implementing class. Something we don't always want.
Encapsulation(by association) prevents method pollution by exposing
only what is needed, which gives us more control. For code completion
this is nice because we aren't confronted with an excessive amount of
methods; we only see what is needed.
Another benefit of encapsulation is that you can replace your internal
collection at a later stadium with an alternative implementation,
perhaps for performance reasons. As long as the interface to the
implementing class remains the same you are free to do as you
please internally.
At times though, it can be a pain exposing all the methods we need;
sometimes we need them all. I know Ruby offers us the "method_missing"
feature which I have used a lot, however, as far as I know C# doesn't
offer me such a luxury.
Thanks in advance.
Cheers,
Emiel
--
Emiel van de Laar
PGP pubkey: %finger (e-mail address removed)
--mYCpIKhGyMATD0i+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="zoo.rb"
class Duck
attr_accessor :name
def initialize name
@name = name
end
end
#
# Inheritance
#
class SomeDucks < Array
end
#
# Encapsulation
#
class MoreDucks
def initialize
@ducks = []
end
def << duck
@ducks << duck
end
def shift
@ducks.shift
end
def each
@ducks.each { |duck| yield duck }
end
end
class Zoo
def initialize
@some_ducks = SomeDucks.new
@more_ducks = MoreDucks.new
%w{daffy donald hewey}.each do |name|
@some_ducks << Duck.new(name)
@more_ducks << Duck.new(name)
end
end
def display_ducks
@some_ducks.each { |duck| puts duck.name }
puts "--"
@more_ducks.each { |duck| puts duck.name }
end
end
if __FILE__ == $0
Zoo.new.display_ducks
end
--mYCpIKhGyMATD0i+--
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Greetings,
Lately I've been pondering about the trade offs one must make when
implementing classes which maintain internal collections. My question
is, when is it wise to inherit and when to encapsulate. I've attached
some sample Ruby code to demonstrate my thinking. My current issues
are with C# but I believe it to be a general OO issue.
Inheriting from collection classes, i.e. Array, Hash, is simple, fast
and takes relatively little code. However every method available is
exposed to the implementing class. Something we don't always want.
Encapsulation(by association) prevents method pollution by exposing
only what is needed, which gives us more control. For code completion
this is nice because we aren't confronted with an excessive amount of
methods; we only see what is needed.
Another benefit of encapsulation is that you can replace your internal
collection at a later stadium with an alternative implementation,
perhaps for performance reasons. As long as the interface to the
implementing class remains the same you are free to do as you
please internally.
At times though, it can be a pain exposing all the methods we need;
sometimes we need them all. I know Ruby offers us the "method_missing"
feature which I have used a lot, however, as far as I know C# doesn't
offer me such a luxury.
Thanks in advance.
Cheers,
Emiel
--
Emiel van de Laar
PGP pubkey: %finger (e-mail address removed)
--mYCpIKhGyMATD0i+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="zoo.rb"
class Duck
attr_accessor :name
def initialize name
@name = name
end
end
#
# Inheritance
#
class SomeDucks < Array
end
#
# Encapsulation
#
class MoreDucks
def initialize
@ducks = []
end
def << duck
@ducks << duck
end
def shift
@ducks.shift
end
def each
@ducks.each { |duck| yield duck }
end
end
class Zoo
def initialize
@some_ducks = SomeDucks.new
@more_ducks = MoreDucks.new
%w{daffy donald hewey}.each do |name|
@some_ducks << Duck.new(name)
@more_ducks << Duck.new(name)
end
end
def display_ducks
@some_ducks.each { |duck| puts duck.name }
puts "--"
@more_ducks.each { |duck| puts duck.name }
end
end
if __FILE__ == $0
Zoo.new.display_ducks
end
--mYCpIKhGyMATD0i+--