the adapter pattern in php
TRANSCRIPT
![Page 1: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/1.jpg)
THE ADAPTER PATTERN
DARREN CRAIG@minusdarren
![Page 2: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/2.jpg)
S.O.L.I.D. OOP
★ Single Responsibility ★ Open / Closed ★ Liskov Substitution Principle ★ Interface Segregation Principle ★ Dependency Inversion Principle
![Page 3: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/3.jpg)
LISKOV SUBSTITUTION PRINCIPLE
“objects in a program should be replaceable with instances of their subtypes without
altering the correctness of that program.”
![Page 4: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/4.jpg)
THE PROBLEM
“Allow users in our system to post updates to Facebook.”
- The Client
![Page 5: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/5.jpg)
WE MEET THEIR REQUIREMENTS
class User
{
public function updateStatus($status)
{
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
}
}
// The Facebook SDK
class Facebook
{
public function updateStatus($status);
}
$user->updateStatus($status);
![Page 6: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/6.jpg)
NEXT…
“Allow users in our system to post updates to Facebook or Twitter”
- The Indecisive Client
![Page 7: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/7.jpg)
WE MEET THEIR REQUIREMENTS
class User{
public function updateStatus($status, $gateway = 'FACEBOOK') {switch($gateway) {
case: "FACEBOOK";$facebook = new Facebook\Facebook;$facebook->updateStatus($status);break;
case: "TWITTER";$twitter = new Twitter\Twitter;$twitter->postStatus($status);break;
}}
}
// The Twitter SDKclass Twitter {
public function postStatus($status);}
$user->updateStatus($status);
![Page 8: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/8.jpg)
“We’re changing the updateStatus()
method to createStatus()”
NEXT…
![Page 9: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/9.jpg)
“We’re changing the updateStatus()
method to createStatus()”
NEXT…
![Page 10: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/10.jpg)
FINE…
class User{
public function updateStatus($status, $gateway = 'FACEBOOK') {switch($gateway) {
case: "FACEBOOK";$facebook = new Facebook\Facebook;$facebook->updateStatus($status);break;
case: "TWITTER";$twitter = new Twitter\Twitter;$twitter->postStatus($status);break;
}}
}
![Page 11: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/11.jpg)
FINE…
class User{
public function updateStatus($status, $gateway = 'FACEBOOK') {switch($gateway) {
case: "FACEBOOK";$facebook = new Facebook\Facebook;$facebook->updateStatus($status);break;
case: "TWITTER";$twitter = new Twitter\Twitter;$twitter->postStatus($status);break;
}}
}
class User{
public function updateStatus($status, $gateway = 'FACEBOOK') {switch($gateway) {
case: "FACEBOOK";$facebook = new Facebook\Facebook;$facebook->createStatus($status);break;
case: "TWITTER";$twitter = new Twitter\Twitter;$twitter->postStatus($status);break;
}}
}
![Page 12: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/12.jpg)
BUT…
class HufflepuffController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
![Page 13: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/13.jpg)
BUT…
class HufflepuffController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
class GryffindoorController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
![Page 14: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/14.jpg)
BUT…
class HufflepuffController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
class GryffindoorController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
class HogwartsController {
public function updateStatus($status, $gateway = 'FACEBOOK') {
switch($gateway) {
case: "FACEBOOK";
$facebook = new Facebook\Facebook;
$facebook->updateStatus($status);
break;
case: "TWITTER";
$twitter = new Twitter\Twitter;
$twitter->postStatus($status);
break;
}
}
}
![Page 15: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/15.jpg)
![Page 16: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/16.jpg)
IT’S A PAIN
★ We should be able to easily add new gateways whenever the client asks
★ We should be able to easily adapt to API changes without too much trouble.
![Page 17: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/17.jpg)
ADAPTERS FTW!
★ We need an interface that defines the functionality required by out application
interface UpdatesStatuses
{
public function post($status);
public function delete($statusId);
}
![Page 18: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/18.jpg)
FACEBOOK ADAPTER
class FacebookAdapter implements UpdatesStatuses
{
private $facebook;
public function __construct(\Facebook\Facebook $facebook)
{
$this->facebook = $facebook;
}
public function post($status)
{
$this->facebook->createStatus($status);
}
public function delete($statusId)
{
$this->facebook->deleteStatus($statusId);
}
}
![Page 19: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/19.jpg)
TWITTER ADAPTER
class TwitterAdapter implements UpdatesStatuses
{
private $twitter;
public function __construct(\Twitter\Twitter $twitter)
{
$this->twitter = $twitter;
}
public function post($status)
{
$this->twitter->postStatus(status);
}
public function delete($statusId)
{
$this->twitter->removeStatus($statusId);
}
}
![Page 20: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/20.jpg)
TAKING IT FURTHER
★ We want users to be able to add several social accounts (connected accounts)
★ When they post using our application, the post should also be shared on all of their social accounts.
![Page 21: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/21.jpg)
SOCIAL ACCOUNTS INTERFACE
interface SocialAccount
{
public function connect();
public function post($post);
// other stuff
}
![Page 22: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/22.jpg)
SOCIAL ACCOUNT CLASSES
class FacebookAccount implements SocialAccount{
public function __construct(Facebook\Facebook $facebook) {$this->facebook = $facebook;
}
public function post($post) {$this->facebook->createPost($post);
}}
class TwitterAccount implements SocialAccount{
public function __construct(Twitter\Twitter $twitter) {$this->twitter = $twitter;
}
public function post($post) {$this->twitter->makePost($post);
}}
class LinkedInAccount implements SocialAccount{
public function __construct(LinkedIn\LinkedIn $linkedin) {$this->linkedin = $linkedin;
}
public function post($post) {$this->linkedin->makePost($post);
}}
![Page 23: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/23.jpg)
THE USER
class User{
private $connectedAccounts = [];
public function addConnectedAccount(SocialAccount $account){
$this->connectedAccounts[] = $account; }
public function postToAccounts($status){
foreach($this->connectedAccounts as $account){
$account->post($status);}
}}
$user->addConnectedAccount(new FacebookAccount(new Facebook\Facebook));$user->addConnectedAccount(new TwitterAccount(new Twitter\Twitter));$user->addConnectedAccount(new LinkedInAccount(new LinkedIn\LinkedIn));
// Sometime in the future.$user->postToAccounts($status)
![Page 24: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/24.jpg)
PRO TIP: IOC - INVERSION OF CONTROL
★ Resolves classes and their dependencies without having to institute them each time
$user->addConnectedAccount(new FacebookAccount(new Facebook\Facebook));
// becomes
$user->addConnectedAccount(new FacebookAccount());
★ Laravel has a built in IoC container ★ A few platform agnostic packages available (Pimple, Dice)
![Page 25: The Adapter Pattern in PHP](https://reader030.vdocument.in/reader030/viewer/2022032504/55c35de2bb61eb686f8b469b/html5/thumbnails/25.jpg)
QUESTIONS?