SlideShare a Scribd company logo
1 of 57
Download to read offline
Dependency Injection for
            WordPress Plugin Development

                    Mike Toppa
                WordCamp Nashville
                  April 21, 2012
                     #wcn12



www.toppa.com                              @mtoppa
Mike Toppa
●   Director of Development, WebDevStudios
●   17 years of experience in web development,
    project management, and team management
●   Universities: Georgetown, Stanford, Penn
●   Dot coms: E*Trade, Ask Jeeves
●   Start-ups: Finexa, Kai's Candy Co
●   WordPress development for non-profits

www.toppa.com                                  @mtoppa
Code is Poetry




www.toppa.com                    @mtoppa
We want code to be...
●   Easy to understand
●   Easy to change
●   Reusable (DRY)
●   Bug free




www.toppa.com                           @mtoppa
So why is it usually like this?




“O.P.C” http://abstrusegoose.com/432
It happens because we are always in a hurry,
          and requirements are always changing.




www.toppa.com                               @mtoppa
But coding fast and dirty
            only makes us slower in the long run.




www.toppa.com                                  @mtoppa
“We like to think we spend our time power typing,
     but we actually spend most of our time
              staring into the abyss.”

                - Douglas Crockford
                   principal discoverer of JSON,
                          Creator of JSLint




www.toppa.com                                      @mtoppa
The ratio of time spent reading code versus
             writing is well over 10 to 1.

         Therefore, making code easy to read
               makes it easier to write.

                       - Bob Martin
                  Paraphrased from his book Clean Code




www.toppa.com                                            @mtoppa
Clean code saves time, saves $$




www.toppa.com                  @mtoppa
Clean code techniques
●   Using meaningful names
●   Don't repeat yourself (DRY)
●   Object oriented principles and patterns
●   Unit testing, test driven development (TDD)
●   The “boy scout rule”
●   Vertical slicing
●   ...and many more
www.toppa.com                                 @mtoppa
Clean code techniques
●   Using meaningful names
●   Don't repeat yourself (DRY)
●   Object oriented principles and patterns
●   Unit testing, test driven development (TDD)
●   The “boy scout rule”
●   Vertical slicing
●   ...and many more
www.toppa.com                                 @mtoppa
The SOLID Principles
●   Single Responsibility (SRP)
●   Open-Closed (OCP)
●   Liskov Substitution (LSP)
●   Interface Segregation (ISP)
●   Dependency Inversion (DIP)



www.toppa.com                          @mtoppa
The SOLID Principles
●   Single Responsibility (SRP)
●   Open-Closed (OCP)
●   Liskov Substitution (LSP)
●   Interface Segregation (ISP)
●   Dependency Inversion (DIP)



www.toppa.com                          @mtoppa
Shashin

   My plugin for displaying albums, photos, and
    videos from Picasa, Twitpic, and YouTube
            (and others coming soon)




www.toppa.com                               @mtoppa
I used the new version as a test case for applying
    clean code principles to WordPress plugins




www.toppa.com                               @mtoppa
From LosTechies.com
My Shashin plugin consists of 44 classes, each of
 which has a meaningful name, follows the SRP,
             and “does one thing”

                PicasaPhotoDisplayer
                    SettingsMenu
                YouTubeSynchronizer
                      Uninstall
                         etc.

www.toppa.com                              @mtoppa
Shashin example

class Admin_ShashinInstall {
   // ...

    public function run() {
      $this->createAlbumTable();
      $this->verifyAlbumTable();
      $this->createPhotoTable();
      $this->verifyPhotoTable();
      $this->updateSettings();
      return true;
    }

    // ...
}


www.toppa.com                            @mtoppa
Class Autoloading
●   The problem:
    ●   PHP lacks an equivalent statement to “import” or
        “use” for classes
    ●   Having to hardcode a bunch of file paths is extra
        work, and makes code harder to change
●   The solution:
    ●   PHP 5.1.2 and spl_autoload_register()
    ●   PHP Standards Working Group: PSR-0

www.toppa.com                                        @mtoppa
PSR-0: Official Description
●   Each "_" character in the CLASS NAME is
    converted to a DIRECTORY_SEPARATOR
●   The fully-qualified namespace and class is suffixed
    with ".php" when loading from the file system
●   Alphabetic characters... may be of any
    combination of lower case and upper case
●   ...And other rules about namespaces
●   Source: https://github.com/php-fig/fig-
    standards/blob/master/accepted/PSR-0.md
www.toppa.com                                   @mtoppa
PSR-0 Example


                 Admin_ShashinInstall

                     is translated to

                Admin/ShashinInstall.php


www.toppa.com                              @mtoppa
Toppa Plugin Libraries Autoloader
// this is at the top of the main file for my Shashin plugin

require_once dirname(__FILE__) . '/../toppa-plugin-libraries-for-
wordpress/ToppaAutoLoaderWp.php';

$shashinAutoLoader = new ToppaAutoLoaderWp('/shashin');

// that's it! I can now call “new” on any class under the shashin folder
// and its class file will be automatically loaded




www.toppa.com                                                              @mtoppa
Shashin's capabilities are shaped by how its
        objects are wired together, through
               implementation of the
         Dependency Inversion Principle




www.toppa.com                                @mtoppa
From LosTechies.com
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();
         }
    }
}
                                                Example from “Agile Software Development”
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();
         }
    }
}
A web of collaborating objects
●   The SRP and DIP together drive 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."
Composition
                 (“Has a...”)

                     vs.

                Inheritance
                  (“Is a...”)



www.toppa.com                   @mtoppa
The SRP is about objects that do one thing

    The DIP is about how to wire them together
        to create working, flexible software




www.toppa.com                              @mtoppa
Never, ever do this


class Button {
    private $lamp;

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

    //...
}




www.toppa.com                              @mtoppa
Instead, you want to
                inject the object dependency

                  Dependency injection!




www.toppa.com                                  @mtoppa
Dependency injection is one of many
                  design patterns
               for implementing the
           Dependency inversion principle




www.toppa.com                                  @mtoppa
It comes in two flavors




www.toppa.com                             @mtoppa
Constructor injection


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




www.toppa.com                                                       @mtoppa
Setter injection


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




www.toppa.com                                                               @mtoppa
Which to use?

                 It depends




www.toppa.com                   @mtoppa
Dependency chains




          If class A depends on class B,
        and class B depends on class C,
 class A should be blissfully unaware of class C



www.toppa.com                               @mtoppa
To do this without going insane,
                you need an injection container




www.toppa.com                                      @mtoppa
Example from Shashin
class Lib_ShashinContainer {
   // …
   public function getPhotoRefData() {
      if (!isset($this->photoRefData)) {
          $this->photoRefData = new Lib_ShashinPhotoRefData();
      }

      return $this->photoRefData;
  }

  public function getClonablePhoto() {
    if (!isset($this->clonablePhoto)) {
        $this->getPhotoRefData();
        $this->clonablePhoto = new Lib_ShashinPhoto($this->photoRefData);
    }

      return $this->clonablePhoto;
  }
www.toppa.com                                                               @mtoppa
Example continued

 public function getClonablePhotoCollection() {
   if (!isset($this->photoCollection)) {
       $this->getClonablePhoto();
       $this->getSettings();
       $this->clonablePhotoCollection = new Lib_ShashinPhotoCollection();
       $this->clonablePhotoCollection->setClonableDataObject($this->clonablePhoto);
       $this->clonablePhotoCollection->setSettings($this->settings);
   }

     return $this->clonablePhotoCollection;
 }




www.toppa.com                                                              @mtoppa
Beyond the textbook examples




www.toppa.com                                  @mtoppa
What to do when you need
                a new object inside a loop

                  One solution is cloning




www.toppa.com                                @mtoppa
Shashin Example

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();
     }



www.toppa.com                                                            @mtoppa
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




www.toppa.com                                       @mtoppa
Shashin Example

class Public_ShashinLayoutManager {
   // ...
   public function setTableBody() {
       // …

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

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

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

      // ...
   }
www.toppa.com                                                            @mtoppa
Dependency injection: key benefits
●   Makes your object dependencies adaptable to
    emerging needs
●   With an injection container, simplifies managing
    dependency chains
●   Supports “preferring polymorphism to
    conditionals”, making it easy to add new class
    subtypes


www.toppa.com                                 @mtoppa
Will this proliferation of objects
                    eat up all my memory?

                               No




www.toppa.com                                        @mtoppa
Use dependency injection to instantiate
             only the objects you need,
               when you need them




www.toppa.com                                @mtoppa
Make immutable objects into
            properties of the container,
     so you only need to instantiate them once




www.toppa.com                               @mtoppa
PHP 5 has improved memory
             management

“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

www.toppa.com                                      @mtoppa
But don't overdo it:
avoid needless complexity

More Related Content

What's hot

Introduction to Version Control
Introduction to Version ControlIntroduction to Version Control
Introduction to Version ControlJeremy Coates
 
Git the Docs: A fun, hands-on introduction to version control
Git the Docs: A fun, hands-on introduction to version controlGit the Docs: A fun, hands-on introduction to version control
Git the Docs: A fun, hands-on introduction to version controlBecky Todd
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your DatabaseDavid Wheeler
 
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)Pedro Moreira da Silva
 
Python Programming Essentials - M6 - Code Blocks and Indentation
Python Programming Essentials - M6 - Code Blocks and IndentationPython Programming Essentials - M6 - Code Blocks and Indentation
Python Programming Essentials - M6 - Code Blocks and IndentationP3 InfoTech Solutions Pvt. Ltd.
 
Github - Git Training Slides: Foundations
Github - Git Training Slides: FoundationsGithub - Git Training Slides: Foundations
Github - Git Training Slides: FoundationsLee Hanxue
 
Basic Javascript
Basic JavascriptBasic Javascript
Basic JavascriptBunlong Van
 
Introduction to Gitlab
Introduction to GitlabIntroduction to Gitlab
Introduction to GitlabJulien Pivotto
 
java 8 new features
java 8 new features java 8 new features
java 8 new features Rohit Verma
 
Jenkins 101: Getting Started
Jenkins 101: Getting StartedJenkins 101: Getting Started
Jenkins 101: Getting StartedR Geoffrey Avery
 

What's hot (20)

Introduction to Version Control
Introduction to Version ControlIntroduction to Version Control
Introduction to Version Control
 
Git the Docs: A fun, hands-on introduction to version control
Git the Docs: A fun, hands-on introduction to version controlGit the Docs: A fun, hands-on introduction to version control
Git the Docs: A fun, hands-on introduction to version control
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your Database
 
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)
GitLab: One Tool for Software Development (2018-02-06 @ SEIUM, Braga, Portugal)
 
Html ppt
Html pptHtml ppt
Html ppt
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Python Programming Essentials - M6 - Code Blocks and Indentation
Python Programming Essentials - M6 - Code Blocks and IndentationPython Programming Essentials - M6 - Code Blocks and Indentation
Python Programming Essentials - M6 - Code Blocks and Indentation
 
Github - Git Training Slides: Foundations
Github - Git Training Slides: FoundationsGithub - Git Training Slides: Foundations
Github - Git Training Slides: Foundations
 
Github
GithubGithub
Github
 
Basic Javascript
Basic JavascriptBasic Javascript
Basic Javascript
 
Introduction to Gitlab
Introduction to GitlabIntroduction to Gitlab
Introduction to Gitlab
 
java 8 new features
java 8 new features java 8 new features
java 8 new features
 
Jenkins 101: Getting Started
Jenkins 101: Getting StartedJenkins 101: Getting Started
Jenkins 101: Getting Started
 
Html 5 Features And Benefits
Html 5 Features And Benefits  Html 5 Features And Benefits
Html 5 Features And Benefits
 
BitBucket presentation
BitBucket presentationBitBucket presentation
BitBucket presentation
 
[O'Reilly] HTML5 Design
[O'Reilly] HTML5 Design[O'Reilly] HTML5 Design
[O'Reilly] HTML5 Design
 
Core java
Core java Core java
Core java
 
Git and Github Session
Git and Github SessionGit and Github Session
Git and Github Session
 
Javascript
JavascriptJavascript
Javascript
 
HTML Forms
HTML FormsHTML Forms
HTML Forms
 

Viewers also liked

WordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressWordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressmtoppa
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHPmtoppa
 
Logging with Monolog
Logging with MonologLogging with Monolog
Logging with MonologTudor Barbu
 
Automated Abstraction of Flow of Control in a System of Distributed Software...
Automated Abstraction of Flow of Control in a System of Distributed  Software...Automated Abstraction of Flow of Control in a System of Distributed  Software...
Automated Abstraction of Flow of Control in a System of Distributed Software...nimak
 
Quanto è sicuro il tuo wordpress?
Quanto è sicuro il tuo wordpress? Quanto è sicuro il tuo wordpress?
Quanto è sicuro il tuo wordpress? GGDBologna
 
Take the next step with git
Take the next step with gitTake the next step with git
Take the next step with gitKarin Taliga
 
WordPress Community: Choose your own adventure
WordPress Community: Choose your own adventureWordPress Community: Choose your own adventure
WordPress Community: Choose your own adventureAndrea Middleton
 
THE WORDPRESS DASHBOARD DEMYSTIFIED
THE WORDPRESS DASHBOARD DEMYSTIFIEDTHE WORDPRESS DASHBOARD DEMYSTIFIED
THE WORDPRESS DASHBOARD DEMYSTIFIEDBobWP.com
 
A house with no walls: Creating a site structure for the future
A house with no walls: Creating a site structure for the futureA house with no walls: Creating a site structure for the future
A house with no walls: Creating a site structure for the futureGizmo Creative Factory, Inc.
 
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...GGDBologna
 
CSI: WordPress -- Getting Into the Guts
CSI: WordPress -- Getting Into the GutsCSI: WordPress -- Getting Into the Guts
CSI: WordPress -- Getting Into the GutsDougal Campbell
 
Cómo crear plugins para Wordpress
Cómo crear plugins para WordpressCómo crear plugins para Wordpress
Cómo crear plugins para Wordpressralcocer
 
Zazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp MilwaukeeZazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp MilwaukeeRachel Baker
 
Congrats. You're having a WordPress Site. WordCamp Philly
Congrats. You're having a WordPress Site. WordCamp PhillyCongrats. You're having a WordPress Site. WordCamp Philly
Congrats. You're having a WordPress Site. WordCamp PhillyTrailer Trash Design
 
A Fantástica Fábrica de Websites - WordPress
A Fantástica Fábrica de Websites - WordPressA Fantástica Fábrica de Websites - WordPress
A Fantástica Fábrica de Websites - WordPressDaniel Glik
 
Getting an eCommerce Site Running in 30 Minutes
Getting an eCommerce Site Running in 30 MinutesGetting an eCommerce Site Running in 30 Minutes
Getting an eCommerce Site Running in 30 MinutesApptivo
 
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress Business
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress BusinessThe Capitalist in the Co-Op: The Art & Science of the Premium WordPress Business
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress BusinessShane Pearlman
 

Viewers also liked (20)

WordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPressWordCamp Nashville: Clean Code for WordPress
WordCamp Nashville: Clean Code for WordPress
 
Dependency Injection for PHP
Dependency Injection for PHPDependency Injection for PHP
Dependency Injection for PHP
 
Logging with Monolog
Logging with MonologLogging with Monolog
Logging with Monolog
 
Use of Monolog with PHP
Use of Monolog with PHPUse of Monolog with PHP
Use of Monolog with PHP
 
Automated Abstraction of Flow of Control in a System of Distributed Software...
Automated Abstraction of Flow of Control in a System of Distributed  Software...Automated Abstraction of Flow of Control in a System of Distributed  Software...
Automated Abstraction of Flow of Control in a System of Distributed Software...
 
Quanto è sicuro il tuo wordpress?
Quanto è sicuro il tuo wordpress? Quanto è sicuro il tuo wordpress?
Quanto è sicuro il tuo wordpress?
 
Take the next step with git
Take the next step with gitTake the next step with git
Take the next step with git
 
WordPress Community: Choose your own adventure
WordPress Community: Choose your own adventureWordPress Community: Choose your own adventure
WordPress Community: Choose your own adventure
 
THE WORDPRESS DASHBOARD DEMYSTIFIED
THE WORDPRESS DASHBOARD DEMYSTIFIEDTHE WORDPRESS DASHBOARD DEMYSTIFIED
THE WORDPRESS DASHBOARD DEMYSTIFIED
 
WordCamp 2015
WordCamp 2015WordCamp 2015
WordCamp 2015
 
A house with no walls: Creating a site structure for the future
A house with no walls: Creating a site structure for the futureA house with no walls: Creating a site structure for the future
A house with no walls: Creating a site structure for the future
 
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...
L’ascesa della geolocalizzazione. Perché mapperemo sempre di più e come lo fa...
 
Caching 101 - WordCamp OC
Caching 101 - WordCamp OCCaching 101 - WordCamp OC
Caching 101 - WordCamp OC
 
CSI: WordPress -- Getting Into the Guts
CSI: WordPress -- Getting Into the GutsCSI: WordPress -- Getting Into the Guts
CSI: WordPress -- Getting Into the Guts
 
Cómo crear plugins para Wordpress
Cómo crear plugins para WordpressCómo crear plugins para Wordpress
Cómo crear plugins para Wordpress
 
Zazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp MilwaukeeZazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp Milwaukee
 
Congrats. You're having a WordPress Site. WordCamp Philly
Congrats. You're having a WordPress Site. WordCamp PhillyCongrats. You're having a WordPress Site. WordCamp Philly
Congrats. You're having a WordPress Site. WordCamp Philly
 
A Fantástica Fábrica de Websites - WordPress
A Fantástica Fábrica de Websites - WordPressA Fantástica Fábrica de Websites - WordPress
A Fantástica Fábrica de Websites - WordPress
 
Getting an eCommerce Site Running in 30 Minutes
Getting an eCommerce Site Running in 30 MinutesGetting an eCommerce Site Running in 30 Minutes
Getting an eCommerce Site Running in 30 Minutes
 
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress Business
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress BusinessThe Capitalist in the Co-Op: The Art & Science of the Premium WordPress Business
The Capitalist in the Co-Op: The Art & Science of the Premium WordPress Business
 

Similar to Dependency Injection for Wordpress

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
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPmtoppa
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPressmtoppa
 
Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Chris Tankersley
 
The WordPress way, the modern way: developing as if it were 2016
The WordPress way, the modern way: developing as if it were 2016The WordPress way, the modern way: developing as if it were 2016
The WordPress way, the modern way: developing as if it were 2016lucatume
 
Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Holden Karau
 
OOP is more than Cars and Dogs
OOP is more than Cars and Dogs OOP is more than Cars and Dogs
OOP is more than Cars and Dogs Chris Tankersley
 
Modernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesModernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesiMasters
 
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...Holden Karau
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоGeeksLab Odessa
 
principles of object oriented class design
principles of object oriented class designprinciples of object oriented class design
principles of object oriented class designNeetu Mishra
 
Common design principles and design patterns in automation testing
Common design principles and design patterns in automation testingCommon design principles and design patterns in automation testing
Common design principles and design patterns in automation testingKMS Technology
 
Merged Automation Talk - Pete Carapetyan - Feb 2016
Merged Automation Talk - Pete Carapetyan - Feb 2016 Merged Automation Talk - Pete Carapetyan - Feb 2016
Merged Automation Talk - Pete Carapetyan - Feb 2016 petecarapetyan
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
Introduction to rails
Introduction to railsIntroduction to rails
Introduction to railsGo Asgard
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 

Similar to Dependency Injection for Wordpress (20)

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
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHP
 
Clean code for WordPress
Clean code for WordPressClean code for WordPress
Clean code for WordPress
 
Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)
 
The WordPress way, the modern way: developing as if it were 2016
The WordPress way, the modern way: developing as if it were 2016The WordPress way, the modern way: developing as if it were 2016
The WordPress way, the modern way: developing as if it were 2016
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018Big Data Beyond the JVM - Strata San Jose 2018
Big Data Beyond the JVM - Strata San Jose 2018
 
OOP is more than Cars and Dogs
OOP is more than Cars and Dogs OOP is more than Cars and Dogs
OOP is more than Cars and Dogs
 
Reusable Apps
Reusable AppsReusable Apps
Reusable Apps
 
Modernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesModernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul Jones
 
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...
Ml pipelines with Apache spark and Apache beam - Ottawa Reactive meetup Augus...
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег ЗинченкоWebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
 
Rails data migrations
Rails data migrationsRails data migrations
Rails data migrations
 
principles of object oriented class design
principles of object oriented class designprinciples of object oriented class design
principles of object oriented class design
 
Common design principles and design patterns in automation testing
Common design principles and design patterns in automation testingCommon design principles and design patterns in automation testing
Common design principles and design patterns in automation testing
 
Dependency injectionpreso
Dependency injectionpresoDependency injectionpreso
Dependency injectionpreso
 
Merged Automation Talk - Pete Carapetyan - Feb 2016
Merged Automation Talk - Pete Carapetyan - Feb 2016 Merged Automation Talk - Pete Carapetyan - Feb 2016
Merged Automation Talk - Pete Carapetyan - Feb 2016
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
Introduction to rails
Introduction to railsIntroduction to rails
Introduction to rails
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 

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
 
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
 
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
 
Why Do Planes Crash?
Why Do Planes Crash?Why Do Planes Crash?
Why Do Planes Crash?mtoppa
 
Why Scrum Why Now
Why Scrum Why NowWhy Scrum Why Now
Why Scrum Why Nowmtoppa
 

More from mtoppa (19)

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
 
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?
 
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?
 
Why Do Planes Crash?
Why Do Planes Crash?Why Do Planes Crash?
Why Do Planes Crash?
 
Why Scrum Why Now
Why Scrum Why NowWhy Scrum Why Now
Why Scrum Why Now
 

Recently uploaded

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 

Recently uploaded (20)

How Tech Giants Cut Corners to Harvest Data for A.I.
How Tech Giants Cut Corners to Harvest Data for A.I.How Tech Giants Cut Corners to Harvest Data for A.I.
How Tech Giants Cut Corners to Harvest Data for A.I.
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 

Dependency Injection for Wordpress

  • 1. Dependency Injection for WordPress Plugin Development Mike Toppa WordCamp Nashville April 21, 2012 #wcn12 www.toppa.com @mtoppa
  • 2. Mike Toppa ● Director of Development, WebDevStudios ● 17 years of experience in web development, project management, and team management ● Universities: Georgetown, Stanford, Penn ● Dot coms: E*Trade, Ask Jeeves ● Start-ups: Finexa, Kai's Candy Co ● WordPress development for non-profits www.toppa.com @mtoppa
  • 4. We want code to be... ● Easy to understand ● Easy to change ● Reusable (DRY) ● Bug free www.toppa.com @mtoppa
  • 5. So why is it usually like this? “O.P.C” http://abstrusegoose.com/432
  • 6. It happens because we are always in a hurry, and requirements are always changing. www.toppa.com @mtoppa
  • 7. But coding fast and dirty only makes us slower in the long run. www.toppa.com @mtoppa
  • 8. “We like to think we spend our time power typing, but we actually spend most of our time staring into the abyss.” - Douglas Crockford principal discoverer of JSON, Creator of JSLint www.toppa.com @mtoppa
  • 9. The ratio of time spent reading code versus writing is well over 10 to 1. Therefore, making code easy to read makes it easier to write. - Bob Martin Paraphrased from his book Clean Code www.toppa.com @mtoppa
  • 10. Clean code saves time, saves $$ www.toppa.com @mtoppa
  • 11. Clean code techniques ● Using meaningful names ● Don't repeat yourself (DRY) ● Object oriented principles and patterns ● Unit testing, test driven development (TDD) ● The “boy scout rule” ● Vertical slicing ● ...and many more www.toppa.com @mtoppa
  • 12. Clean code techniques ● Using meaningful names ● Don't repeat yourself (DRY) ● Object oriented principles and patterns ● Unit testing, test driven development (TDD) ● The “boy scout rule” ● Vertical slicing ● ...and many more www.toppa.com @mtoppa
  • 13. The SOLID Principles ● Single Responsibility (SRP) ● Open-Closed (OCP) ● Liskov Substitution (LSP) ● Interface Segregation (ISP) ● Dependency Inversion (DIP) www.toppa.com @mtoppa
  • 14. The SOLID Principles ● Single Responsibility (SRP) ● Open-Closed (OCP) ● Liskov Substitution (LSP) ● Interface Segregation (ISP) ● Dependency Inversion (DIP) www.toppa.com @mtoppa
  • 15. Shashin My plugin for displaying albums, photos, and videos from Picasa, Twitpic, and YouTube (and others coming soon) www.toppa.com @mtoppa
  • 16. I used the new version as a test case for applying clean code principles to WordPress plugins www.toppa.com @mtoppa
  • 17.
  • 18.
  • 19.
  • 20.
  • 22. My Shashin plugin consists of 44 classes, each of which has a meaningful name, follows the SRP, and “does one thing” PicasaPhotoDisplayer SettingsMenu YouTubeSynchronizer Uninstall etc. www.toppa.com @mtoppa
  • 23. Shashin example class Admin_ShashinInstall { // ... public function run() { $this->createAlbumTable(); $this->verifyAlbumTable(); $this->createPhotoTable(); $this->verifyPhotoTable(); $this->updateSettings(); return true; } // ... } www.toppa.com @mtoppa
  • 24. Class Autoloading ● The problem: ● PHP lacks an equivalent statement to “import” or “use” for classes ● Having to hardcode a bunch of file paths is extra work, and makes code harder to change ● The solution: ● PHP 5.1.2 and spl_autoload_register() ● PHP Standards Working Group: PSR-0 www.toppa.com @mtoppa
  • 25. PSR-0: Official Description ● Each "_" character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR ● The fully-qualified namespace and class is suffixed with ".php" when loading from the file system ● Alphabetic characters... may be of any combination of lower case and upper case ● ...And other rules about namespaces ● Source: https://github.com/php-fig/fig- standards/blob/master/accepted/PSR-0.md www.toppa.com @mtoppa
  • 26. PSR-0 Example Admin_ShashinInstall is translated to Admin/ShashinInstall.php www.toppa.com @mtoppa
  • 27. Toppa Plugin Libraries Autoloader // this is at the top of the main file for my Shashin plugin require_once dirname(__FILE__) . '/../toppa-plugin-libraries-for- wordpress/ToppaAutoLoaderWp.php'; $shashinAutoLoader = new ToppaAutoLoaderWp('/shashin'); // that's it! I can now call “new” on any class under the shashin folder // and its class file will be automatically loaded www.toppa.com @mtoppa
  • 28. Shashin's capabilities are shaped by how its objects are wired together, through implementation of the Dependency Inversion Principle www.toppa.com @mtoppa
  • 30. 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(); } } } Example from “Agile Software Development”
  • 31. Dependency inversion applied <<interface>> Button SwitchableDevice + poll() + turnOn() + turnOff() Lamp This is the Abstract Server pattern
  • 32. 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(); } } }
  • 33. A web of collaborating objects ● The SRP and DIP together drive 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."
  • 34. Composition (“Has a...”) vs. Inheritance (“Is a...”) www.toppa.com @mtoppa
  • 35. The SRP is about objects that do one thing The DIP is about how to wire them together to create working, flexible software www.toppa.com @mtoppa
  • 36. Never, ever do this class Button { private $lamp; public function __construct() { $this->lamp = new Lamp(); } //... } www.toppa.com @mtoppa
  • 37. Instead, you want to inject the object dependency Dependency injection! www.toppa.com @mtoppa
  • 38. Dependency injection is one of many design patterns for implementing the Dependency inversion principle www.toppa.com @mtoppa
  • 39. It comes in two flavors www.toppa.com @mtoppa
  • 40. Constructor injection public function __construct(SwitchableDevice $switchableDevice) { $this->switchableDevice = $switchableDevice; } www.toppa.com @mtoppa
  • 41. Setter injection public function setSwitchableDevice(SwitchableDevice $switchableDevice) { $this->switchableDevice = $switchableDevice; } www.toppa.com @mtoppa
  • 42. Which to use? It depends www.toppa.com @mtoppa
  • 43. Dependency chains If class A depends on class B, and class B depends on class C, class A should be blissfully unaware of class C www.toppa.com @mtoppa
  • 44. To do this without going insane, you need an injection container www.toppa.com @mtoppa
  • 45. Example from Shashin class Lib_ShashinContainer { // … public function getPhotoRefData() { if (!isset($this->photoRefData)) { $this->photoRefData = new Lib_ShashinPhotoRefData(); } return $this->photoRefData; } public function getClonablePhoto() { if (!isset($this->clonablePhoto)) { $this->getPhotoRefData(); $this->clonablePhoto = new Lib_ShashinPhoto($this->photoRefData); } return $this->clonablePhoto; } www.toppa.com @mtoppa
  • 46. Example continued public function getClonablePhotoCollection() { if (!isset($this->photoCollection)) { $this->getClonablePhoto(); $this->getSettings(); $this->clonablePhotoCollection = new Lib_ShashinPhotoCollection(); $this->clonablePhotoCollection->setClonableDataObject($this->clonablePhoto); $this->clonablePhotoCollection->setSettings($this->settings); } return $this->clonablePhotoCollection; } www.toppa.com @mtoppa
  • 47. Beyond the textbook examples www.toppa.com @mtoppa
  • 48. What to do when you need a new object inside a loop One solution is cloning www.toppa.com @mtoppa
  • 49. Shashin Example 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(); } www.toppa.com @mtoppa
  • 50. 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 www.toppa.com @mtoppa
  • 51. Shashin Example class Public_ShashinLayoutManager { // ... public function setTableBody() { // … for ($i = 0; $i < count($this->collection); $i++) { // ... $dataObjectDisplayer = $this->container->getDataObjectDisplayer( $this->shortcode, $this->collection[$i] ); $this->tableBody .= $dataObjectDisplayer->run(); // ... } www.toppa.com @mtoppa
  • 52. Dependency injection: key benefits ● Makes your object dependencies adaptable to emerging needs ● With an injection container, simplifies managing dependency chains ● Supports “preferring polymorphism to conditionals”, making it easy to add new class subtypes www.toppa.com @mtoppa
  • 53. Will this proliferation of objects eat up all my memory? No www.toppa.com @mtoppa
  • 54. Use dependency injection to instantiate only the objects you need, when you need them www.toppa.com @mtoppa
  • 55. Make immutable objects into properties of the container, so you only need to instantiate them once www.toppa.com @mtoppa
  • 56. PHP 5 has improved memory management “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 www.toppa.com @mtoppa
  • 57. But don't overdo it: avoid needless complexity

Editor's Notes

  1. This means different things to different people Smashing Magazine article compared them in terms of: Structure – short line lengths, indentions Purpose – limericks for humor, not using HTML tables for layout Meaning and Efficiency – how intent is conveyed, how bloat is avoided Perception – perceived as the master&apos;s craft “apex of the written word” - custom wooden staircases parallel But while we can appreciate poetry with hidden meaning and indirection, that&apos;s not what we want in our code
  2. Easy to understand Intention revealing: not just what, but also why Easy to change Adaptable to emerging needs: not fragile, not rigid Reusable (DRY) If we copy and paste, we are creating duplicate code we have to maintain Bug free Broken code costs time, money, and reputation
  3. Tight deadlines Too much work Changing requirements Too many useless meetings Other people&apos;s messy code Our messy code Just make it work and get on to the next thing!
  4. And launching buggy code can cost money and reputation
  5. The exact shape of these lines is hotly debated May projects have ultimately failed because of the steep cost curve of messy code
  6. Design patterns you may know or heard of, are ways of expressing these design principles
  7. To explain dependency injection, I need to explain the DIP, and to explain it, I first need to explain the SRP
  8. I&apos;m going to show SRP and DIP examples of code from Shashin
  9. Clean code books and articles all use other languages as examples – I wanted to try applying them to PHP and WordPress
  10. Shashin supports multiple viewers
  11. There&apos;s a lot going on here. A lot of different data sources and display possibilities to support. How do you keep the code from becoming a tangled mess?
  12. Do one thing, do it well, do it only For methods, this typically means changing the value of only one variable If you are passing more than 2 or 3 arguments into a method, you are probably doing more than one thing For classes, it means having a single conceptual responsibility You want high cohesiveness in a class This is the opposite of how most WordPress plugins are written
  13. The whole class is about 150 lines The run method calls the other methods (this is a simple use of the command pattern) It reads like a table of contents Breaking the functionality down into methods that do one thing makes the code easier to read and to unit test Installation is especially useful to break down into small methods that can have automated tests, as plugin activation is especially difficult to debug
  14. spl_autoloader_register allows you to register a function that will be called when PHP encounters a “new” call, for finding and including the file containing the class. You can register more than one function.
  15. The problem is, this conflicts with WordPress naming conventions
  16. It&apos;s common to see code that hard-wires together all the parts, when those connections could be made more flexible and extensible
  17. This solution violates the DIP Button depends directly on Lamp Button is not reusable It can&apos;t control, for example, a Motor
  18. 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
  19. Not shown here is the interface
  20. Author: Steve Freeman and Nat Pryce
  21. There was one thing that was ok in the naïve example – we were at least passing in the lamp object Instantiating it directly in the class makes your code impossible to unit test
  22. Factory pattern, adapter patter, service locator pattern are others that implement the DIP
  23. 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 More about this in an upcoming slide...
  24. We want loose coupling, not a rigid chain of dependencies that is hard to change
  25. I am making the objects properties of the container, because they happen to be immutable objects, so they are reusable You can see I&apos;m using constructor injection I&apos;ll explain in a minute why I called it a “clonable” photo
  26. 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&apos;t have to worry about forgetting to call a required setter
  27. This was an interesting problem for me with Shashin. It supports multiple media sources (Picasa, etc), multiple viewers (Fancybox, etc), and we could be displaying a photo or an album cover, each of which has different behaviors
  28. Regardless of the type, the layout rules for the thumbnails is always the same So here I&apos;ve injected the container itself getDataObjectDisplayer() uses the passed in arguments to determine which subtype of DataObjectDisplayer to return
  29. The complexity of having 44 classes in Shashin is justified by its need for flexibility You can support a new viewer or a new photo service simply by creating a new subclass. This is much more maintainable and extensible than a single huge file with deeply nested conditionals and unclear dependencies But if I knew I would never need that kind of flexibility, there would be no justification for creating these layers of abstraction – they would just be needless complexity