CSC/ECE 517 Fall 2010/ch5 5e mf
The Dependency Injection Pattern
The dependency injection pattern is a design pattern for fully decoupling one class from the instantiation of another class upon which it depends. In this sense, it is similar to the factory and service locator patterns which are also concerned with object creation. The difference between these patterns may be demonstrated through example. Suppose, that Syd has a strategy for making statements about objects illustrated in the following Ruby code.
# A strategy for remarking on things. class Syd def remark if @thing.got_it? puts "I've got a #{@thing}." else puts "I know a #{@thing}." end end end
With this method, Syd can make a statement about any object thing that implements the methods got_it? and to_s. The Bike class shown below is an example.
# An example of a thing upon which to remark. class Bike def to_s "bike" end def got_it? return true end end
However, in order for Syd to use his strategy, he must get ahold of a thing. The simplest way to do this is to instantiate a thing directly.
# An example of direct object instantiation. class Syd def initialize @thing = Bike.new end end
However, now all that Syd can talk about is his bike. This is because, although Syd has a strategy for talking about a wide variety of things, Syd depends on the concrete class Bike for thing creation. A common technique for encapsulating object instantiation is the factory pattern. The example below uses a factory to allow Syd to talk about an array of things.
# An example of the factory pattern. class ThingFactory def initialize # An array of shiny new things. @things = [Bike.new, Cloak.new, Mouse.new, GingerbreadMen.new, Room.new] end def get_random_thing # Return a random thing from the array. @things.sort_by { rand }[0] end end $thing_factory = ThingFactory.new class Syd def initialize # Use the factory to get things @thing = $thing_factory.get_random_thing end end