SlideShare a Scribd company logo
Coming to Terms with
OOP in Drupal
Chris Tankersley
php[world] 2016
php[world] 2016 1
In the beginning…
function mymodule_modules_enabled($modules) {
// Stuff happens
}
function mymodule_menu() {
return array(
// …
);
}
php[world] 2016 2
Procedural Programming
• Code is kept in Procedures (functions)
• Procedures contain steps to be carried out
php[world] 2016 3
Why don’t people like it?
• Can be hard to test
• Can be hard to isolate
• Can be hard to name functions succinctly
• Can be hard to organize
• Can be hard to share
• Nearly impossible to modify original, 3rd party code
php[world] 2016 4
Why do we want OOP?
• Better ability to test
• Better architecture through code encapsulation
• With Namespaces, better naming
• The ability to share code that can be extended
php[world] 2016 5
Vocabulary
• Class – Textual representation of how an object is made up
• Object – Variable built from a class that holds data and performs
actions
php[world] 2016 6
php[world] 2016 7
Class
class Employee {
protected $name;
protected $number;
public function setData($data) {
$this->name = $data['name'];
$this->number = $data['number'];
}
public function viewData() {
echo <<<ENDTEXT
Name: {$this->name}
Number: {$this->number}
ENDTEXT;
}
}
Object
<?php
$manager= new Employee();
// ^
// |
// `--- This is the Object
php[world] 2016 8
php[world] 2016 9
Methods and Properties
class Employee {
protected $name; // This is a property
protected $number;
// This is a Method
public function setData($data) {
$this->name = $data['name'];
$this->number = $data['number'];
}
public function viewData() {
echo <<<ENDTEXT
Name: {$this->name}
Number: {$this->number}
ENDTEXT;
}
}
New Vocabulary
• Property – Data inside of an object
• Method – Function inside of an object
• Both are accessed using the -> notation
php[world] 2016 10
Visibility
• Public – Anyone can access the property/method
• Protected – Only the class, or child classes, can access
• Private – Only the class itself can access
php[world] 2016 11
php[world] 2016 12
Class
class Employee {
public $name; // Anyone can access this
protected $number; // Only itself, and children can access
private $ssn; // Only itself can access this
// Anyone can call this method
public function setData($data) {
$this->name = $data['name'];
$this->number = $data['number'];
}
public function viewData() {
echo <<<ENDTEXT
Name: {$this->name}
Number: {$this->number}
ENDTEXT;
}
}
Object
<?php
$manager= new Employee();
$manager->name = ‘Bob’;
$manager->number = 1234;
// PHP Fatal error: Cannot access protected
property Employee::$number
php[world] 2016 13
Extending Classes
• Inheritance
• Composition
php[world] 2016 14
Namespaces
• Sets up “packages” of code for organization
• Is a “path” separated by 
• Allows us to have classes with simple, clear names and avoid naming
collisions
php[world] 2016 15
namespace DrupalblockEntity;
class Block {
}
php[world] 2016 16
$block = new DrupalblockEntityBlock();
php[world] 2016 17
use DrupalblockEntityBlock;
use MyNamespaceblockEntityBlock as MyBlock;
$block = new Block();
$my_block = new MyBlock();
php[world] 2016 18
Inheritance
php[world] 2016 19
The first thing most people learn
• Classes are “things” in the real world
• We should construct class properties based on Attributes
• Number of wheels
• Sound it makes
• We should construct class methods based on “Actions”
• Running
• Speaking
• Jumping
php[world] 2016 20
New Vocabulary
• Parent Class – Class that is extended
• Child Class – Class that is extending another class
In PHP, a class can be both a Child and a Parent at the same time
php[world] 2016 21
Our Structure
php[world] 2016 22
Employee
Manager Scientist Laborer
The Employee Class
php[world] 2016 23
abstract class Employee {
protected $name; // Employee Name
protected $number; // Employee Number
public function setData($data) {
$this->name = $data['name'];
$this->number = $data['number'];
}
public function viewData() {
echo <<<ENDTEXT
Name: {$this->name}
Number: {$this->number}
ENDTEXT;
}
}
The Manager Class
php[world] 2016 24
class Manager extends Employee {
protected $title; // Employee Title
protected $dues; // Golf Dues
public function setData($data) {
parent::setData($data);
$this->title = $data['title'];
$this->dues = $data['dues'];
}
public function viewData() {
parent::viewData();
echo <<<ENDTEXT
Title: {$this->title}
Golf Dues: {$this->dues}
ENDTEXT;
}
}
The Scientist Class
php[world] 2016 25
class Scientist extends Employee {
protected $pubs; // Number of Publications
public function setData($data) {
parent::setData($data);
$this->pubs = $data['pubs'];
}
public function viewData() {
parent::viewData();
echo <<<ENDTEXT
Publications: {$this->pubs}
ENDTEXT;
}
}
The Laborer Class
php[world] 2016 26
class Laborer extends Employee {
}
What does this teach us?
• Inheritance
• Makes it easier to group code together and share it amongst classes
• Allows us to extend code as needed
• PHP allows Single inheritance
php[world] 2016 27
We use it all the time
namespace DrupalblockEntity;
use DrupalCoreConfigEntityConfigEntityBase;
use DrupalblockBlockInterface;
use DrupalCoreEntityEntityWithPluginCollectionInterface;
class Block extends ConfigEntityBase, implements BlockInterface, EntityWithPluginCollectionInterface {
protected $id;
protected $settings;
// …
public function getRegion() {
return $this->region;
}
// …
}
php[world] 2016 28
Why it Works (Most of the time, Kinda)
• Allows us to extend things we didn’t necessarily create
• Encourages code re-use
• Allows developers to abstract away things
php[world] 2016 29
Why can Inheritance Be Bad
• PHP only allows Single Inheritance on an Class
• You can have a series of Inheritance though, for example CEO extends
Manager, Manager extends Employee
• Long inheritance chains can be a code smell
• Private members and methods cannot be used by Child classes
• Single Inheritance can make it hard to ‘bolt on’ new functionality
between disparate classes
php[world] 2016 30
Composition
php[world] 2016 31
The General Idea
• Classes contain other classes to do work and extend that way, instead
of through Inheritance
• Interfaces define “contracts” that objects will adhere to
• Your classes implement interfaces to add needed functionality
php[world] 2016 32
Interfaces
interface EmployeeInterface {
protected $name;
protected $number;
public function getName();
public function setName($name);
public function getNumber();
public function setNumber($number);
}
interface ManagerInterface {
protected $golfHandicap;
public function getHandicap();
public function setHandicap($handicap);
}
php[world] 2016 33
Interface Implementation
class Employee implements EmployeeInterface {
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
}
class Manager implements EmployeeInterface, ManagerInterface {
// defines the employee getters/setters as well
public function getHandicap() {
return $this->handicap;
}
public function setHandicap($handicap) {
$this->handicap = $handicap;
}
}
php[world] 2016 34
This is Good and Bad
• “HAS-A” is tends to be more flexible than “IS-A”
• Somewhat easier to understand, since there isn’t a hierarchy you
have to backtrack
• Each class must provide their own Implementation, so can lead to
code duplication
php[world] 2016 35
Traits
• Allows small blocks of code to be defined that can be used by many
classes
• Useful when abstract classes/inheritance would be cumbersome
• My Posts and Pages classes shouldn’t need to extend a Slugger class just to
generate slugs.
php[world] 2016 36
Avoid Code-Duplication with Traits
trait EmployeeTrait {
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
}
class Employee implements EmployeeInterface {
use EmployeeTrait;
}
class Manager implements EmployeeInterface, ManagerInterface {
use EmployeeTrait;
use ManagerTrait;
}
php[world] 2016 37
Taking Advantage of OOP
php[world] 2016 38
Coupling
php[world] 2016 39
What is Coupling?
• Coupling is how dependent your code is on another class
• The more classes you are coupled to, the more changes affect your
class
php[world] 2016 40
class Block extends ConfigEntityBase, implements BlockInterface,
EntityWithPluginCollectionInterface {
public function getPlugin() {
return $this->getPluginCollection()->get($this->plugin);
}
protected function getPluginCollection() {
if (!$this->pluginCollection) {
$this->pluginCollection = new BlockPluginCollection(
Drupal::service('plugin.manager.block'),
$this->plugin,
$this->get('settings'),
$this->id());
}
return $this->pluginCollection;
}
}
php[world] 2016 41
Law of Demeter
php[world] 2016 42
Dependency Injection
php[world] 2016 43
What is Dependency Injection?
• Injecting dependencies into classes, instead of having the class create
it
• Allows for much easier testing
• Allows for a much easier time swapping out code
• Reduces the coupling that happens between classes
php[world] 2016 44
Method Injection
class MapService {
public function getLatLong(GoogleMaps $map, $street, $city, $state) {
return $map->getLatLong($street . ' ' . $city . ' ' . $state);
}
public function getAddress(GoogleMaps $map, $lat, $long) {
return $map->getAddress($lat, $long);
}
}
php[world] 2016 45
Constructor Injection
class MapService {
protected $map;
public function __construct(GoogleMaps $map) {
$this->map = $map;
}
public function getLatLong($street, $city, $state) {
return $this
->map
->getLatLong($street . ' ' . $city . ' ' . $state);
}
}
php[world] 2016 46
Setter Injection
class MapService {
protected $map;
public function setMap(GoogleMaps $map) {
$this->map = $map;
}
public function getMap() {
return $this->map;
}
public function getLatLong($street, $city, $state) {
return $this->getMap()->getLatLong($street . ' ' . $city . ' ' . $state);
}
}
php[world] 2016 47
Single Responsibility Principle
php[world] 2016 48
Single Responsibility Principle
• Every class should have a single responsibility, and that responsibility
should be encapsulated in that class
php[world] 2016 49
What is a Responsibility?
• Responsibility is a “Reason To Change” – Robert C. Martin
• By having more than one “Reason to Change”, code is harder to
maintain and becomes coupled
• Since the class is coupled to multiple responsibilities, it becomes
harder for the class to adapt to any one responsibility
php[world] 2016 50
An Example
/**
* Create a new invoice instance.
*
* @param LaravelCashierContractsBillable $billable
* @param object
* @return void
*/
public function __construct(BillableContract $billable, $invoice)
{
$this->billable = $billable;
$this->files = new Filesystem;
$this->stripeInvoice = $invoice;
}
/**
* Create an invoice download response.
*
* @param array $data
* @param string $storagePath
* @return SymfonyComponentHttpFoundationResponse
*/
public function download(array $data, $storagePath = null)
{
$filename = $this->getDownloadFilename($data['product']);
$document = $this->writeInvoice($data, $storagePath);
$response = new Response($this->files->get($document), 200, [
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename="'.$filename.'"',
'Content-Transfer-Encoding' => 'binary',
'Content-Type' => 'application/pdf',
]);
$this->files->delete($document);
return $response;
}
php[world] 2016 51
https://github.com/laravel/cashier/blob/master/src/Laravel/Cashier/Invoice.php
Why is this Bad?
• This single class has the following responsibilities:
• Generating totals for the invoice (including discounts/coupons)
• Generating an HTML View of the invoice (Invoice::view())
• Generating a PDF download of the invoice(Invoice::download())
• This is coupled to a shell script as well
• Two different displays handled by the class. Adding more means more
responsibility
• Coupled to a specific HTML template, the filesystem, the Laravel
Views system, and PhantomJS via the shell script
php[world] 2016 52
How to Improve
• Change responsibility to just building the invoice data
• Move the ‘output’ stuff to other classes
php[world] 2016 53
Unit Testing
php[world] 2016 54
This is not a testing talk
• Using Interfaces makes it easier to mock objects
• Reducing coupling and following Demeter’s Law makes you have to
mock less objects
• Dependency Injection means you only mock what you need for that
test
• Single Responsibility means your test should be short and sweet
• Easier testing leads to more testing
php[world] 2016 55
Additional Resources
• Clean Code – Robert C. Martin
• PHP Objects, Patterns, and Practice – Matt Zandstra
php[world] 2016 56
Thank You!
• Software Engineer, InQuest
• Co-Host of “Jerks Talk Games”
• http://jerkstalkgames.com
• Author of “Docker for Developers”
• https://leanpub.com/dockerfordevs
• http://ctankersley.com
• chris@ctankersley.com
• @dragonmantank
php[world] 2016 57

More Related Content

What's hot

Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Jitendra Kumar Gupta
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Fabien Potencier
 

What's hot (20)

Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
Php 101: PDO
Php 101: PDOPhp 101: PDO
Php 101: PDO
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...
 
Magento code audit
Magento code auditMagento code audit
Magento code audit
 
Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017Demystifying Object-Oriented Programming - PHP UK Conference 2017
Demystifying Object-Oriented Programming - PHP UK Conference 2017
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
Web 10 | PHP with MySQL
Web 10 | PHP with MySQLWeb 10 | PHP with MySQL
Web 10 | PHP with MySQL
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 
Cfphp Zce 01 Basics
Cfphp Zce 01 BasicsCfphp Zce 01 Basics
Cfphp Zce 01 Basics
 
Web 8 | Introduction to PHP
Web 8 | Introduction to PHPWeb 8 | Introduction to PHP
Web 8 | Introduction to PHP
 
Web 9 | OOP in PHP
Web 9 | OOP in PHPWeb 9 | OOP in PHP
Web 9 | OOP in PHP
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
PHP Traits
PHP TraitsPHP Traits
PHP Traits
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18Demystifying Object-Oriented Programming #phpbnl18
Demystifying Object-Oriented Programming #phpbnl18
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 

Viewers also liked

Viewers also liked (13)

Docker for Developers - PNWPHP 2016 Workshop
Docker for Developers - PNWPHP 2016 WorkshopDocker for Developers - PNWPHP 2016 Workshop
Docker for Developers - PNWPHP 2016 Workshop
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
WTF Is Rancher?
WTF Is Rancher?WTF Is Rancher?
WTF Is Rancher?
 
MSDevCon 2016 DevOps Impact on Architecture
MSDevCon 2016 DevOps Impact on ArchitectureMSDevCon 2016 DevOps Impact on Architecture
MSDevCon 2016 DevOps Impact on Architecture
 
A Brief History of Open Source
A Brief History of Open SourceA Brief History of Open Source
A Brief History of Open Source
 
Flusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous DeliveryFlusso Continuous Integration & Continuous Delivery
Flusso Continuous Integration & Continuous Delivery
 
Deploying Containers with Rancher
Deploying Containers with RancherDeploying Containers with Rancher
Deploying Containers with Rancher
 
CI/CD with Jenkins and Docker - DevOps Meetup Day Thailand
CI/CD with Jenkins and Docker - DevOps Meetup Day ThailandCI/CD with Jenkins and Docker - DevOps Meetup Day Thailand
CI/CD with Jenkins and Docker - DevOps Meetup Day Thailand
 
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
Scaling Jenkins with Docker: Swarm, Kubernetes or Mesos?
 
Pipeline: Continuous Delivery as Code in Jenkins 2.0
Pipeline: Continuous Delivery as Code in Jenkins 2.0Pipeline: Continuous Delivery as Code in Jenkins 2.0
Pipeline: Continuous Delivery as Code in Jenkins 2.0
 
Jenkins Pipelines
Jenkins PipelinesJenkins Pipelines
Jenkins Pipelines
 
Delivery Pipeline as Code: using Jenkins 2.0 Pipeline
Delivery Pipeline as Code: using Jenkins 2.0 PipelineDelivery Pipeline as Code: using Jenkins 2.0 Pipeline
Delivery Pipeline as Code: using Jenkins 2.0 Pipeline
 
Docker for PHP Developers - Jetbrains
Docker for PHP Developers - JetbrainsDocker for PHP Developers - Jetbrains
Docker for PHP Developers - Jetbrains
 

Similar to Coming to Terms with OOP In Drupal - php[world] 2016

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
jsmith92
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
Alexei Gorobets
 

Similar to Coming to Terms with OOP In Drupal - php[world] 2016 (20)

OOP Is More Than Cars and Dogs
OOP Is More Than Cars and DogsOOP 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 OOP is more than Cars and Dogs
OOP is more than Cars and Dogs
 
Migration from Procedural to OOP
Migration from Procedural to OOP Migration from Procedural to OOP
Migration from Procedural to OOP
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017Demystifying Object-Oriented Programming - PHP[tek] 2017
Demystifying Object-Oriented Programming - PHP[tek] 2017
 
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
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016Demystifying Object-Oriented Programming - ZendCon 2016
Demystifying Object-Oriented Programming - ZendCon 2016
 
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering CollegeObject Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
Object Oriented PHP by Dr.C.R.Dhivyaa Kongu Engineering College
 
UNIT III (8).pptx
UNIT III (8).pptxUNIT III (8).pptx
UNIT III (8).pptx
 
UNIT III (8).pptx
UNIT III (8).pptxUNIT III (8).pptx
UNIT III (8).pptx
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
Lecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptxLecture 17 - PHP-Object-Orientation.pptx
Lecture 17 - PHP-Object-Orientation.pptx
 
PHP OOP Lecture - 04.pptx
PHP OOP Lecture - 04.pptxPHP OOP Lecture - 04.pptx
PHP OOP Lecture - 04.pptx
 
Part 2
Part 2Part 2
Part 2
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
Quality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStormQuality assurance for php projects with PHPStorm
Quality assurance for php projects with PHPStorm
 
PHP OOP Lecture - 02.pptx
PHP OOP Lecture - 02.pptxPHP OOP Lecture - 02.pptx
PHP OOP Lecture - 02.pptx
 

More from Chris Tankersley

More from Chris Tankersley (20)

Docker is Dead: Long Live Containers
Docker is Dead: Long Live ContainersDocker is Dead: Long Live Containers
Docker is Dead: Long Live Containers
 
Bend time to your will with git
Bend time to your will with gitBend time to your will with git
Bend time to your will with git
 
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)
 
Dead Simple APIs with OpenAPI
Dead Simple APIs with OpenAPIDead Simple APIs with OpenAPI
Dead Simple APIs with OpenAPI
 
Killer Docker Workflows for Development
Killer Docker Workflows for DevelopmentKiller Docker Workflows for Development
Killer Docker Workflows for Development
 
You Got Async in my PHP!
You Got Async in my PHP!You Got Async in my PHP!
You Got Async in my PHP!
 
Docker for Developers - PHP Detroit 2018
Docker for Developers - PHP Detroit 2018Docker for Developers - PHP Detroit 2018
Docker for Developers - PHP Detroit 2018
 
Docker for Developers
Docker for DevelopersDocker for Developers
Docker for Developers
 
They are Watching You
They are Watching YouThey are Watching You
They are Watching You
 
BASHing at the CLI - Midwest PHP 2018
BASHing at the CLI - Midwest PHP 2018BASHing at the CLI - Midwest PHP 2018
BASHing at the CLI - Midwest PHP 2018
 
You Were Lied To About Optimization
You Were Lied To About OptimizationYou Were Lied To About Optimization
You Were Lied To About Optimization
 
Docker for PHP Developers - php[world] 2017
Docker for PHP Developers - php[world] 2017Docker for PHP Developers - php[world] 2017
Docker for PHP Developers - php[world] 2017
 
Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017
 
Docker for Developers - php[tek] 2017
Docker for Developers - php[tek] 2017Docker for Developers - php[tek] 2017
Docker for Developers - php[tek] 2017
 
Why Docker? Dayton PHP, April 2017
Why Docker? Dayton PHP, April 2017Why Docker? Dayton PHP, April 2017
Why Docker? Dayton PHP, April 2017
 
From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017
 
Docker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHPDocker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHP
 
How We Got Here: A Brief History of Open Source
How We Got Here: A Brief History of Open SourceHow We Got Here: A Brief History of Open Source
How We Got Here: A Brief History of Open Source
 
Docker for PHP Developers - ZendCon 2016
Docker for PHP Developers - ZendCon 2016Docker for PHP Developers - ZendCon 2016
Docker for PHP Developers - ZendCon 2016
 
From Docker to Production - ZendCon 2016
From Docker to Production - ZendCon 2016From Docker to Production - ZendCon 2016
From Docker to Production - ZendCon 2016
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Peter Udo Diehl
 

Recently uploaded (20)

JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 

Coming to Terms with OOP In Drupal - php[world] 2016

  • 1. Coming to Terms with OOP in Drupal Chris Tankersley php[world] 2016 php[world] 2016 1
  • 2. In the beginning… function mymodule_modules_enabled($modules) { // Stuff happens } function mymodule_menu() { return array( // … ); } php[world] 2016 2
  • 3. Procedural Programming • Code is kept in Procedures (functions) • Procedures contain steps to be carried out php[world] 2016 3
  • 4. Why don’t people like it? • Can be hard to test • Can be hard to isolate • Can be hard to name functions succinctly • Can be hard to organize • Can be hard to share • Nearly impossible to modify original, 3rd party code php[world] 2016 4
  • 5. Why do we want OOP? • Better ability to test • Better architecture through code encapsulation • With Namespaces, better naming • The ability to share code that can be extended php[world] 2016 5
  • 6. Vocabulary • Class – Textual representation of how an object is made up • Object – Variable built from a class that holds data and performs actions php[world] 2016 6
  • 7. php[world] 2016 7 Class class Employee { protected $name; protected $number; public function setData($data) { $this->name = $data['name']; $this->number = $data['number']; } public function viewData() { echo <<<ENDTEXT Name: {$this->name} Number: {$this->number} ENDTEXT; } }
  • 8. Object <?php $manager= new Employee(); // ^ // | // `--- This is the Object php[world] 2016 8
  • 9. php[world] 2016 9 Methods and Properties class Employee { protected $name; // This is a property protected $number; // This is a Method public function setData($data) { $this->name = $data['name']; $this->number = $data['number']; } public function viewData() { echo <<<ENDTEXT Name: {$this->name} Number: {$this->number} ENDTEXT; } }
  • 10. New Vocabulary • Property – Data inside of an object • Method – Function inside of an object • Both are accessed using the -> notation php[world] 2016 10
  • 11. Visibility • Public – Anyone can access the property/method • Protected – Only the class, or child classes, can access • Private – Only the class itself can access php[world] 2016 11
  • 12. php[world] 2016 12 Class class Employee { public $name; // Anyone can access this protected $number; // Only itself, and children can access private $ssn; // Only itself can access this // Anyone can call this method public function setData($data) { $this->name = $data['name']; $this->number = $data['number']; } public function viewData() { echo <<<ENDTEXT Name: {$this->name} Number: {$this->number} ENDTEXT; } }
  • 13. Object <?php $manager= new Employee(); $manager->name = ‘Bob’; $manager->number = 1234; // PHP Fatal error: Cannot access protected property Employee::$number php[world] 2016 13
  • 14. Extending Classes • Inheritance • Composition php[world] 2016 14
  • 15. Namespaces • Sets up “packages” of code for organization • Is a “path” separated by • Allows us to have classes with simple, clear names and avoid naming collisions php[world] 2016 15
  • 17. $block = new DrupalblockEntityBlock(); php[world] 2016 17
  • 18. use DrupalblockEntityBlock; use MyNamespaceblockEntityBlock as MyBlock; $block = new Block(); $my_block = new MyBlock(); php[world] 2016 18
  • 20. The first thing most people learn • Classes are “things” in the real world • We should construct class properties based on Attributes • Number of wheels • Sound it makes • We should construct class methods based on “Actions” • Running • Speaking • Jumping php[world] 2016 20
  • 21. New Vocabulary • Parent Class – Class that is extended • Child Class – Class that is extending another class In PHP, a class can be both a Child and a Parent at the same time php[world] 2016 21
  • 22. Our Structure php[world] 2016 22 Employee Manager Scientist Laborer
  • 23. The Employee Class php[world] 2016 23 abstract class Employee { protected $name; // Employee Name protected $number; // Employee Number public function setData($data) { $this->name = $data['name']; $this->number = $data['number']; } public function viewData() { echo <<<ENDTEXT Name: {$this->name} Number: {$this->number} ENDTEXT; } }
  • 24. The Manager Class php[world] 2016 24 class Manager extends Employee { protected $title; // Employee Title protected $dues; // Golf Dues public function setData($data) { parent::setData($data); $this->title = $data['title']; $this->dues = $data['dues']; } public function viewData() { parent::viewData(); echo <<<ENDTEXT Title: {$this->title} Golf Dues: {$this->dues} ENDTEXT; } }
  • 25. The Scientist Class php[world] 2016 25 class Scientist extends Employee { protected $pubs; // Number of Publications public function setData($data) { parent::setData($data); $this->pubs = $data['pubs']; } public function viewData() { parent::viewData(); echo <<<ENDTEXT Publications: {$this->pubs} ENDTEXT; } }
  • 26. The Laborer Class php[world] 2016 26 class Laborer extends Employee { }
  • 27. What does this teach us? • Inheritance • Makes it easier to group code together and share it amongst classes • Allows us to extend code as needed • PHP allows Single inheritance php[world] 2016 27
  • 28. We use it all the time namespace DrupalblockEntity; use DrupalCoreConfigEntityConfigEntityBase; use DrupalblockBlockInterface; use DrupalCoreEntityEntityWithPluginCollectionInterface; class Block extends ConfigEntityBase, implements BlockInterface, EntityWithPluginCollectionInterface { protected $id; protected $settings; // … public function getRegion() { return $this->region; } // … } php[world] 2016 28
  • 29. Why it Works (Most of the time, Kinda) • Allows us to extend things we didn’t necessarily create • Encourages code re-use • Allows developers to abstract away things php[world] 2016 29
  • 30. Why can Inheritance Be Bad • PHP only allows Single Inheritance on an Class • You can have a series of Inheritance though, for example CEO extends Manager, Manager extends Employee • Long inheritance chains can be a code smell • Private members and methods cannot be used by Child classes • Single Inheritance can make it hard to ‘bolt on’ new functionality between disparate classes php[world] 2016 30
  • 32. The General Idea • Classes contain other classes to do work and extend that way, instead of through Inheritance • Interfaces define “contracts” that objects will adhere to • Your classes implement interfaces to add needed functionality php[world] 2016 32
  • 33. Interfaces interface EmployeeInterface { protected $name; protected $number; public function getName(); public function setName($name); public function getNumber(); public function setNumber($number); } interface ManagerInterface { protected $golfHandicap; public function getHandicap(); public function setHandicap($handicap); } php[world] 2016 33
  • 34. Interface Implementation class Employee implements EmployeeInterface { public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } class Manager implements EmployeeInterface, ManagerInterface { // defines the employee getters/setters as well public function getHandicap() { return $this->handicap; } public function setHandicap($handicap) { $this->handicap = $handicap; } } php[world] 2016 34
  • 35. This is Good and Bad • “HAS-A” is tends to be more flexible than “IS-A” • Somewhat easier to understand, since there isn’t a hierarchy you have to backtrack • Each class must provide their own Implementation, so can lead to code duplication php[world] 2016 35
  • 36. Traits • Allows small blocks of code to be defined that can be used by many classes • Useful when abstract classes/inheritance would be cumbersome • My Posts and Pages classes shouldn’t need to extend a Slugger class just to generate slugs. php[world] 2016 36
  • 37. Avoid Code-Duplication with Traits trait EmployeeTrait { public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } class Employee implements EmployeeInterface { use EmployeeTrait; } class Manager implements EmployeeInterface, ManagerInterface { use EmployeeTrait; use ManagerTrait; } php[world] 2016 37
  • 38. Taking Advantage of OOP php[world] 2016 38
  • 40. What is Coupling? • Coupling is how dependent your code is on another class • The more classes you are coupled to, the more changes affect your class php[world] 2016 40
  • 41. class Block extends ConfigEntityBase, implements BlockInterface, EntityWithPluginCollectionInterface { public function getPlugin() { return $this->getPluginCollection()->get($this->plugin); } protected function getPluginCollection() { if (!$this->pluginCollection) { $this->pluginCollection = new BlockPluginCollection( Drupal::service('plugin.manager.block'), $this->plugin, $this->get('settings'), $this->id()); } return $this->pluginCollection; } } php[world] 2016 41
  • 44. What is Dependency Injection? • Injecting dependencies into classes, instead of having the class create it • Allows for much easier testing • Allows for a much easier time swapping out code • Reduces the coupling that happens between classes php[world] 2016 44
  • 45. Method Injection class MapService { public function getLatLong(GoogleMaps $map, $street, $city, $state) { return $map->getLatLong($street . ' ' . $city . ' ' . $state); } public function getAddress(GoogleMaps $map, $lat, $long) { return $map->getAddress($lat, $long); } } php[world] 2016 45
  • 46. Constructor Injection class MapService { protected $map; public function __construct(GoogleMaps $map) { $this->map = $map; } public function getLatLong($street, $city, $state) { return $this ->map ->getLatLong($street . ' ' . $city . ' ' . $state); } } php[world] 2016 46
  • 47. Setter Injection class MapService { protected $map; public function setMap(GoogleMaps $map) { $this->map = $map; } public function getMap() { return $this->map; } public function getLatLong($street, $city, $state) { return $this->getMap()->getLatLong($street . ' ' . $city . ' ' . $state); } } php[world] 2016 47
  • 49. Single Responsibility Principle • Every class should have a single responsibility, and that responsibility should be encapsulated in that class php[world] 2016 49
  • 50. What is a Responsibility? • Responsibility is a “Reason To Change” – Robert C. Martin • By having more than one “Reason to Change”, code is harder to maintain and becomes coupled • Since the class is coupled to multiple responsibilities, it becomes harder for the class to adapt to any one responsibility php[world] 2016 50
  • 51. An Example /** * Create a new invoice instance. * * @param LaravelCashierContractsBillable $billable * @param object * @return void */ public function __construct(BillableContract $billable, $invoice) { $this->billable = $billable; $this->files = new Filesystem; $this->stripeInvoice = $invoice; } /** * Create an invoice download response. * * @param array $data * @param string $storagePath * @return SymfonyComponentHttpFoundationResponse */ public function download(array $data, $storagePath = null) { $filename = $this->getDownloadFilename($data['product']); $document = $this->writeInvoice($data, $storagePath); $response = new Response($this->files->get($document), 200, [ 'Content-Description' => 'File Transfer', 'Content-Disposition' => 'attachment; filename="'.$filename.'"', 'Content-Transfer-Encoding' => 'binary', 'Content-Type' => 'application/pdf', ]); $this->files->delete($document); return $response; } php[world] 2016 51 https://github.com/laravel/cashier/blob/master/src/Laravel/Cashier/Invoice.php
  • 52. Why is this Bad? • This single class has the following responsibilities: • Generating totals for the invoice (including discounts/coupons) • Generating an HTML View of the invoice (Invoice::view()) • Generating a PDF download of the invoice(Invoice::download()) • This is coupled to a shell script as well • Two different displays handled by the class. Adding more means more responsibility • Coupled to a specific HTML template, the filesystem, the Laravel Views system, and PhantomJS via the shell script php[world] 2016 52
  • 53. How to Improve • Change responsibility to just building the invoice data • Move the ‘output’ stuff to other classes php[world] 2016 53
  • 55. This is not a testing talk • Using Interfaces makes it easier to mock objects • Reducing coupling and following Demeter’s Law makes you have to mock less objects • Dependency Injection means you only mock what you need for that test • Single Responsibility means your test should be short and sweet • Easier testing leads to more testing php[world] 2016 55
  • 56. Additional Resources • Clean Code – Robert C. Martin • PHP Objects, Patterns, and Practice – Matt Zandstra php[world] 2016 56
  • 57. Thank You! • Software Engineer, InQuest • Co-Host of “Jerks Talk Games” • http://jerkstalkgames.com • Author of “Docker for Developers” • https://leanpub.com/dockerfordevs • http://ctankersley.com • chris@ctankersley.com • @dragonmantank php[world] 2016 57