SlideShare a Scribd company logo
1 of 34
Download to read offline
Dependency Inversion
        and
Dependency Injection
      in PHP

          Michael Toppa
   University of Pennsylvania
  Perelman School of Medicine
      Information Services
         August 11, 2011
Dependency injection
 is a design pattern
  for implementing
dependency inversion
Dependency inversion*
 is a design principle




                  *AKA The Hollywood Principle:
                    “Don't call us, we'll call you”
The SOLID Principles
● Single Responsibility (SRP)
● Open-Closed (OCP)


● Liskov Substitution (LSP)


● Interface Segregation (ISP)


● Dependency Inversion (DIP)
The SRP is about objects that do one thing

The DIP is about how to wire them together
    to create working, flexible software
Formal Definition of the DIP
●   High level modules should not depend on low-
    level modules. Both should depend on
    abstractions.
●   Abstractions should not depend on details.
    Details should depend on abstractions.




                       This definition and the following example are from
                        Bob Martin's book “Agile Software Development”
Naïve model of a button and lamp
                                                  Lamp
                          Button
                                                + turnOn()
                           + poll()
                                                + turnOff()


class Button {
    private $lamp;

    public function __construct(Lamp $lamp) {
         $this->lamp = $lamp;
    }

    public function poll() {
         if (/* some condition */) {
                $this->lamp->turnOn();
         }
    }
}
This solution violates the DIP
●   Button depends directly on Lamp
    ●   Changes to Lamp may require changes to Button
●   Button is not reusable
    ●   It can't control, for example, a Motor
●   The high level abstraction is missing
    ●   “the truths that do not vary when the details are
        changed”
    ●   “To detect an on/off gesture from a user and relay
        that gesture to a target object”
From LosTechies.com
Dependency Inversion Applied

                              <<interface>>
      Button                SwitchableDevice

      + poll()                   + turnOn()
                                 + turnOff()




                                   Lamp



       This is the Abstract Server pattern
class Lamp implements SwitchableDevice {
    public function turnOn() {
         // code
    }

    public function turnOff() {
         // code
    }
}

class Button {
    private $switchableDevice;

    public function __construct(SwitchableDevice $switchableDevice) {
         $this->switchableDevice = $switchableDevice;
    }

    public function poll() {
         if (/* some condition */) {
                $this->switchableDevice->turnOn();
         }
    }
}
What it means
●   Neither Button nor Lamp “own” the interface
●   Buttons can now control any device that
    implements SwitchableDevice
●   Lamps and other SwitchableDevices can now
    be controlled by any object that accepts a
    SwitchableDevice
Patterns that implement the DIP
●   Abstract Server
●   Constructor injection
●   Setter injection
●   Interface injection
●   Factory pattern
●   Adapter pattern
●   Service locator pattern
●   Contextualized lookup (push)
Never do this
class MySqlDb {
  public function __construct($username, $password, $host) {
    // .. snip ..
  }
  public function executeSql($sql) {
    // .. snip ..
  }
}

class BookReader {
  private $_db;
  public function __construct() {
    $this->_db = new MySqlDb(DB_USER, DB_PASS, DB_HOST);
  }
  public function getChapters() {
    return $this->_db->executeSql('SELECT name FROM chapter');
  }
}

                                                  Example from Crafty documentation
                                  http://phpcrafty.sourceforge.net/documentation.php
In addition to other DIP violations,
you cannot write unit tests for that code
Constructor injection solution
interface Db {
  public function executeSql($sql);
}

class MySqlDb implements Db {
  public function __construct($username, $password, $host) {
    // .. snip ..
  }
  public function executeSql($sql) {
    // .. snip ..
  }
}

class BookReader {
  private $_db;
  public function __construct(Db $db) {
    $this->_db = $db;
  }
  public function getChapters() {
    return $this->_db->executeSql('SELECT name FROM chapter');
  }
}
Setter injection solution
class BookReader {
 private $_db;
 public function __construct() {
 }

    public function setDb(Db $db) {
      $this->_db = $db;
    }

    public function getChapters() {
      return $this->_db->executeSql('SELECT name FROM chapter');
    }
}
Which to use?
●   Constructor injection gives you a valid object,
    with all its dependencies, upon construction
●   But constructor injection becomes hard to read
    and use when there are more than a few
    objects to inject
    ●   This is especially true when subclassing
●   More about this in an upcoming slide...
If class A depends on class B,
       and class B depends on class C,
class A should be blissfully unaware of class C
This supports loose coupling

                     and

lets you do dependency injection “just in time”
To do this without going insane,
you need an injection container
Example from Shashin
class Lib_ShashinContainer {
   // ...
   public function __construct($autoLoader) {
       $this->autoLoader = $autoLoader;
   }

    public function getDatabaseFacade() {
      if (!$this->dbFacade) {
          $this->dbFacade = new ToppaDatabaseFacadeWp($this->autoLoader);
      }

        return $this->dbFacade;
    }

    public function getClonablePhoto() {
      if (!$this->clonablePhoto) {
          $this->getDatabaseFacade();
          $this->clonablePhoto = new Lib_ShashinPhoto($this->dbFacade);
      }

        return $this->clonablePhoto;            I am making the objects properties of the
    }                                              container, because they happen to be
}                                                immutable objects, so they are reusable
Container Benefits
●   Loose coupling - objects don't have to worry
    about the dependencies of the objects they use
●   Facilitates portability - specific implementations
    or subtypes are centralized in the container
●   Dependencies are clearly articulated in one
    place
●   Simple design
Constructor vs setter injection:
        my personal preference
●   Start with constructor injection
●   As your design evolves, switch to setter
    injection once there are more than 2 objects to
    inject
●   If you rely on an injection container, you don't
    have to worry about forgetting to call a required
    setter
Injection containers for PHP
●   It's not hard to roll your own
●   There are also many available for PHP
    ●   Bucket
    ●   PicoContainer
    ●   Crafty
    ●   Pimple
    ●   Symfony comes with one
Beyond the textbook examples
What to do when you need
a new object inside a loop

  One solution is cloning
Example from Shashin
class Admin_ShashinSynchronizerPicasa extends Admin_ShashinSynchronizer {

    // …

    public function syncAlbumPhotos(array $decodedAlbumData) {
      // …

     foreach ($decodedAlbumData['feed']['entry'] as $entry) {
        $photoData = $this->extractFieldsFromDecodedData($entry, $photoRefData,
'picasa');
        // ...
        $photo = clone $this->clonablePhoto;
        $photo->set($photoData);
        $photo->flush();
     }

        // ...
    }

    // ...
}
                                                 https://github.com/toppa/Shashin/
What if you need a new object inside a loop,
  but can't know the subtype you'll need
              ahead of time?

   Let the injection container figure it out
Example from Shashin
class Public_ShashinLayoutManager {
   // ...
   public function setTableBody() {
       // …

        for ($i = 0; $i < count($this->collection); $i++) {
           // ...

             $dataObjectDisplayer = $this->container->getDataObjectDisplayer(
                $this->shortcode,
                $this->collection[$i],
                $this->thumbnailCollection[$i]
             );

             $this->tableBody .= $dataObjectDisplayer->run();

             // ...
        }
        // ...
                                                    getDataObjectDisplayer() uses the passed in
    }
                                                       arguments to determine which subtype of
    // ...
                                                                 DataObjectDisplayer to return
}
What makes an injection container
different from the factory pattern?
Good question!
●   An injection container can be used to generate
    more than one class of objects
    ●   A factory generates objects of a single class (or set
        of class subtypes)
●   An injection container consists of methods that
    create and return objects – it's a simple design
    ●   A full factory pattern implementation can be
        complex, and hard to test*
●   They're not mutually exclusive – you can use a
    container to create and inject a factory!
    See http://blog.astrumfutura.com/2009/03/the-case-for-dependency-injection-part-1/
Will this proliferation of objects eat
         up all the server memory?
●   No
     ●   “In PHP 5, the infrastructure of the object model
         was rewritten to work with object handles. Unless
         you explicitly clone an object by using the clone
         keyword you will never create behind the scene
         duplicates of your objects. In PHP 5, there is neither
         a need to pass objects by reference nor assigning
         them by reference.”
     ●   From http://devzone.zend.com/article/1714
A web of collaborating objects
●   Dependency injection is all about a
    “composition” approach to OO design
●   From Growing Object Oriented Software,
    Guided by Tests:
    "An object oriented system is a web of
    collaborating objects... The behavior of the
    system is an emergent property of the
    composition of the objects - the choice of
    objects and how they are connected... Thinking
    of a system in terms of its dynamic
    communication structure is a significant mental
    shift from the static classification that most of us
    learn when being introduced to objects."

More Related Content

What's hot

Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in phpCPD INDIA
 
次世代DaoフレームワークDoma
次世代DaoフレームワークDoma次世代DaoフレームワークDoma
次世代DaoフレームワークDomaToshihiro Nakamura
 
5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャKenji Tanaka
 
20200610 マイクロサービス勉強会
20200610 マイクロサービス勉強会20200610 マイクロサービス勉強会
20200610 マイクロサービス勉強会Naoki Yoshitake
 
Python - Dicionários
Python - DicionáriosPython - Dicionários
Python - DicionáriosMarcos Castro
 
αναπαράσταση αλγορίθμων και δεδομένων
αναπαράσταση αλγορίθμων και δεδομένωναναπαράσταση αλγορίθμων και δεδομένων
αναπαράσταση αλγορίθμων και δεδομένωνMariaProGr
 
C++ Tutorial.docx
C++ Tutorial.docxC++ Tutorial.docx
C++ Tutorial.docxPinkiVats1
 
Html & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshopHtml & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshopVero Rebagliatte
 
Basic JavaScript Tutorial
Basic JavaScript TutorialBasic JavaScript Tutorial
Basic JavaScript TutorialDHTMLExtreme
 
Ασκήσεις δομή Επιλογής
Ασκήσεις δομή ΕπιλογήςΑσκήσεις δομή Επιλογής
Ασκήσεις δομή ΕπιλογήςEleni Kokkinou
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Yasutaka Kawamoto
 
rsyncのちょっとイイ話
rsyncのちょっとイイ話rsyncのちょっとイイ話
rsyncのちょっとイイ話Kazuhiro Oinuma
 
15分でわかるGit入門
15分でわかるGit入門15分でわかるGit入門
15分でわかるGit入門to_ueda
 
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχεια
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχειαΔιαγώνισμα ΕΠΑΛ μέχρι και συνέχεια
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχειαΜάκης Χατζόπουλος
 

What's hot (17)

Oops concepts in php
Oops concepts in phpOops concepts in php
Oops concepts in php
 
次世代DaoフレームワークDoma
次世代DaoフレームワークDoma次世代DaoフレームワークDoma
次世代DaoフレームワークDoma
 
5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ5分でわかるクリーンアーキテクチャ
5分でわかるクリーンアーキテクチャ
 
Php basics
Php basicsPhp basics
Php basics
 
20200610 マイクロサービス勉強会
20200610 マイクロサービス勉強会20200610 マイクロサービス勉強会
20200610 マイクロサービス勉強会
 
Python - Dicionários
Python - DicionáriosPython - Dicionários
Python - Dicionários
 
αναπαράσταση αλγορίθμων και δεδομένων
αναπαράσταση αλγορίθμων και δεδομένωναναπαράσταση αλγορίθμων και δεδομένων
αναπαράσταση αλγορίθμων και δεδομένων
 
Apexデザインパターン
ApexデザインパターンApexデザインパターン
Apexデザインパターン
 
C++ Tutorial.docx
C++ Tutorial.docxC++ Tutorial.docx
C++ Tutorial.docx
 
Html & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshopHtml & CSS - Best practices 2-hour-workshop
Html & CSS - Best practices 2-hour-workshop
 
PHP and Mysql
PHP and MysqlPHP and Mysql
PHP and Mysql
 
Basic JavaScript Tutorial
Basic JavaScript TutorialBasic JavaScript Tutorial
Basic JavaScript Tutorial
 
Ασκήσεις δομή Επιλογής
Ασκήσεις δομή ΕπιλογήςΑσκήσεις δομή Επιλογής
Ασκήσεις δομή Επιλογής
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
 
rsyncのちょっとイイ話
rsyncのちょっとイイ話rsyncのちょっとイイ話
rsyncのちょっとイイ話
 
15分でわかるGit入門
15分でわかるGit入門15分でわかるGit入門
15分でわかるGit入門
 
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχεια
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχειαΔιαγώνισμα ΕΠΑΛ μέχρι και συνέχεια
Διαγώνισμα ΕΠΑΛ μέχρι και συνέχεια
 

Viewers also liked

Dependency inversion w php
Dependency inversion w phpDependency inversion w php
Dependency inversion w phpRafał Kański
 
Object Oriented Design Principles
Object Oriented Design PrinciplesObject Oriented Design Principles
Object Oriented Design PrinciplesThang Tran Duc
 
Gearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsGearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsDinh Pham
 
OOD - Princípio da Inversão de Dependência
OOD - Princípio da Inversão de DependênciaOOD - Princípio da Inversão de Dependência
OOD - Princípio da Inversão de DependênciaPriscila Mayumi
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier 7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier Thoughtworks
 

Viewers also liked (6)

Dependency inversion w php
Dependency inversion w phpDependency inversion w php
Dependency inversion w php
 
Object Oriented Design Principles
Object Oriented Design PrinciplesObject Oriented Design Principles
Object Oriented Design Principles
 
Gearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsGearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applications
 
OOD - Princípio da Inversão de Dependência
OOD - Princípio da Inversão de DependênciaOOD - Princípio da Inversão de Dependência
OOD - Princípio da Inversão de Dependência
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier 7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier
 

Similar to Dependency Inversion and Dependency Injection in PHP

Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
 
Object Oriented Programming for WordPress Plugin Development
Object Oriented Programming for WordPress Plugin DevelopmentObject Oriented Programming for WordPress Plugin Development
Object Oriented Programming for WordPress Plugin Developmentmtoppa
 
10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboardsDenis Ristic
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Greg Szczotka
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeNeil Crookes
 
2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#Daniel Fisher
 
Dependency Injection for Wordpress
Dependency Injection for WordpressDependency Injection for Wordpress
Dependency Injection for Wordpressmtoppa
 
Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?ColdFusionConference
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Iakiv Kramarenko
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsRan Mizrahi
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 

Similar to Dependency Inversion and Dependency Injection in PHP (20)

Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
Design patterns in PHP
Design patterns in PHPDesign patterns in PHP
Design patterns in PHP
 
Object Oriented Programming for WordPress Plugin Development
Object Oriented Programming for WordPress Plugin DevelopmentObject Oriented Programming for WordPress Plugin Development
Object Oriented Programming for WordPress Plugin Development
 
10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards10 PHP Design Patterns #burningkeyboards
10 PHP Design Patterns #burningkeyboards
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Design Patterns and Usage
Design Patterns and UsageDesign Patterns and Usage
Design Patterns and Usage
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014
 
SOLID
SOLIDSOLID
SOLID
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better Code
 
2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#
 
Dependency Injection for Wordpress
Dependency Injection for WordpressDependency Injection for Wordpress
Dependency Injection for Wordpress
 
Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?Dependency Injection Why is it awesome and Why should I care?
Dependency Injection Why is it awesome and Why should I care?
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Creational Design Patterns
Creational Design PatternsCreational Design Patterns
Creational Design Patterns
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 

More from mtoppa

RubyConf 2022 - From beginner to expert, and back again
RubyConf 2022 - From beginner to expert, and back againRubyConf 2022 - From beginner to expert, and back again
RubyConf 2022 - From beginner to expert, and back againmtoppa
 
RailsConf 2022 - Upgrading Rails: The Dual Boot Way
RailsConf 2022 - Upgrading Rails: The Dual Boot WayRailsConf 2022 - Upgrading Rails: The Dual Boot Way
RailsConf 2022 - Upgrading Rails: The Dual Boot Waymtoppa
 
Applying Omotenashi (Japanese customer service) to your work
Applying Omotenashi (Japanese customer service) to your workApplying Omotenashi (Japanese customer service) to your work
Applying Omotenashi (Japanese customer service) to your workmtoppa
 
Talking to strangers causes train wrecks
Talking to strangers causes train wrecksTalking to strangers causes train wrecks
Talking to strangers causes train wrecksmtoppa
 
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between: accessib...
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between:  accessib...A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between:  accessib...
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between: accessib...mtoppa
 
The promise and peril of Agile and Lean practices
The promise and peril of Agile and Lean practicesThe promise and peril of Agile and Lean practices
The promise and peril of Agile and Lean practicesmtoppa
 
Why do planes crash? Lessons for junior and senior developers
Why do planes crash? Lessons for junior and senior developersWhy do planes crash? Lessons for junior and senior developers
Why do planes crash? Lessons for junior and senior developersmtoppa
 
Boston Ruby Meetup: The promise and peril of Agile and Lean practices
Boston Ruby Meetup: The promise and peril of Agile and Lean practicesBoston Ruby Meetup: The promise and peril of Agile and Lean practices
Boston Ruby Meetup: The promise and peril of Agile and Lean practicesmtoppa
 
A real-life overview of Agile and Scrum
A real-life overview of Agile and ScrumA real-life overview of Agile and Scrum
A real-life overview of Agile and Scrummtoppa
 
WordCamp Nashville 2016: The promise and peril of Agile and Lean practices
WordCamp Nashville 2016: The promise and peril of Agile and Lean practicesWordCamp Nashville 2016: The promise and peril of Agile and Lean practices
WordCamp Nashville 2016: The promise and peril of Agile and Lean practicesmtoppa
 
WordCamp US: Clean Code
WordCamp US: Clean CodeWordCamp US: Clean Code
WordCamp US: Clean Codemtoppa
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHPmtoppa
 
WordCamp Boston 2015: Agile Contracts for WordPress Consultants
WordCamp Boston 2015: Agile Contracts for WordPress ConsultantsWordCamp Boston 2015: Agile Contracts for WordPress Consultants
WordCamp Boston 2015: Agile Contracts for WordPress Consultantsmtoppa
 
WordCamp Nashville 2015: Agile Contracts for WordPress Consultants
WordCamp Nashville 2015: Agile Contracts for WordPress ConsultantsWordCamp Nashville 2015: Agile Contracts for WordPress Consultants
WordCamp Nashville 2015: Agile Contracts for WordPress Consultantsmtoppa
 
Rails testing: factories or fixtures?
Rails testing: factories or fixtures?Rails testing: factories or fixtures?
Rails testing: factories or fixtures?mtoppa
 
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?mtoppa
 
WordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressWordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressmtoppa
 
A real-life overview of Agile workflow practices
A real-life overview of Agile workflow practicesA real-life overview of Agile workflow practices
A real-life overview of Agile workflow practicesmtoppa
 
Why Agile? Why Now?
Why Agile? Why Now?Why Agile? Why Now?
Why Agile? Why Now?mtoppa
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPressmtoppa
 

More from mtoppa (20)

RubyConf 2022 - From beginner to expert, and back again
RubyConf 2022 - From beginner to expert, and back againRubyConf 2022 - From beginner to expert, and back again
RubyConf 2022 - From beginner to expert, and back again
 
RailsConf 2022 - Upgrading Rails: The Dual Boot Way
RailsConf 2022 - Upgrading Rails: The Dual Boot WayRailsConf 2022 - Upgrading Rails: The Dual Boot Way
RailsConf 2022 - Upgrading Rails: The Dual Boot Way
 
Applying Omotenashi (Japanese customer service) to your work
Applying Omotenashi (Japanese customer service) to your workApplying Omotenashi (Japanese customer service) to your work
Applying Omotenashi (Japanese customer service) to your work
 
Talking to strangers causes train wrecks
Talking to strangers causes train wrecksTalking to strangers causes train wrecks
Talking to strangers causes train wrecks
 
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between: accessib...
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between:  accessib...A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between:  accessib...
A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between: accessib...
 
The promise and peril of Agile and Lean practices
The promise and peril of Agile and Lean practicesThe promise and peril of Agile and Lean practices
The promise and peril of Agile and Lean practices
 
Why do planes crash? Lessons for junior and senior developers
Why do planes crash? Lessons for junior and senior developersWhy do planes crash? Lessons for junior and senior developers
Why do planes crash? Lessons for junior and senior developers
 
Boston Ruby Meetup: The promise and peril of Agile and Lean practices
Boston Ruby Meetup: The promise and peril of Agile and Lean practicesBoston Ruby Meetup: The promise and peril of Agile and Lean practices
Boston Ruby Meetup: The promise and peril of Agile and Lean practices
 
A real-life overview of Agile and Scrum
A real-life overview of Agile and ScrumA real-life overview of Agile and Scrum
A real-life overview of Agile and Scrum
 
WordCamp Nashville 2016: The promise and peril of Agile and Lean practices
WordCamp Nashville 2016: The promise and peril of Agile and Lean practicesWordCamp Nashville 2016: The promise and peril of Agile and Lean practices
WordCamp Nashville 2016: The promise and peril of Agile and Lean practices
 
WordCamp US: Clean Code
WordCamp US: Clean CodeWordCamp US: Clean Code
WordCamp US: Clean Code
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHP
 
WordCamp Boston 2015: Agile Contracts for WordPress Consultants
WordCamp Boston 2015: Agile Contracts for WordPress ConsultantsWordCamp Boston 2015: Agile Contracts for WordPress Consultants
WordCamp Boston 2015: Agile Contracts for WordPress Consultants
 
WordCamp Nashville 2015: Agile Contracts for WordPress Consultants
WordCamp Nashville 2015: Agile Contracts for WordPress ConsultantsWordCamp Nashville 2015: Agile Contracts for WordPress Consultants
WordCamp Nashville 2015: Agile Contracts for WordPress Consultants
 
Rails testing: factories or fixtures?
Rails testing: factories or fixtures?Rails testing: factories or fixtures?
Rails testing: factories or fixtures?
 
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?
WordCamp Lancaster 2014: A11Y? I18N? L10N? UTF8? WTF?
 
WordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressWordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPress
 
A real-life overview of Agile workflow practices
A real-life overview of Agile workflow practicesA real-life overview of Agile workflow practices
A real-life overview of Agile workflow practices
 
Why Agile? Why Now?
Why Agile? Why Now?Why Agile? Why Now?
Why Agile? Why Now?
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPress
 

Recently uploaded

Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 

Dependency Inversion and Dependency Injection in PHP

  • 1. Dependency Inversion and Dependency Injection in PHP Michael Toppa University of Pennsylvania Perelman School of Medicine Information Services August 11, 2011
  • 2. Dependency injection is a design pattern for implementing dependency inversion
  • 3. Dependency inversion* is a design principle *AKA The Hollywood Principle: “Don't call us, we'll call you”
  • 4. The SOLID Principles ● Single Responsibility (SRP) ● Open-Closed (OCP) ● Liskov Substitution (LSP) ● Interface Segregation (ISP) ● Dependency Inversion (DIP)
  • 5. The SRP is about objects that do one thing The DIP is about how to wire them together to create working, flexible software
  • 6. Formal Definition of the DIP ● High level modules should not depend on low- level modules. Both should depend on abstractions. ● Abstractions should not depend on details. Details should depend on abstractions. This definition and the following example are from Bob Martin's book “Agile Software Development”
  • 7. Naïve model of a button and lamp Lamp Button + turnOn() + poll() + turnOff() class Button { private $lamp; public function __construct(Lamp $lamp) { $this->lamp = $lamp; } public function poll() { if (/* some condition */) { $this->lamp->turnOn(); } } }
  • 8. This solution violates the DIP ● Button depends directly on Lamp ● Changes to Lamp may require changes to Button ● Button is not reusable ● It can't control, for example, a Motor ● The high level abstraction is missing ● “the truths that do not vary when the details are changed” ● “To detect an on/off gesture from a user and relay that gesture to a target object”
  • 10. Dependency Inversion Applied <<interface>> Button SwitchableDevice + poll() + turnOn() + turnOff() Lamp This is the Abstract Server pattern
  • 11. class Lamp implements SwitchableDevice { public function turnOn() { // code } public function turnOff() { // code } } class Button { private $switchableDevice; public function __construct(SwitchableDevice $switchableDevice) { $this->switchableDevice = $switchableDevice; } public function poll() { if (/* some condition */) { $this->switchableDevice->turnOn(); } } }
  • 12. What it means ● Neither Button nor Lamp “own” the interface ● Buttons can now control any device that implements SwitchableDevice ● Lamps and other SwitchableDevices can now be controlled by any object that accepts a SwitchableDevice
  • 13. Patterns that implement the DIP ● Abstract Server ● Constructor injection ● Setter injection ● Interface injection ● Factory pattern ● Adapter pattern ● Service locator pattern ● Contextualized lookup (push)
  • 14. Never do this class MySqlDb { public function __construct($username, $password, $host) { // .. snip .. } public function executeSql($sql) { // .. snip .. } } class BookReader { private $_db; public function __construct() { $this->_db = new MySqlDb(DB_USER, DB_PASS, DB_HOST); } public function getChapters() { return $this->_db->executeSql('SELECT name FROM chapter'); } } Example from Crafty documentation http://phpcrafty.sourceforge.net/documentation.php
  • 15. In addition to other DIP violations, you cannot write unit tests for that code
  • 16. Constructor injection solution interface Db { public function executeSql($sql); } class MySqlDb implements Db { public function __construct($username, $password, $host) { // .. snip .. } public function executeSql($sql) { // .. snip .. } } class BookReader { private $_db; public function __construct(Db $db) { $this->_db = $db; } public function getChapters() { return $this->_db->executeSql('SELECT name FROM chapter'); } }
  • 17. Setter injection solution class BookReader { private $_db; public function __construct() { } public function setDb(Db $db) { $this->_db = $db; } public function getChapters() { return $this->_db->executeSql('SELECT name FROM chapter'); } }
  • 18. Which to use? ● Constructor injection gives you a valid object, with all its dependencies, upon construction ● But constructor injection becomes hard to read and use when there are more than a few objects to inject ● This is especially true when subclassing ● More about this in an upcoming slide...
  • 19. If class A depends on class B, and class B depends on class C, class A should be blissfully unaware of class C
  • 20. This supports loose coupling and lets you do dependency injection “just in time”
  • 21. To do this without going insane, you need an injection container
  • 22. Example from Shashin class Lib_ShashinContainer { // ... public function __construct($autoLoader) { $this->autoLoader = $autoLoader; } public function getDatabaseFacade() { if (!$this->dbFacade) { $this->dbFacade = new ToppaDatabaseFacadeWp($this->autoLoader); } return $this->dbFacade; } public function getClonablePhoto() { if (!$this->clonablePhoto) { $this->getDatabaseFacade(); $this->clonablePhoto = new Lib_ShashinPhoto($this->dbFacade); } return $this->clonablePhoto; I am making the objects properties of the } container, because they happen to be } immutable objects, so they are reusable
  • 23. Container Benefits ● Loose coupling - objects don't have to worry about the dependencies of the objects they use ● Facilitates portability - specific implementations or subtypes are centralized in the container ● Dependencies are clearly articulated in one place ● Simple design
  • 24. Constructor vs setter injection: my personal preference ● Start with constructor injection ● As your design evolves, switch to setter injection once there are more than 2 objects to inject ● If you rely on an injection container, you don't have to worry about forgetting to call a required setter
  • 25. Injection containers for PHP ● It's not hard to roll your own ● There are also many available for PHP ● Bucket ● PicoContainer ● Crafty ● Pimple ● Symfony comes with one
  • 27. What to do when you need a new object inside a loop One solution is cloning
  • 28. Example from Shashin class Admin_ShashinSynchronizerPicasa extends Admin_ShashinSynchronizer { // … public function syncAlbumPhotos(array $decodedAlbumData) { // … foreach ($decodedAlbumData['feed']['entry'] as $entry) { $photoData = $this->extractFieldsFromDecodedData($entry, $photoRefData, 'picasa'); // ... $photo = clone $this->clonablePhoto; $photo->set($photoData); $photo->flush(); } // ... } // ... } https://github.com/toppa/Shashin/
  • 29. What if you need a new object inside a loop, but can't know the subtype you'll need ahead of time? Let the injection container figure it out
  • 30. Example from Shashin class Public_ShashinLayoutManager { // ... public function setTableBody() { // … for ($i = 0; $i < count($this->collection); $i++) { // ... $dataObjectDisplayer = $this->container->getDataObjectDisplayer( $this->shortcode, $this->collection[$i], $this->thumbnailCollection[$i] ); $this->tableBody .= $dataObjectDisplayer->run(); // ... } // ... getDataObjectDisplayer() uses the passed in } arguments to determine which subtype of // ... DataObjectDisplayer to return }
  • 31. What makes an injection container different from the factory pattern?
  • 32. Good question! ● An injection container can be used to generate more than one class of objects ● A factory generates objects of a single class (or set of class subtypes) ● An injection container consists of methods that create and return objects – it's a simple design ● A full factory pattern implementation can be complex, and hard to test* ● They're not mutually exclusive – you can use a container to create and inject a factory! See http://blog.astrumfutura.com/2009/03/the-case-for-dependency-injection-part-1/
  • 33. Will this proliferation of objects eat up all the server memory? ● No ● “In PHP 5, the infrastructure of the object model was rewritten to work with object handles. Unless you explicitly clone an object by using the clone keyword you will never create behind the scene duplicates of your objects. In PHP 5, there is neither a need to pass objects by reference nor assigning them by reference.” ● From http://devzone.zend.com/article/1714
  • 34. A web of collaborating objects ● Dependency injection is all about a “composition” approach to OO design ● From Growing Object Oriented Software, Guided by Tests: "An object oriented system is a web of collaborating objects... The behavior of the system is an emergent property of the composition of the objects - the choice of objects and how they are connected... Thinking of a system in terms of its dynamic communication structure is a significant mental shift from the static classification that most of us learn when being introduced to objects."