Your SlideShare is downloading. ×
0
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Dependency injection
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Dependency injection

3,574

Published on

Apresentação feita no Latinoware 2010 apresentando o conceito de Dependency Injection no PHP 5.3. …

Apresentação feita no Latinoware 2010 apresentando o conceito de Dependency Injection no PHP 5.3.

Esta palestra é uma tradução e simplificação da palestra Dependency Injection in PHP 5.3 de Fabien Potencier.

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,574
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
91
Comments
0
Likes
9
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Dependency Injection no PHP 5.3 Guilherme Blanco – Yahoo!
  • 2. 2 Guilherme Blanco ● 10+ anos como desenvolvedor ● Evangelista Open Source ● Trabalha para Yahoo! ● Contribui para Doctrine, Zend Framework, Symfony e PHP ● No Twitter: @guilhermeblanco ● No GitHub: http://github.com/guilhermeblanco
  • 3. 3 Dependency Injection no PHP 5.3 Um exemplo real na web Esta palestra é uma tradução de: Dependency Injection in PHP 5.3 Concedida pelo autor Fabien Potencier
  • 4. 4 Dependency Injection no PHP 5.3 ● Na maioria das aplicações web, você precisa gerenciar as preferências do usuário: ● A linguagem do usuário ● Se o usuário está autenticado ou não ● As credenciais do usuário ● ...
  • 5. 5 Dependency Injection no PHP 5.3 ● Isto pode ser feito no objeto User (Usuário): ● setLanguage(), getLanguage() ● setAuthenticated(), getAuthenticated() ● addCredential(), hasCredential() ● ...
  • 6. 6 Dependency Injection no PHP 5.3 ● As informações do Usuário precisam ser persistidas entre requisições HTTP ● Nós usamos sessões em PHP para Storage (Armazenagem)
  • 7. 7 Dependency Injection no PHP 5.3 <?php class SessionStorage {   function __construct($cookieName = 'PHP_SESS_ID')   {     session_name($cookieName);     session_start();   }   function set($key, $value)   {     $_SESSION[$key] = $value;   }   // ... }
  • 8. 8 Dependency Injection no PHP 5.3 Muito difícil de customizar Muito fácil de usar <?php class User {   protected $storage;   function __construct()   {     $this­>storage = new SessionStorage();   }   function setLanguage($language)   {     $this­>storage­>set('language', $language);   }   // ... } $user = new User();
  • 9. 9 Dependency Injection no PHP 5.3 Muito fácil de customizar Um pouco mais difícil de usar <?php class User {   protected $storage;   function __construct($storage)   {     $this­>storage = $storage;   } }  $storage = new SessionStorage(); $user = new User($storage);
  • 10. 10 Dependency Injection no PHP 5.3 ● Isto é Dependency Injection (Injeção de Dependência) ● Nada além disso...
  • 11. 11 Dependency Injection no PHP 5.3 ● Vamos entender porque o primeiro exemplo não é uma boa idéia... ● Quero mudar o nome do cookie da sessão do usuário
  • 12. 12 Dependency Injection no PHP 5.3 Hardcode na classe do Usuário <?php class User {   protected $storage;   function __construct()   {     $this­>storage = new SessionStorage('SESSION_ID');   }   function setLanguage($language)   {     $this­>storage­>set('language', $language);   }   // ... } $user = new User();
  • 13. 13 Dependency Injection no PHP 5.3 Adicionar uma variável global? <?php class User {   protected $storage;   function __construct()   {     $this­>storage = new SessionStorage(STORAGE_SESSION_NAME);   } } define('STORAGE_SESSION_NAME', 'SESSION_ID'); $user = new User();
  • 14. 14 Dependency Injection no PHP 5.3 Configurar via Usuário? <?php class User {   protected $storage;   function __construct($sessionName)   {     $this­>storage = new SessionStorage($sessionName);   } } $user = new User('SESSION_ID');
  • 15. 15 Dependency Injection no PHP 5.3 Configurar com um Array? <?php class User {   protected $storage;   function __construct($storageOptions)   {     $this­>storage = new SessionStorage($storageOptions['session_name']);   } } $user = new User(array('session_name' => 'SESSION_ID'));
  • 16. 16 Dependency Injection no PHP 5.3 ● Eu quero mudar a implementação de armazenamento da sessão ● Sistema de Arquivos ● MySQL ● Memcached ● etc
  • 17. 17 Usar uma instância no Registro global? <?php class User {   protected $storage;   function __construct()   {     $this­>storage = Registry::get('session_storage');   } } $storage = new SessionStorage(); Registry::set('session_storage', $storage); $user = new User(); Dependency Injection no PHP 5.3
  • 18. 18 Agora, o Usuário (User) depende do Registro Dependency Injection no PHP 5.3
  • 19. 19 Dependency Injection no PHP 5.3 ● Ao invés da dependência do Storage estar “hardcoded” no construtor da classe Usuário ● Injete a dependência de Storage no objeto Usuário
  • 20. 20 Dependency Injection no PHP 5.3 <?php class User {   protected $storage;   function __construct($storage)   {     $this­>storage = $storage;   } } $storage = new SessionStorage('SESSION_ID'); $user = new User($storage);
  • 21. 21 Dependency Injection no PHP 5.3 Quais as vantagens?
  • 22. 22 Dependency Injection no PHP 5.3 Usar uma estratégia de Storage diferente
  • 23. 23 Uso de uma estratégia diferente de Storage Dependency Injection no PHP 5.3 <?php class User {   protected $storage;   function __construct($storage)   {     $this­>storage = $storage;   } } $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage);
  • 24. 24 Dependency Injection no PHP 5.3 A configuração fica natural
  • 25. 25 A configuração fica natural <?php class User {   protected $storage;   function __construct($storage)   {     $this­>storage = $storage;   } } $storage = new MySQLSessionStorage('SESSION_ID'); $user = new User($storage); Dependency Injection no PHP 5.3
  • 26. 26 Dependency Injection no PHP 5.3 Engloba classes de terceiros (Adapter/Interface)
  • 27. 27 Adiciona uma interface Dependency Injection no PHP 5.3 <?php class User {   protected $storage;   function __construct(SessionStorageInterface $storage)   {     $this­>storage = $storage;   } } interface SessionStorageInterface {   function get($key);   function set($key, $value); }
  • 28. 28 Dependency Injection no PHP 5.3 Mock do objeto Storage (para testes)
  • 29. 29 Dependency Injection no PHP 5.3 Mock de uma Session class User {   protected $storage;   function __construct(SessionStorageInterface $storage)   {     $this­>storage = $storage;   } } class SessionStorageForTests implements SessionStorageInterface {   protected $data = array();   public function set($key, $value)   {     $this­>data[$key] = $value;   }   public function get($key)   {     return $this­>data[$key];   } }
  • 30. 30 Dependency Injection no PHP 5.3 ● Uso de diferentes estratégias de Storage ● Configuração fica natural ● Engloba classes de terceiros (Adapter/Interface) ● Mock do objeto Storage (para testes) ● Fácil sem alterar a classe Usuário (User)
  • 31. 31 Dependency Injection no PHP 5.3 “Dependency Injection é onde os objetos obtém suas dependências através do construtor, métodos ou diretamente nas propriedades” http://www.picocontainer.org/injection.html
  • 32. 32 Dependency Injection no PHP 5.3 <?php $storage = new SessionStorage(); // constructor injection $user = new User($storage); // setter injection $user = new User(); $user­>setStorage($storage); // property injection $user = new User(); $user­>storage = $storage;
  • 33. 33 Dependency Injection no PHP 5.3 Um exemplo web um pouco mais complexo
  • 34. 34 Dependency Injection no PHP 5.3 <?php $request = new Request(); $response = new Response(); $storage = new FileSessionStorage('SESSION_ID'); $user = new User($storage); $cache = new FileCache(   array('dir' => dirname(__FILE__) . '/cache') ); $routing = new Routing($cache);
  • 35. 35 Dependency Injection no PHP 5.3 <?php class Application {   function __construct()   {     $this­>request = new WebRequest();     $this­>response = new WebResponse();     $storage = new FileSessionStorage('SESSION_ID');     $this­>user = new User($storage);     $cache = new FileCache(       array('dir' => dirname(__FILE__).'/cache')     );     $this­>routing = new Routing($cache);   } } $application = new Application();
  • 36. 36 Dependency Injection no PHP 5.3 De volta à estaca zero
  • 37. 37 Dependency Injection no PHP 5.3 <?php class Application {   function __construct()   {     $this­>request = new WebRequest();     $this­>response = new WebResponse();     $storage = new FileSessionStorage('SESSION_ID');     $this­>user = new User($storage);     $cache = new FileCache(       array('dir' => dirname(__FILE__).'/cache')     );     $this­>routing = new Routing($cache);   } } $application = new Application();
  • 38. 38 Dependency Injection no PHP 5.3 ● Nós precisamos de um Container ● Descreve objetos e suas dependências ● Instancia e configura objetos sob demanda
  • 39. 39 Dependency Injection no PHP 5.3 ● Um Container DEVE ser capaz de gerenciar QUALQUER objeto PHP (POPO) ● Os objetos NÃO DEVEM saber que são gerenciados por um Container
  • 40. 40 Dependency Injection no PHP 5.3 ● Parâmetros ● A implementação de SessionStorageInterface que queremos usar (o nome da classe) ● O nome da sessão ● Objetos ● SessionStorage ● User ● Dependências ● Usuário depende de uma implementação de SessionStorageInterface
  • 41. 41 Dependency Injection no PHP 5.3 Vamos criar um simples Container com o PHP 5.3
  • 42. 42 Dependency Injection no PHP 5.3 DIC (Dependency Injection Container) Gerenciando parâmetros
  • 43. 43 Dependency Injection no PHP 5.3 <?php class Container {   protected $parameters = array();   public function setParameter($key, $value)   {     $this­>parameters[$key] = $value;   }   public function getParameter($key)   {     return $this­>parameters[$key];   } }
  • 44. 44 <?php $class = $container­>getParameter('storage_class'); $sessionStorage = new $class($container­>getParameter('session_name')); $user = new User($sessionStorage); <?php $container = new Container(); $container­>setParameter('session_name', 'SESSION_ID'); $container­>setParameter('storage_class', 'SessionStorage'); Dependency Injection no PHP 5.3 Criação de Objeto Customização Desacoplamento
  • 45. 45 Dependency Injection no PHP 5.3 <?php class Container {   protected $parameters = array();   public function __set($key, $value)   {     $this­>parameters[$key] = $value;   }   public function __get($key)   {     return $this­>parameters[$key];   } }
  • 46. 46 Dependency Injection no PHP 5.3 <?php $container = new Container(); $container­>session_name = 'SESSION_ID'; $container­>storage_class = 'SessionStorage'; $sessionStorage = new $container­>storage_class($container­>session_name); $user = new User($sessionStorage); Interface é mais limpa
  • 47. 47 Dependency Injection no PHP 5.3 DIC (Dependency Injection Container) Gerenciando objetos
  • 48. 48 Dependency Injection no PHP 5.3 ● Precisamos de uma forma para descrever como criar objetos, sem na realidade instanciar qualquer coisa! ● Funções anônimas existem para nos salvar!
  • 49. 49 Funções anônimas / Lambdas ● Função anônima é uma função definida diretamente e sem um nome <?php function () { echo 'Hello World'; };
  • 50. 50 Funções anônimas / Lambdas ● Uma lambda pode ser armazenado em uma variável <?php $hello = function () { echo 'Hello World'; };
  • 51. 51 Funções anônimas / Lambdas ● E depois podem ser usadas como qualquer executável PHP <?php $hello(); call_user_func($hello);
  • 52. 52 Funções anônimas / Lambdas ● Você também pode passar uma lambda como um argumento de uma função ou método <?php function foo(Closure $func) {   $func(); } foo($hello);
  • 53. 53 Funções anônimas / Lambdas <?php $hello = function ($name) { echo 'Hello '.$name; }; $hello('Fabien'); call_user_func($hello, 'Fabien'); function foo(Closure $func, $name) {   $func($name); } foo($hello, 'Fabien');
  • 54. 54 Dependency Injection no PHP 5.3 DIC (Dependency Injection Container) Gerenciando objetos
  • 55. 55 Armazene um lambda capaz de criar objetos sob demanda Dependency Injection no PHP 5.3 Notifique a closure para criar um objeto passando um Container class Container {   protected $parameters = array();   protected $objects = array();   public function __set($key, $value)   {     $this­>parameters[$key] = $value;   }   public function __get($key)   {     return $this­>parameters[$key];   }   public function setService($key, Closure $service)   {     $this­>objects[$key] = $service;   }   public function getService($key)   {     return $this­>objects[$key]($this);   } }
  • 56. 56 Dependency Injection no PHP 5.3 <?php $container = new Container(); $container­>session_name = 'SESSION_ID'; $container­>storage_class = 'SessionStorage'; $container­>setService('user', function ($c) {   return new User($c­>getService('storage')); }); $container­>setService('storage', function ($c) {   return new $c­>storage_class($c­>session_name); }); <?php $user = $container­>getService('user');
  • 57. 57 Dependency Injection no PHP 5.3 Simplificando o código
  • 58. 58 Dependency Injection no PHP 5.3 <?php class Container {   protected $values = array();   function __set($id, $value)   {     $this­>values[$id] = $value;   }   function __get($id)   {     if (is_callable($this­>values[$id]))     {       return $this­>values[$id]($this);     }     else     {       return $this­>values[$id];     }   } }
  • 59. 59 Dependency Injection no PHP 5.3 <?php $container = new Container(); $container­>session_name = 'SESSION_ID'; $container­>storage_class = 'SessionStorage'; $container­>user = function ($c) {   return new User($c­>storage); }; $container­>storage = function ($c) {   return new $c­>storage_class($c­>session_name); }; Interface unificada
  • 60. 60 Dependency Injection no PHP 5.3 DIC (Dependency Injection Container) Escopo
  • 61. 61 Dependency Injection no PHP 5.3 ● Para alguns tipos de objetos, como o Usuário, o Container sempre deve retornar a mesma instância <?php spl_object_hash($container­>user) !== spl_object_hash($container­>user);
  • 62. 62 Dependency Injection no PHP 5.3 <?php $container­>user = function ($c) {   static $user;   if (is_null($user))   {     $user = new User($c­>storage);   }   return $user; };
  • 63. 63 Dependency Injection no PHP 5.3 <?php spl_object_hash($container­>user) === spl_object_hash($container­>user);
  • 64. 64 Dependency Injection no PHP 5.3 <?php $container­>user = $container­>asShared(function ($c) {   return new User($c­>storage); });
  • 65. 65 Dependency Injection no PHP 5.3 Uma Closure é uma lambda que lembra seu estado durante sua criação
  • 66. 66 Dependency Injection no PHP 5.3 <?php class Article {   public function __construct($title)   {     $this­>title = $title;   }   public function getTitle()   {     return $this­>title;   } } $articles = array(   new Article('Title 1'),   new Article('Title 2'), );
  • 67. 67 Dependency Injection no PHP 5.3 <?php $mapper = function ($article) {   return $article­>getTitle(); }; $titles = array_map($mapper, $articles);
  • 68. 68 Dependency Injection no PHP 5.3 <?php $method = 'getTitle'; $mapper = function ($article) use($method) {   return $article­>$method(); }; $method = 'getAuthor'; $titles = array_map($mapper, $articles);
  • 69. 69 Dependency Injection no PHP 5.3 <?php $mapper = function ($method) {   return function ($article) use ($method)   {     return $article­>$method();   }; };
  • 70. 70 Dependency Injection no PHP 5.3 <?php $titles = array_map($mapper('getTitle'), $articles); $authors = array_map($mapper('getAuthor'), $articles);
  • 71. 71 Dependency Injection no PHP 5.3 <?php $container­>user = $container­>asShared(function ($c) {   return new User($c­>storage); });
  • 72. 72 Dependency Injection no PHP 5.3 <?php function asShared(Closure $lambda) {   return function ($container) use ($lambda)   {     static $object;     if (is_null($object))     {       $object = $lambda($container);     }     return $object;   }; }
  • 73. 73 Dependency Injection no PHP 5.3 Gerenciamento de erros class Container {   protected $values = array();   function __set($id, $value) {     $this­>values[$id] = $value;   }   function __get($id) {     if ( ! isset($this­>values[$id])) {       throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));     }     if (is_callable($this­>values[$id])) {       return $this­>values[$id]($this);     } else {       return $this­>values[$id];     }   }   function asShared($callable) {     return function ($c) use ($callable) {       static $object;       if (is_null($object)) {         $object = $callable($c);       }       return $object;     };   } }
  • 74. 74 Dependency Injection no PHP 5.3 NÃO estou afirmando para usarem lambdas em todos os lugares Esta apresentação tem o intuito de mostrar como elas funcionam em exemplos práticos
  • 75. 75 Dependency Injection no PHP 5.3 Um DI Container NÃO gerencia TODOS seus objetos
  • 76. 76 Dependency Injection no PHP 5.3 Boa regra para lembrar: Ele gerencia objetos “globais” Objetos com somente uma instância (!= singleton)
  • 77. 77 Dependency Injection no PHP 5.3 COMO Um Usuário, uma Requisição (Request), um Logger, uma conexão com a Base de Dados, ...
  • 78. 78 Dependency Injection no PHP 5.3 E NÃO COMO Objetos de Modelo (um Blog, um Produto, ...)
  • 79. 79 Dependency Injection no PHP 5.3 Lembre-se: Na maioria das vezes, você não precisa de um Container para usar Dependency Injection
  • 80. 80 Dependency Injection no PHP 5.3 Você pode começar a usar e se beneficiar de Dependency Injection hoje
  • 81. 81 Dependency Injection no PHP 5.3 Implementando uma no seu projeto Usando bibliotecas externas que já utilizam DI sem precisa de um Container
  • 82. 82 Dependency Injection no PHP 5.3 Symfony Zend Framework Doctrine ezComponents Swift Mailer ...
  • 83. 83 Dependency Injection no PHP 5.3 ● Symfony Components DependencyInjection ● Usado no core do Symfony 2 (uma das mais rápidas frameworks) ● Flexível (YAML, XML, INI and PHP)
  • 84. 84 Perguntas?

×