Disadvantages of Dependency Inversion?

Nowadays, DI (Dependency Inversion) is one of the widely used design
pattern.
It provides several benefits, such as (1) loose coupling between
component (2) effective and easy testing (component testing or unit
testing)

What are the drawbacks or disadvantages of using DI?

Thank you very much for your answer in advance.

On Jun 8, 2007, at 1:55 PM, [email protected] wrote:

Nowadays, DI (Dependency Inversion) is one of the widely used design
pattern.
It provides several benefits, such as (1) loose coupling between
component (2) effective and easy testing (component testing or unit
testing)

What are the drawbacks or disadvantages of using DI?

I’m not anti-DI, but I think one disadvantage is that it can be hard
to follow the code. You see a method in a class, you know something
is calling it to inject a value, but you’re not sure where it happens
or what value is injected.

On Jun 8, 2007, at 11:55, [email protected] wrote:

Nowadays, DI (Dependency Inversion) is one of the widely used design
pattern.
It provides several benefits, such as (1) loose coupling between
component (2) effective and easy testing (component testing or unit
testing)

What are the drawbacks or disadvantages of using DI?

Ruby is dynamic enough that you probably don’t need it.

I can build a duck-type object for testing very easily. I can inject
these duck-type objects into classes that at test-time very easily.
See the ar_mailer gem for an example.

On 8 Jun 2007, at 21:05, Mark V. wrote:

I’m not anti-DI, but I think one disadvantage is that it can be
hard to follow the code. You see a method in a class, you know
something is calling it to inject a value, but you’re not sure
where it happens or what value is injected.

Actually Dependency Injection comes from less dynamic languages where
you have the notion of interfaces, etc.

In Ruby though this does not exist at such a level (like Smalltalk an
the like), but it is still advantageous to use in most cases.

Dependency Injection follows the Hollywood principle: “You won’t call
us, we will call you”.

Let’s suppose you have a method that calls a method from a command
(it doesn’t matter much what this command does; and sure, the example
is pretty silly). You could create an instance of the particular
command in the method like:

class CommandCaller

def initialize
@command = MySuperCommand.new
end

def call_command()
@command.execute
end
end

or, using a DI approach you would pass the fully initialized command
itself to the method:

class CommandCaller

def initialize(command)
@command = command
end

def call_command(command)
command.execute
end
end

Obviously one of the strengths of DI (or IoC; Inversion of Control)
is that you normally wire those objects dynamically on startup of
your application…

I hope that helped a bit.

Cheers,


Enrique Comba R.
[email protected]

I always thought Smalltalk would beat Java, I just didn’t know it
would be called ‘Ruby’ when it did.
– Kent Beck

Warning - I am pretty skeptical about DI

DI one of the most most widely discussed design patterns, but
probably not than most widely used.
My opinion is that, as with SOA, web services, EJBs, XML, Corba the
idea moved from “sounds interesting”
to “widely accepted without question” without a body of compelling
data that pointed to clear business
benefit. My hunch is this is partly do to the “this looks cool”
effect impressing us technologists.

Given this, I’d say the drawbacks of DI are:

uncertain value proposition
less explicit than the ServiceLocater pattern and thus harder to
debug/comprehend
not a fit for Ruby
canonical implementation (Spring) is a bit fat and overcomplex
other Java implementations are sparsely documented and have uncertain
viability
not pragmatic

  • Peter

On Jun 8, 2007, at 2:55 PM, [email protected] wrote:

Peter B.
[email protected]
917 445 5663

[email protected] wrote:

Nowadays, DI (Dependency Inversion) is one of the widely used design
pattern.
It provides several benefits, such as (1) loose coupling between
component (2) effective and easy testing (component testing or unit
testing)

What are the drawbacks or disadvantages of using DI?

I think the best article on the topic is this by Martin F.:

He does a good job of analyzing the pros and cons. And basically I agree
with him; DI is useless unless you write 3rd party packages.

Daniel

Peter B. wrote:

Given this, I’d say the drawbacks of DI are:

uncertain value proposition
less explicit than the ServiceLocater pattern and thus harder to
debug/comprehend
not a fit for Ruby
canonical implementation (Spring) is a bit fat and overcomplex
other Java implementations are sparsely documented and have uncertain
viability
not pragmatic

It’s pretty easy to build a lightweight DI framework in ruby, taking
advantage dynamic language features like method_missing.[1]

But I rarely find the need to use it, even in relatively complex
programs.

However, ruby has some DI-like idioms that are very useful, with no need
for a framework. A somewhat imaginary variant on a very common example:

class Foo

map host to addr

def addr_map
@addr_map ||= {}
end

def session
@session ||= Hash.new do |hsh,host|
hsh[host] = Session.new(addr_map[host])
end
end

def send_to_host(msg, host)
session[host].send(msg)
end

end

[1] For example:

http://raa.ruby-lang.org/project/mindi/

On Jun 8, 10:47 pm, Daniel DeLorme [email protected] wrote:

I think the best article on the topic is this by Martin F.:Inversion of Control Containers and the Dependency Injection pattern
He does a good job of analyzing the pros and cons. And basically I agree
with him; DI is useless unless you write 3rd party packages.

For a long time I felt DI was very interesting and potentially very
useful, but I never could quite get mileage out of it. I think I
finally figured out why: DI is just a contrived codification of an
essentially simple top-level construction layer. Here’s what I mean.
Reading Jim’s OSCON 2005 - Dependency Injection - Cover, he gives this
basic example:

magic_lamp = DIM::Container.new

magic_lamp.register(:warmer) { |c|
Warmer.new(c.pot_sensor, c.heater)
}

magic_lamp.register(:pot_sensor) { |c|
PotSensor.new(c.pot_sensor_io_port)
}

magic_lamp.register(:heater) { |c|
Heater.new(c.heater_io_port)
}

Hardware IO Port Assignments

magic_lamp.register(:pot_sensor_io_port) { 0x08F0 }
magic_lamp.register(:heater_io_port) { 0x08F1 }

magic_lamp.register(:coffee_maker) { |c|
MarkIV::CoffeeMaker.new(c.boiler, c.warmer)
}

coffee_maker = magic_lamp.coffee_maker

The magic of the lamp seems quite wonderful, granting us the
flexibility of indirection in lew of a little complexity. And though
Jim goes on to tell us that DI isn’t so important for Ruby because we
can dynamically define constants instead (eg. Heater =
Mocking::Heater), I think that’s missing the point a bit. Somewhere
along the line the constants must be “injected” too. No, the real lack
luster of the genie’s lamp comes from a slight of hand, because no
magic is actually required.

class JustALamp

def warmer
  Warmer.new(pot_sensor, heater)
end

def pot_sensor
  PotSensor.new(pot_sensor_io_port)
end

def heater
  Heater.new(heater_io_port)
end

# Hardware IO Port Assignments
def pot_sensor_io_port
  0x08F0
end

def heater_io_port
  0x08F1
end

def coffee_maker
  MarkIV::CoffeeMaker.new(boiler, warmer)
end

def self.coffee_maker
  new.coffee_maker
end

end

coffee_maker = JustALamp.coffee_maker

So it seems to me that the heart of DI is really nothing more than a
good programming practice --using an control layer. Of course, I’m no
DI expert, so maybe I’m missing something. But this certainly helps to
explain why all this magic never seemed to pane out for me in
practice.

(BTW, a nice side-effect of this simplification, JustALamp can be
easily subclassed.)

T.

On 14.06.2007 12:04, Trans wrote:

basic example:
Isn’t DI just about callbacks? If that was the case DI is all over Ruby
code - every block is an anonymous callback function.

Kind regards

robert

On 6/14/07, Robert K. [email protected] wrote:

useful, but I never could quite get mileage out of it. I think I
robert
DI just about callbacks? You need to go read up on DI.

Dependency Injection is all about keeping components as uncoupled as
possible. This usually means that each object takes in it’s constructor,
or
has setter methods for, the objects it needs to function. E.g.:

class MyClass < …
def initialize(logger, my_worker, …)
@logger = logger
@my_worker = worker
end
end

This makes testing MyClass extremely easy (on top of this being Ruby
anyway)
and very extensible.

So yeah, Dependency Injection itself has nothing to do with callbacks.

Jason