M
Manuel Kiessling
Hello everyone,
I'm quite new to Ruby, with a strong background in PHP.
I had a great time finding my way around in Ruby, because it is a =
fantastic language. However, right now I'm a bit stuck regarding the =
issue of loose coupling / inversion of control / writing testable units.
I spent the last days reading a lot of articles, but feel sort of =
puzzled now.
As far as I can see, there are several approaches. I will start with my =
own, which probably is the weirdest of all - feel free to dissect it.
Let's say I have 2 classes, SomeClass and OtherClass, and SomeClass =
depends on OtherClass, because in some cases it needs to create an =
instance of this class, and in others it doesn't, which is why we can't =
simply pass an already created instance of OtherClass into SomeClass.
This is how it could be done using no DI at all:
class SomeClass
def do_something(a, b)
c =3D a + b
if (c > 5) then
o =3D OtherClass.new()
o.log(c)
end
end
end
s =3D SomeClass.new
s.do_something(1, 2)
Which of course doesn't allow me to replace "o" with a mock object for =
testing etc.
This is how it might be done using the fact that ruby classes are =
objects (my approach):
class SomeClass
def do_something(a, b, logObjectClass)
c =3D a + b
if (c > 5) then
o =3D logObjectClass.new()
o.log(c)
end
end
end
s =3D SomeClass.new
s.do_something(1, 2, OtherClass)
This way, I can inject into SomeClass which class to actually use - as =
long as whatever I pass using logObjectClass supports the expected =
protocol, all should be fine. I could easily inject a mock log object =
for my tests.
But, I couldn't find any articles recommending this approach, and I =
guess there's a reason for that...
Another solution which seems to be more along "the Ruby way" is this:
class SomeClass
def do_something(a, b)
c =3D a + b
if (c > 5) then
o =3D get_logger()
o.log(c)
end
end
def get_logger()
OtherClass.new()
end
end
// Replacing with mock object:
s =3D SomeClass.new
def s.get_logger()
MockLoggerClass.new()
end
s.do_something(1, 2)
Could someone help me to understand which approach is better, and why? =
Or if maybe I'm getting it completely wrong?
Thanks in advance,
--=20
Manuel
I'm quite new to Ruby, with a strong background in PHP.
I had a great time finding my way around in Ruby, because it is a =
fantastic language. However, right now I'm a bit stuck regarding the =
issue of loose coupling / inversion of control / writing testable units.
I spent the last days reading a lot of articles, but feel sort of =
puzzled now.
As far as I can see, there are several approaches. I will start with my =
own, which probably is the weirdest of all - feel free to dissect it.
Let's say I have 2 classes, SomeClass and OtherClass, and SomeClass =
depends on OtherClass, because in some cases it needs to create an =
instance of this class, and in others it doesn't, which is why we can't =
simply pass an already created instance of OtherClass into SomeClass.
This is how it could be done using no DI at all:
class SomeClass
def do_something(a, b)
c =3D a + b
if (c > 5) then
o =3D OtherClass.new()
o.log(c)
end
end
end
s =3D SomeClass.new
s.do_something(1, 2)
Which of course doesn't allow me to replace "o" with a mock object for =
testing etc.
This is how it might be done using the fact that ruby classes are =
objects (my approach):
class SomeClass
def do_something(a, b, logObjectClass)
c =3D a + b
if (c > 5) then
o =3D logObjectClass.new()
o.log(c)
end
end
end
s =3D SomeClass.new
s.do_something(1, 2, OtherClass)
This way, I can inject into SomeClass which class to actually use - as =
long as whatever I pass using logObjectClass supports the expected =
protocol, all should be fine. I could easily inject a mock log object =
for my tests.
But, I couldn't find any articles recommending this approach, and I =
guess there's a reason for that...
Another solution which seems to be more along "the Ruby way" is this:
class SomeClass
def do_something(a, b)
c =3D a + b
if (c > 5) then
o =3D get_logger()
o.log(c)
end
end
def get_logger()
OtherClass.new()
end
end
// Replacing with mock object:
s =3D SomeClass.new
def s.get_logger()
MockLoggerClass.new()
end
s.do_something(1, 2)
Could someone help me to understand which approach is better, and why? =
Or if maybe I'm getting it completely wrong?
Thanks in advance,
--=20
Manuel