Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dependency Injection and Dependency Inversion in PHP

Dependency Injection and Dependency Inversion in PHP

Dependency Injection and Dependency Inversion are important tools for writing testable and reusable code. They are available in any object oriented language and PHP is no exception. In this talk we will look at both Dependency Injection and the Dependency Inversion Principle, how they fit in with SOLID, and why they should be used when writing object oriented code. How are objects wired together? What is an object graph? Is a Dependency Injection Container the right way forward? Can we do this automatically, and are there any patterns or reusable components available to help us achieve reusable and decoupled code? These are some of the topics covered in this talk from both a theoretical and a practical standpoint. Walking out of the room you should understand why dependency injection is so heavily advocated in programming and how you can use it to write awesome, decoupled code in PHP.

James Mallison

October 03, 2015
Tweet

More Decks by James Mallison

Other Decks in Technology

Transcript

  1. Dependency Injection and
    Dependency Inversion in PHP
    @J7mbo

    View Slide

  2. Your goal on a project?

    View Slide

  3. Professional Integrity

    View Slide

  4. “I want a plumber who takes a pride in his work, who
    bothers to learn and gain experience, who takes what he
    does seriously”
    “I expect to pay extra for expertise, but it's a wise
    investment compared to hiring a cowboy plumber and
    having to pay later to fix up the botch job he left me with”

    View Slide

  5. “Integrity is "doing the right thing even
    when no one is looking", and I see
    Software Craftsmanship as striving for
    integrity in the systems we create.”
    David Starr (elegantcode.com)

    View Slide

  6. View Slide

  7. A little bit about me…

    View Slide

  8. OOP, DI, DiP, IoC, DIC, SOLID, WTF

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. Object Instantiation

    View Slide

  18. Object Instantiation
    Http
    Request

    View Slide

  19. Object Instantiation
    Http
    Request
    Disgusting
    DOM Searching

    View Slide

  20. Object Instantiation
    Http
    Request
    Disgusting
    DOM Searching
    Sorting Algorithm

    View Slide

  21. View Slide

  22. Please be True…

    View Slide

  23. View Slide

  24. View Slide

  25. Asking for objects to be passed in
    is Dependency Injection
    Calling Code

    View Slide

  26. Inversion of Control

    View Slide

  27. I have to mock this…
    And this… This too.. srsly

    View Slide

  28. Calling getContents()
    will now return
    this HTML
    Passing in my
    $fakeClient

    View Slide

  29. Dependency Injection
    provides Control

    View Slide

  30. 1 year later…

    View Slide

  31. “High-level modules should not depend on low-level modules.
    Both should depend on abstractions”

    View Slide

  32. View Slide

  33. View Slide

  34. “Polymorphism is the provision of a single interface
    to entities of different types”

    View Slide

  35. Recap
    • Dependency Injection is simply passing in object dependencies
    as parameters instead of instantiating them in the object using them

    View Slide

  36. Recap
    • Dependency Injection is simply passing in object dependencies
    as parameters instead of instantiating them in the object using them
    • Doing this gives you Inversion of Control, as the control over
    object creation is no longer delegated to the object using them

    View Slide

  37. Recap
    • Dependency Injection is simply passing in object dependencies
    as parameters instead of instantiating them in the object using them
    • Doing this gives you Inversion of Control, as the control over
    object creation is no longer delegated to the object using them
    • If you use don’t do this, other people will hate you because they can’t
    mock your objects easily in their tests (so your code is not testable)

    View Slide

  38. Recap
    • Dependency Injection is simply passing in object dependencies
    as parameters instead of instantiating them in the object using them
    • Doing this gives you Inversion of Control, as the control over
    object creation is no longer delegated to the object using them
    • Using interfaces, we can adhere to the Dependency Inversion
    Principle and depend on abstractions
    • If you use don’t do this, other people will hate you because they can’t
    mock your objects easily in their tests (so your code is not testable)

    View Slide

  39. Recap
    • Dependency Injection is simply passing in object dependencies
    as parameters instead of instantiating them in the object using them
    • Doing this gives you Inversion of Control, as the control over
    object creation is no longer delegated to the object using them
    • Using interfaces, we can adhere to the Dependency Inversion
    Principle and depend on abstractions
    • Code always starts off procedural, and builds objects up before
    executing them in an object oriented manner
    • If you use don’t do this, other people will hate you because they can’t
    mock your objects easily in their tests (so your code is not testable)

    View Slide

  40. View Slide

  41. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects built

    View Slide

  42. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects built
    Match route to
    controller + action
    Create controller
    Run action with
    any request parameters

    View Slide

  43. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects built
    Match route to
    controller + action
    Create controller
    Run action with
    any request parameters
    Developer creates
    a controller
    Does whatever they want

    View Slide

  44. Framework
    (Object Oriented)
    (hopefully)

    View Slide

  45. Framework
    (Object Oriented)
    (hopefully)

    View Slide

  46. Dependency Injection Container
    (DiC)

    View Slide

  47. Get the Conference
    object here

    View Slide

  48. External requirements should be visible from
    an object’s constructor and method signatures

    View Slide

  49. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects defined
    and registed
    in container
    ‘Object Graph’

    View Slide

  50. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects defined
    and registed
    in container
    Match route to
    controller + action
    Container
    Creates controller
    (with dependencies)
    Container runs action
    with any
    request parameters
    ‘Object Graph’

    View Slide

  51. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Objects defined
    and registed
    in container
    Match route to
    controller + action
    Container
    Creates controller
    (with dependencies)
    Container runs action
    with any
    request parameters
    Developer creates
    a controller
    DI’s registered
    dependencies
    Does whatever they want
    ‘Object Graph’

    View Slide

  52. View Slide

  53. View Slide

  54. View Slide

  55. Create the
    PhpNw15Conference object

    View Slide

  56. View Slide

  57. View Slide

  58. View Slide

  59. View Slide

  60. Automatic Injection for concrete classes

    View Slide

  61. View Slide

  62. View Slide

  63. See ‘Conference’
    Create ‘PhpNw15Conference’

    View Slide

  64. View Slide

  65. View Slide

  66. Bootstrap
    (Procedural)
    Framework
    (Object Oriented)
    (hopefully)
    Dev Code
    (Object Oriented)
    (hopefully)
    Composition Root
    Relationships
    (object graph)
    defined in
    configuration file
    Match route to
    controller + action
    Injector
    Creates controller
    (with dependencies)
    Developer creates
    a controller
    DI’s registered
    dependencies
    Does whatever they want

    View Slide

  67. Dev Code
    (Object Oriented)
    (hopefully)
    Developer creates
    a controller
    DI’s registered
    dependencies
    Does whatever they want

    View Slide

  68. Dev Code
    (Object Oriented)
    (hopefully)
    Developer creates
    a controller
    DI’s registered
    dependencies
    Does whatever they want

    View Slide

  69. Dev Code
    (Object Oriented)
    (hopefully)
    Developer creates
    a controller
    DI’s registered
    dependencies
    Does whatever they want
    • Not coupled to container
    • Remove code / move code about at any time
    • Concentrate on writing SOLID code

    View Slide

  70. View Slide

  71. View Slide

  72. • Your objects should specify external requirements needed in their
    constructor and method signatures

    View Slide

  73. • Your objects should specify external requirements needed in their
    constructor and method signatures
    • Dependency Injection is simply passing in external requirements
    as parameters

    View Slide

  74. • Your objects should specify external requirements needed in their
    constructor and method signatures
    • Dependency Injection is simply passing in external requirements
    as parameters
    • Using interfaces for functionality that might change provides
    polymorphism (switch out concrete implementation any time)

    View Slide

  75. • Your objects should specify external requirements needed in their
    constructor and method signatures
    • Dependency Injection is simply passing in external requirements
    as parameters
    • Using interfaces for functionality that might change provides
    polymorphism (switch out concrete implementation any time)
    • Depending on abstractions rather than concretes (interfaces), and
    having your object graph composed ‘higher’ in the codebase
    (composition root), provides Inversion of Control and helps you
    adhere to the Dependency Inversion Principle

    View Slide

  76. What next?
    AOP and PHP7’s Anonymous Classes

    View Slide

  77. ‘Decorate’ existing Controller
    Delegate controller
    method call,

    but add additional
    functionality (logging)

    View Slide

  78. View Slide

  79. View Slide

  80. View Slide

  81. Anonymous Class
    Automatic

    Decoration

    View Slide

  82. How can I apply this?
    • Choose a framework that supports automatic recursive DI
    • Choose a micro-framework or components that allow you to
    substitute the ‘controller resolver’ to provide this
    • Legacy codebase? Don’t have to use an auto-injector, just design
    your interfaces well adhere to DIP when you can
    • In your next project, make this a primary consideration of your
    software architecture

    View Slide

  83. Why bother?

    View Slide

  84. • The ‘gang of four book’ (GoF)
    • The Clean Coder (Robert C. Martin)
    • Post your code on CodeReview
    (and survive)

    View Slide

  85. @J7mbo
    https://joind.in/talk/view/15431

    View Slide