Object-Oriented Programming

Dependency Injection

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Review: Strategy

Define a family of algorithms, encapsulate each one, and make them interchangeable

Strategy lets the algorithm vary independently from clients that use it

Review: Strategy-Applicability

gofstructure

  • Many related classes differ only in behavior
  • Different variants of an algorithm are needed, often for different space/time tradeoffs
  • The algorithm uses data the client should not know about or had dependencies we want to leave out of the client
  • A class has many behaviors, and the operations have multiple conditional statements. Move the switch statement into its own Strategy class

Review: Strategy-Structure

gofstructure

  • All ConcreteStrategy's have the same interface
  • Can change which ConcreteStrategy at any point during runtime

Dependency Injection

  • A broader form of Inversion of Control
  • Once chosen, it doesn't tend to change during runtime
  • The primary purpose is for testing
  • Often extends the interface beyond that of the regular client

Original UML Sequence

diseq1

Original UML Sequence

diseq1

  • Production code
  • Client calls orderProcessor()
  • OrderProcessor uses DBUtilities
  • DBUtilities is hardwired to use SQL to access the database

Original Code

Writing Tests

UML Sequence

diseq2

UML Sequence

diseq2

  • Testing code
  • Client calls orderProcessor()
  • OrderProcessor uses TestDBUtilities
  • TestDBUtilities is hardwired to provide a test case without a Database

Solution

diseq3

Solution

diseq3

  • Both Production and Testing code
  • Client calls orderProcessor()
  • OrderProcessor uses the abstract DBAccessor
  • Which ConcreteStrategy gets called is configured outside of this code

DBAccessor Class Diagram

dbaccessoruml

Client Code

Test Code (Attempt #1)

Test Code Solution

Comparison

dbaccessoruml diseq3

  • Advantages:
  • Decouples code
  • Allows for rich testing
  • Frameworks for creating mock objects
  • Each class has a more direct purpose
  • Disadvantages:
  • Creates more classes
  • Obliged to do better testing
  • Introduces a controlled increase in complexity