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.

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 1:55 PM, sweetchuck74@gmail.com 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 Jun 8, 2007, at 11:55, sweetchuck74@gmail.com 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?

--
Poor workers blame their tools. Good workers build better tools. The best
workers get their tools to do the work for them. -- Syndicate Wars

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, sweetchuck74@gmail.com 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?

Thank you very much for your answer in advance.

Peter Booth
peter_booth@mac.com
917 445 5663

sweetchuck74@gmail.com 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 Fowler:

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

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,

···

On 8 Jun 2007, at 21:05, Mark Volkmann wrote:

On Jun 8, 2007, at 1:55 PM, sweetchuck74@gmail.com 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.

----
Enrique Comba Riepenhausen
ecomba@mac.com

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

Peter Booth 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/

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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 Jun 8, 10:47 pm, Daniel DeLorme <dan...@dan42.com> wrote:

I think the best article on the topic is this by Martin Fowler: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.

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 14.06.2007 12:04, Trans wrote:

On Jun 8, 10:47 pm, Daniel DeLorme <dan...@dan42.com> wrote:

I think the best article on the topic is this by Martin Fowler: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:

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

···

On 6/14/07, Robert Klemme <shortcutter@googlemail.com> wrote:

On 14.06.2007 12:04, Trans wrote:
> On Jun 8, 10:47 pm, Daniel DeLorme <dan...@dan42.com> wrote:
>> I think the best article on the topic is this by Martin Fowler:
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:

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