Object Oriented Programming for WordPress Plugin Development
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Object Oriented Programming for WordPress Plugin Development

on

  • 7,292 views

An introduction to object oriented programming in PHP. This is applicable to WordPress and other CMS/frameworks as well. Note the last half of the slideshow contains the notes for the slides shown in ...

An introduction to object oriented programming in PHP. This is applicable to WordPress and other CMS/frameworks as well. Note the last half of the slideshow contains the notes for the slides shown in the first half.

Statistics

Views

Total Views
7,292
Views on SlideShare
6,141
Embed Views
1,151

Actions

Likes
15
Downloads
130
Comments
1

20 Embeds 1,151

http://www.toppa.com 812
http://channeleaton.com 126
http://notes.channeleaton.com 104
http://local.wordpress.dev 23
http://local.webdoc.com 18
http://memcat.wordpress.com 17
http://feeds.feedburner.com 13
https://twitter.com 13
https://si0.twimg.com 5
http://translate.googleusercontent.com 3
http://channeleaton.test 3
http://channeleaton.wpengine.com 2
http://kkdvaca.wordpress.com 2
http://webcache.googleusercontent.com 2
http://cz.graftonapps.com 2
http://www.onlydoo.com 2
http://channeleaton.tumblr.com 1
https://twimg0-a.akamaihd.net 1
http://us-w1.rockmelt.com 1
http://a0.twimg.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • i want to learn programming but it seems to be so difficult :(
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Object Oriented Programming for WordPress Plugin Development Presentation Transcript

  • 1. Object oriented programming for WordPress plugin development Mike Toppa WordCamp NYC June 9, 2012www.toppa.com @mtoppa
  • 2. www.toppa.com @mtoppa
  • 3. 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, Kais Candy Co● WordPress development for non-profitswww.toppa.com @mtoppa
  • 4. Overview● Nuts and bolts of classes and objects in PHP● The single responsibility principle● The dependency inversion principle● When to prefer OO to procedural programmingwww.toppa.com @mtoppa
  • 5. www.toppa.com @mtoppa
  • 6. Simple exampleclass Lamp { // property declaration private $maxSafeWatts = 100; // method declaration public function getMaxSafeWatts() { return $this->maxSafeWatts; }}---------------------------------------------------------------// instantiate and assign$myLamp = new Lamp();echo $myLamp->getMaxSafeWatts();
  • 7. Rule of thumb: avoid public propertiesclass Lamp { public $maxSafeWatts = 100;}---------------------------------------------$myLamp = new Lamp();// dangerous to allow this!$myLamp->maxSafeWatts = a string to wreck your math;
  • 8. Prefer private propertiesclass Lamp { private $maxSafeWatts = 100; public setMaxSafeWatts($watts) { if (!is_numeric($watts) || $watts > 125 || $watts < 1) { throw New Exception(invalid value for watts); } $this->maxSafeWatts = $watts; return $this->maxSafeWatts; }}-------------------------------------------------------------------$myLamp = new Lamp();$myLamp->setMaxSafeWatts(75);
  • 9. Constructorsclass Lamp { private $bulb; public function __construct($bulb) { $this->bulb = $bulb; }}---------------------------------------------$myLamp = new Lamp(3 way);
  • 10. Type Hintingclass Lamp { private $bulb; public function __construct(Bulb $bulb) { $this->bulb = $bulb; }}---------------------------------------------$myBulb = new Bulb();$myLamp = new Lamp($bulb);
  • 11. Organizing your classeswww.toppa.com @mtoppa
  • 12. Initializing your OO plugin// this is the start.php file for a “Lamp” WP plugin...// require or autoload the “main” class file for your plugin// and then...$lamp = new Lamp();$lamp->run();// thats it!
  • 13. Abstract classes and inheritance Lamp FloorLamp DeskLamp HangingLamp
  • 14. Abstract classes and methodsabstract class Lamp { protected $color; protected $maxSafeWatts; public function setColor($color) { $this->color = $color; return $this->color; } abstract public function setMaxSafeWatts($watts);}
  • 15. Implementing abstract classesclass FloorLamp extends Lamp { public function setMaxSafeWatts($watts) { /* if numeric and less than 150... */ $this->maxSafeWatts = $watts; return $this->maxSafeWatts; }}------------------------------------------------------------------class DeskLamp extends Lamp { public function setMaxSafeWatts($watts) { /* if numeric and less than 100... */ $this->maxSafeWatts = $watts; return $this->maxSafeWatts; }}
  • 16. Interfaces
  • 17. Using interfaces: the facade pattern Functions A PHP facade application interface WordPress Drupal Some other facade facade facade implementation implementation implementation
  • 18. Interface Exampleinterface FunctionsFacade { public function enqueueStylesheet($handle);}------------------------------------------------------------------------class FunctionsFacadeWp implements FunctionsFacade { public function enqueueStylesheet($handle) { return wp_enqueue_style($handle); }}// well look at how to actually use the interface in a few minutes...
  • 19. The SOLID Principles● Single Responsibility (SRP)● Open-Closed (OCP)● Liskov Substitution (LSP)● Interface Segregation (ISP)● Dependency Inversion (DIP)www.toppa.com @mtoppa
  • 20. From LosTechies.com
  • 21. The purpose is to reduce the complexity and fragility of a classwww.toppa.com @mtoppa
  • 22. But what does it mean to do “one thing”?www.toppa.com @mtoppa
  • 23. Cohesionwww.toppa.com @mtoppa
  • 24. Only one reason to changewww.toppa.com @mtoppa
  • 25. Classes ExampleShashinDisplayer.php ShashinAlbumDisplayer.php ShashinAlbumDisplayerPicasa.php ShashinAlbumDisplayerTwitpic.php ShashinAlbumDisplayerFlickr.php ShashinPhotoDisplayer.php ShashinPhotoDisplayerPicasa.php ShashinPhotoDisplayerTwitpic.php ShashinPhotoDisplayerFlickr.php
  • 26. Methods Exampleclass ShashinInstall { public function run() { $this->createAlbumTable(); $this->verifyAlbumTable(); $this->createPhotoTable(); $this->verifyPhotoTable(); $this->updateSettings(); return true; } // ...}
  • 27. From LosTechies.com
  • 28. 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”}
  • 29. Dependency inversion applied <<interface>> Button SwitchableDevice + poll() + turnOn() + turnOff() Lamp This is the Abstract Server pattern
  • 30. SwitchableDevice and Lampinterface SwitchableDevice { public function turnOn(); public function turnOff();}--------------------------------------------------------------class Lamp implements SwitchableDevice { public function turnOn() { // code } public function turnOff() { // code }}
  • 31. Buttonclass Button { private $switchableDevice; public function __construct(SwitchableDevice$switchableDevice) { $this->switchableDevice = $switchableDevice; } public function poll() { if (/* some condition */) { $this->switchableDevice->turnOn(); } }}
  • 32. Using the Button// require or autoload the class files, then...$lamp = new Lamp();$buttonForLamp = new Button($lamp);$buttonforLamp->poll();$motor = new Motor();$buttonForMotor = new Button($motor);$buttonForMotor->poll();
  • 33. Dependency Chains If class A depends on class B, and class B depends on class C, class A should be blissfully unaware of class Cwww.toppa.com @mtoppa
  • 34. To do this without going insane, you need an injection containerwww.toppa.com @mtoppa
  • 35. 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."
  • 36. But dont overdo it:avoid needless complexity
  • 37. When to prefer OOP to procedural programmingwww.toppa.com @mtoppa
  • 38. Object oriented programming for WordPress plugin development Mike Toppa WordCamp NYC June 9, 2012 www.toppa.com @mtoppaSkill levelTheory and practiceWont be an expertWe will be looking at code
  • 39. www.toppa.com @mtoppaWhat Ill cover is not specific to WordPressWhen you write a plugin you are writing softwareYour software should be organized around its use cases, it should not be organized around WordPress architectureThat is, you should not start with something like a “plugin” class. Your classes should be organized around the business problem they are trying to solved, not around the details of WordPress.
  • 40. 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, Kais Candy Co● WordPress development for non-profitswww.toppa.com @mtoppa
  • 41. Overview● Nuts and bolts of classes and objects in PHP● The single responsibility principle● The dependency inversion principle● When to prefer OO to procedural programmingwww.toppa.com @mtoppa
  • 42. www.toppa.com @mtoppa
  • 43. Simple example class Lamp { // property declaration private $maxSafeWatts = 100; // method declaration public function getMaxSafeWatts() { return $this->maxSafeWatts; } } --------------------------------------------------------------- // instantiate and assign $myLamp = new Lamp(); echo $myLamp->getMaxSafeWatts();A class consists of properties, and methods which perform actions, by manipulating those propertiesEncapsulation of related methods and properties. This is what a class really is.Properties and methods have a visibility (public, private, or protected)An object is created by instantiating a class (calling new). Then you typically, assign it to a variable, and call its methods as needed
  • 44. Rule of thumb: avoid public properties class Lamp { public $maxSafeWatts = 100; } --------------------------------------------- $myLamp = new Lamp(); // dangerous to allow this! $myLamp->maxSafeWatts = a string to wreck your math;Public properties can be used and abused by external code at any time.
  • 45. Prefer private properties class Lamp { private $maxSafeWatts = 100; public setMaxSafeWatts($watts) { if (!is_numeric($watts) || $watts > 125 || $watts < 1) { throw New Exception(invalid value for watts); } $this->maxSafeWatts = $watts; return $this->maxSafeWatts; } } ------------------------------------------------------------------- $myLamp = new Lamp(); $myLamp->setMaxSafeWatts(75);By requiring them to be set through a method call, you can control what types of values are valid, and what ranges are valid.
  • 46. Constructors class Lamp { private $bulb; public function __construct($bulb) { $this->bulb = $bulb; } } --------------------------------------------- $myLamp = new Lamp(3 way);The constructor is a special method, used for initializing a class.Its optional – is called when you call “new”A constructor does not return anythingIt should be used for getting a class into a valid initial stateA common design mistake is to put a lot of complex logic in the constructor, or call it to execute the objects functionality.
  • 47. Type Hintingclass Lamp { private $bulb; public function __construct(Bulb $bulb) { $this->bulb = $bulb; }}---------------------------------------------$myBulb = new Bulb();$myLamp = new Lamp($bulb);
  • 48. Organizing your classes www.toppa.com @mtoppaOne class per file, and the file name should match the class nameGive the class a meaningful name and its methods meaningful namesClass names and property names should be nouns or noun phrasesMethod names should be verbs or verb phrasesGet a real IDE that autocompletes variable names and method names
  • 49. Initializing your OO plugin// this is the start.php file for a “Lamp” WP plugin...// require or autoload the “main” class file for your plugin// and then...$lamp = new Lamp();$lamp->run();// thats it!
  • 50. Abstract classes and inheritance Lamp FloorLamp DeskLamp HangingLamp
  • 51. Abstract classes and methods abstract class Lamp { protected $color; protected $maxSafeWatts; public function setColor($color) { $this->color = $color; return $this->color; } abstract public function setMaxSafeWatts($watts); }An abstract class cannot be implemented directlyIt can also have abstract methods, which must be implemented by the child classProtected methods and properties are essentially private, but can be used by child classes
  • 52. Implementing abstract classesclass FloorLamp extends Lamp { public function setMaxSafeWatts($watts) { /* if numeric and less than 150... */ $this->maxSafeWatts = $watts; return $this->maxSafeWatts; }}------------------------------------------------------------------class DeskLamp extends Lamp { public function setMaxSafeWatts($watts) { /* if numeric and less than 100... */ $this->maxSafeWatts = $watts; return $this->maxSafeWatts; }}
  • 53. InterfacesAn electrical outlet is a great example of an interface. It can power anything designed to plug into it. It doesnt need to know or care about exactly what its connected to.Interfaces define a set of methods a class must implement. Its similar to abstract classes in this way, but there is no inheritance.
  • 54. Using interfaces: the facade pattern Functions A PHP facade application interface WordPress Drupal Some other facade facade facade implementation implementation implementationA different implementation of the facade would allow the PHP application to work outside of WordPress, without touching the applications codeWhen you write a class to implement an interface, it can interact with other classes that know how to talk to that interface, without those other classes having to know anything about your particular implementation of the interface
  • 55. Interface Exampleinterface FunctionsFacade { public function enqueueStylesheet($handle);}------------------------------------------------------------------------class FunctionsFacadeWp implements FunctionsFacade { public function enqueueStylesheet($handle) { return wp_enqueue_style($handle); }}// well look at how to actually use the interface in a few minutes...
  • 56. The SOLID Principles ● Single Responsibility (SRP) ● Open-Closed (OCP) ● Liskov Substitution (LSP) ● Interface Segregation (ISP) ● Dependency Inversion (DIP) www.toppa.com @mtoppaIntroduced by Bob Martin in his book “Agile Software Development”
  • 57. From LosTechies.comApplied to classes and methodsDo one thing, do it well, do it onlyFor methods, this typically means changing the value of only one variableIf you are passing more than 2 or 3 arguments into a method, you are probably doing more than one thingFor classes, it means having a single conceptual responsibility
  • 58. The purpose is to reduce the complexity and fragility of a class www.toppa.com @mtoppaWe want code that is flexible and easy to understand, not brittle and mind-numbing to readWhen a method is manipulating multiple properties and invoking lots of other methods, it can be very hard to test, debug, and change. This is a common reason why developers feel fear when making a change – they dont know what might breakWhen a class has many methods and multiple responsibilities, it can be hard to understand and difficult to refactor
  • 59. But what does it mean to do “one thing”?www.toppa.com @mtoppa
  • 60. Cohesionwww.toppa.com @mtoppa
  • 61. Only one reason to change www.toppa.com @mtoppaA typical example is when business logic is entangled with the user interface. If you want to develop an RSS feed for a web page, and cant create the feed without tearing apart or copying-and-pasting code thats woven into your HTML, then youve got code that has more than one reason to change.
  • 62. Classes Example ShashinDisplayer.php ShashinAlbumDisplayer.php ShashinAlbumDisplayerPicasa.php ShashinAlbumDisplayerTwitpic.php ShashinAlbumDisplayerFlickr.php ShashinPhotoDisplayer.php ShashinPhotoDisplayerPicasa.php ShashinPhotoDisplayerTwitpic.php ShashinPhotoDisplayerFlickr.phpYou can start to see the power of the OO approach hereI can add support for a new photos service by creating a new subclass, instead of having to touch code all over the place, adding a bunch of “if” statements
  • 63. Methods Exampleclass ShashinInstall { public function run() { $this->createAlbumTable(); $this->verifyAlbumTable(); $this->createPhotoTable(); $this->verifyPhotoTable(); $this->updateSettings(); return true; } // ...}
  • 64. From LosTechies.comIts common to see code that hard-wires together all the parts, when those connections could be made more flexible and extensible
  • 65. 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” }This solution violates the DIP● Button depends directly on Lamp● Button is not reusable ● It cant control, for example, a Motor
  • 66. Dependency inversion applied <<interface>> Button SwitchableDevice + poll() + turnOn() + turnOff() Lamp This is the Abstract Server patternWhat it meansNeither Button nor Lamp “own” the interfaceButtons can now control any device that implements SwitchableDeviceLamps and other SwitchableDevices can now be controlled by any object that accepts a SwitchableDevice
  • 67. SwitchableDevice and Lampinterface SwitchableDevice { public function turnOn(); public function turnOff();}--------------------------------------------------------------class Lamp implements SwitchableDevice { public function turnOn() { // code } public function turnOff() { // code }}
  • 68. Buttonclass Button { private $switchableDevice; public function __construct(SwitchableDevice$switchableDevice) { $this->switchableDevice = $switchableDevice; } public function poll() { if (/* some condition */) { $this->switchableDevice->turnOn(); } }}
  • 69. Using the Button// require or autoload the class files, then...$lamp = new Lamp();$buttonForLamp = new Button($lamp);$buttonforLamp->poll();$motor = new Motor();$buttonForMotor = new Button($motor);$buttonForMotor->poll();
  • 70. Dependency Chains If class A depends on class B, and class B depends on class C, class A should be blissfully unaware of class Cwww.toppa.com @mtoppa
  • 71. To do this without going insane, you need an injection containerwww.toppa.com @mtoppa
  • 72. 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."Author: Steve Freeman and Nat Pryce
  • 73. But dont overdo it: avoid needless complexityThe complexity of having 44 classes in Shashin is justified by its need for flexibilityYou 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 dependenciesBut 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
  • 74. When to prefer OOP to procedural programming www.toppa.com @mtoppaThis can be subjective. For me, it hurts my brain to program procedurally, even for small projects.For a very small project, OO will usually involve more codeIf you can classify the components of an application into objects with properties and methods, and you have an idea of what kind of changes will come in the future, an OO approach is very powerful.Also, if you want to do unit testing, you need OO code