Your SlideShare is downloading. ×

PHP para Adultos: Clean Code e Object Calisthenics

3,629

Published on

Palestra apresentada no InterconPHP em São Paulo. …

Palestra apresentada no InterconPHP em São Paulo.
Data do evento: 2014-07-19

Published in: Software
0 Comments
55 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,629
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
65
Comments
0
Likes
55
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. TitleText Guilherme
 Blanco PHP4Adults Object Calisthenics Clean Code
  • 2. Guilherme
 Blanco PHP4Adults Who speaks English?
  • 3. Guilherme
 Blanco PHP4Adults "Vamos lá, Sucker! Mexa esse traseiro gordo!" Fucker & Sucker: A Pair of Two Double Cops
  • 4. Guilherme
 Blanco PHP4Adults Guilherme Blanco @guilhermeblanco github.com/guilhermeblanco
  • 5. Guilherme
 Blanco PHP4Adults Instaclick • ~300 empregados • Mais de 67 milhões de usuários 
 (somente em um website) • 12000 requisições/segundo • Nós usamos PHP!
  • 6. Guilherme
 Blanco PHP4Adults Motivação • Legibilidade • Mantenabilidade • Reusabilidade • Testabilidade
  • 7. Guilherme
 Blanco PHP4Adults Resumindo…
  • 8. Guilherme
 Blanco PHP4Adults
  • 9. Guilherme
 Blanco PHP4Adults Clean Code
  • 10. Guilherme
 Blanco PHP4Adults S T U P I Dingleton ightcoupling ntestability rematureoptimization ndescriptivenaming uplication
  • 11. Guilherme
 Blanco PHP4Adults S O L I D ingleresponsibility pen/closeprinciple iskovsubstitution nterfacesegregation ependencyinversion
  • 12. Guilherme
 Blanco PHP4Adults Liskov Substitution Principle
  • 13. Guilherme
 Blanco PHP4Adults ! interface Bird! {! public function setLocation($longitude, $latitude);! ! public function setAltitude($altitude);! ! public function draw();! }!
  • 14. Guilherme
 Blanco PHP4Adults ! class Penguim implements Bird! {! public function setAltitude($altitude)! {! // Do nothing! }! }!
  • 15. Guilherme
 Blanco PHP4Adults ! interface Bird! {! public function setLocation($longitude, $latitude);! ! public function draw($altitude);! }! ! interface FlightfulBird extends Bird! {! ! public function setAltitude($altitude);! }!
  • 16. Guilherme
 Blanco PHP4Adults Dependency Inversion Principle
  • 17. Guilherme
 Blanco PHP4Adults ! namespace DatingUserBundleEntity! {! class User! {! /**! * @var DatingUserBundleEntityImage! */! ! protected $avatar;! }! }! ! namespace DatingMediaBundleEntity! {! class Image! {! /**! * @var DatingUserBundleEntityUser! */! ! protected $owner;! ! }! }
  • 18. Guilherme
 Blanco PHP4Adults ! namespace DatingUserBundleEntity! {! class User! {! /**! * @var AvatarInterface! */! ! protected $avatar;! }! ! interface AvatarInterface! {! // ...! }! }! ! namespace DatingMediaBundleEntity! {! use DatingUserBundleEntityAvatarInterface;! ! class Image implements AvatarInterface! {! /**! * @var DatingUserBundleEntityUser! */! ! protected $owner;! ! }! }!
  • 19. Guilherme
 Blanco PHP4Adults Object Calisthenics Termo grego, significa "exercício"
  • 20. Guilherme
 Blanco PHP4Adults Somente um nível de indentação por método
  • 21. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters='', $validators='', $options='')! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ($input->hasInvalid() || $input->hasMissing()) {! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! if (strpos($message, "empty")) {! throw new Tss_FormException(! "The field {$field} cannot be empty!", ! 3, ! "javascript:history.back();"! );! } else { ! throw new Tss_FormException(! "{$message}", ! 3, ! "javascript:history.back();"! );! }! }! }! }! ! return $input;! }
  • 22. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters='', $validators='', $options='')! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ($input->hasInvalid() || $input->hasMissing()) {! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! if (strpos($message, "empty")) {! throw new Tss_FormException(! "The field {$field} cannot be empty!", ! 3, ! "javascript:history.back();"! );! } else { ! throw new Tss_FormException(! "{$message}", ! 3, ! "javascript:history.back();"! );! }! }! }! }! ! return $input;! } 0 Class prototype 1 2 3 4
  • 23. Guilherme
 Blanco PHP4Adults Early returns
  • 24. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! if (strpos($message, "empty")) {! throw new Tss_FormException(! "The field {$field} cannot be empty!", ! 3, ! "javascript:history.back();"! );! } else { ! throw new Tss_FormException(! "{$message}", ! 3, ! "javascript:history.back();"! );! }! }! }! ! return $input;! } !
  • 25. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! if (strpos($message, "empty")) {! throw new Tss_FormException(! "The field {$field} cannot be empty!", ! 3, ! "javascript:history.back();"! );! } else { ! throw new Tss_FormException(! "{$message}", ! 3, ! "javascript:history.back();"! );! }! }! }! ! return $input;! } ! 0 1 2 3
  • 26. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! $errorMessage = (strpos($message, "empty") === false)! ? "The field {$field} cannot be empty!"! : $message;! ! throw new Tss_FormException(! $errorMessage, ! 3, ! "javascript:history.back();"! );! }! }! ! return $input;! } !
  • 27. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! foreach ($messageList as $message) {! $errorMessage = (strpos($message, "empty") === false)! ? "The field {$field} cannot be empty!"! : $message;! ! throw new Tss_FormException(! $errorMessage, ! 3, ! "javascript:history.back();"! );! }! }! ! return $input;! } ! 0 1 2
  • 28. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! $message = array_shift($messageList);! $errorMessage = (strpos($message, "empty") === false)! ? "The field {$field} cannot be empty!"! : $message;! ! throw new Tss_FormException(! $errorMessage, ! 3, ! "javascript:history.back();"! );! }! ! return $input;! } !
  • 29. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! $message = array_shift($messageList);! $errorMessage = (strpos($message, "empty") === false)! ? "The field {$field} cannot be empty!"! : $message;! ! throw new Tss_FormException(! $errorMessage, ! 3, ! "javascript:history.back();"! );! }! ! return $input;! } ! 0 1 Logical blocks Variable interpolation
  • 30. Guilherme
 Blanco PHP4Adults ! public function validateForm($filters=array(), $validators=array(), $options=null)! { ! $data = $_POST; ! $input = new Zend_Filter_Input($filters, $validators, $data, $options); ! ! $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); ! ! if ( ! ($input->hasInvalid() || $input->hasMissing())) {! ! return $input;! ! }! ! foreach ($input->getMessages() as $field => $messageList) {! $message = array_shift($messageList);! $errorMessage = (strpos($message, "empty") === false)! ? sprintf("The field %s cannot be empty!", $field)! : $message;! ! throw new Tss_FormException(! $errorMessage, ! 3, ! "javascript:history.back();"! );! }! ! return $input;! } !
  • 31. Guilherme
 Blanco PHP4Adults Benefícios • Single Responsibility Principle 
 ("S" de SOLID) • Favorece reusabilidade
  • 32. Guilherme
 Blanco PHP4Adults Não existe "else"
  • 33. Guilherme
 Blanco PHP4Adults ! public function createPost($request)! {! $entity = new Post();! $form = new MyForm($entity);! $form->bind($request);! if ($form->isValid()){! $repository = $this->getRepository('MyBundle:Post');! if (!$repository->exists($entity)) {! $repository->save($entity);! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! return array('form' => $form, 'error' => $error);! } ! } Type-cast Separe o código 
 em blocos.
 
 Considere como
 parágrafos! Espaçamento
  • 34. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 35. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 36. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 37. Guilherme
 Blanco PHP4Adults UML Normal vs. Alternate
 flows
  • 38. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 39. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 40. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ($form->isValid()) {! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! } else {! $error = "Invalid fields";! ! return array('form' => $form, 'error' => $error);! } ! }!
  • 41. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ( ! $form->isValid()) {! return array('form' => $form, 'error' => "Invalid fields");! }! ! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! }!
  • 42. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ( ! $form->isValid()) {! return array('form' => $form, 'error' => "Invalid fields");! }! ! if ( ! $repository->exists($entity)) {! $repository->save($entity);! ! return $this->redirect('create_ok');! } else {! $error = "Post Title already exists";! ! return array('form' => $form, 'error' => $error);! }! }!
  • 43. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ( ! $form->isValid()) {! return array('form' => $form, 'error' => "Invalid fields");! }! ! if ($repository->exists($entity)) {! return array('form' => $form, 'error' => "Post Title already exists");! }! ! $repository->save($entity);! ! return $this->redirect('create_ok');! }
  • 44. Guilherme
 Blanco PHP4Adults ! public function createPost(Request $request)! {! $repository = $this->getRepository('MyBundle:Post');! $entity = new Post();! $form = new MyForm($entity);! ! $form->bind($request);! ! if ( ! $form->isValid()) {! return array('form' => $form, 'error' => "Invalid fields");! }! ! if ($repository->exists($entity)) {! return array('form' => $form, 'error' => "Post Title already exists");! }! ! $repository->save($entity);! ! return $this->redirect('create_ok');! }
  • 45. Guilherme
 Blanco PHP4Adults Benefícios • Evita duplicação de código • Aumenta legibilidade • Reduz cyclomatic complexity
  • 46. Guilherme
 Blanco PHP4Adults Encapsule todos os tipos primitivos e strings
  • 47. Guilherme
 Blanco PHP4Adults Encapsule todos os tipos primitivos e strings Caso haja comportamento
  • 48. Guilherme
 Blanco PHP4Adults Mas… por que?
  • 49. Guilherme
 Blanco PHP4Adults O uso excessivo de objetos no PHP aumenta significativamente o consumo de memória
  • 50. Guilherme
 Blanco PHP4Adults ! class Item ! {! final public static function find($id)! {! if (is_string($id) && trim($id) != '') {! // do find ...! }! ! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! final public static function create($id, array $data)! {! if ( ! is_string($id)) {! throw new InvalidArgumentException('$id must be a string');! }! ! if (empty(trim($id))) {! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! // do create ...! }! }
  • 51. Guilherme
 Blanco PHP4Adults ! class Item ! {! final public static function find($id)! {! if ( ! is_string($id) || trim($id) === '') {! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! // do find ...! }! ! final public static function create($id, array $data)! {! if ( ! is_string($id) || trim($id) === '') {! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! // do create ...! }! }
  • 52. Guilherme
 Blanco PHP4Adults ! class Item ! {! final public static function find($id)! {! if ( ! is_string($id) || trim($id) === '') {! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! // do find ...! }! ! final public static function create($id, array $data)! {! if ( ! is_string($id) || trim($id) === '') {! throw new InvalidArgumentException('$id must be a non-empty string');! }! ! // do create ...! }! }
  • 53. Guilherme
 Blanco PHP4Adults ! final class Id! {! private $value;! ! public function __construct($value)! {! if ( ! is_string($value) || trim($value) === '') {! throw new InvalidArgumentException(! sprintf('%s must be a non-empty string', $value)! );! }! ! $this->value = $value;! }! ! public function getValue()! {! return $this->value;! }! }!
  • 54. Guilherme
 Blanco PHP4Adults ! class Item ! {! final public static function find(Id $id)! {! // do find ...! }! ! final public static function create(Id $id, array $data)! {! // do create ...! }! }
  • 55. Guilherme
 Blanco PHP4Adults Benefícios • Type hinting • Encapsulamento de código • Auxilia na prevenção de código duplicado
  • 56. Guilherme
 Blanco PHP4Adults Um único operador de objeto (->) por linha
  • 57. Guilherme
 Blanco PHP4Adults $this->manager->getConfig()->getSegment()->setName("foo"); Propriedades são
 difíceis de "mockar" E se a chamada ao método anterior retornasse NULL?
  • 58. Guilherme
 Blanco PHP4Adults NULL Object?
  • 59. Guilherme
 Blanco PHP4Adults ! final class NullObject! {! ! public function __get($property)! ! {! ! return new self;! ! }! ! ! public function __set($property, $value)! ! {! ! return new self;! ! }! ! ! public function __call($method, array $arguments)! ! {! ! ! return new self;! ! }! ! ! public function __callStatic($method, array $arguments)! ! {! ! return new self;! ! }! ! ! public function __toString()! ! {! ! return 'null';! ! }! }
  • 60. Guilherme
 Blanco PHP4Adults Por que é ruim? • Esconde um problema de encapsulamento • Difícil de debugar e tratar exceções • Código deve ser todo estruturado para utilizar NullObject • Difícil de ler e entender
  • 61. Guilherme
 Blanco PHP4Adults Exceção a interface fluente com o mesmo nome de método
  • 62. Guilherme
 Blanco PHP4Adults $filterChain
 ->addFilter(new Zend_Filter_Alpha())! ->addFilter(new Zend_Filter_StringToLower());
  • 63. Guilherme
 Blanco PHP4Adults Benefícios • Lei de Demeter • Legibilidade • Aumenta testabilidade (mais fácil "mockar") • Facilidade para debugar
  • 64. Guilherme
 Blanco PHP4Adults Não abrevie
  • 65. Guilherme
 Blanco PHP4Adults – Tim Bray (mencionando Phil Karlton) “Há apenas 2 problemas difíceis na computação: invalidação de cache, nomear coisas e errar por 1.”
  • 66. Guilherme
 Blanco PHP4Adults Por que você abrevia?
  • 67. TitleText Guilherme
 Blanco PHP4Adults Problema de duplicação de código! Escrever o mesmo nome repetidamente
  • 68. TitleText Guilherme
 Blanco PHP4Adults Problema de múltiplas responsabilidades Nome muito longo
  • 69. Guilherme
 Blanco PHP4Adults public function getPage($data) { ... }! ! ! ! public function startProcess() { ... }! ! ! ! $trx->process('site.login'); Obter de onde? Que p. é essa? $extendedTranslator fork, create, begin, open renderHomePage()
  • 70. Guilherme
 Blanco PHP4Adults Benefícios • Melhora na comunicação e legibilidade • Melhora mantenabilidade • Bom indicador para problemas de encapsulamento e duplicação de código
  • 71. Guilherme
 Blanco PHP4Adults Mantenha suas classes pequenas
  • 72. Guilherme
 Blanco PHP4Adults Objetivo • Máximo 200 linhas por classe 
 (incluindo docblocks/documentação) • 10 métodos por classe • Até 20 linhas por método • 15 classes por namespace (folder/pasta)
  • 73. Guilherme
 Blanco PHP4Adults Benefícios • Single Responsibility Principle • Métodos claros e objetivos • Melhor segregação de código • Namespaces mais limpos
  • 74. Guilherme
 Blanco PHP4Adults Limite o número de variáveis de instância numa classe (2 a 5)
  • 75. Guilherme
 Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! }
  • 76. Guilherme
 Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! } Interações com o 
 banco de dados devem
 estar em $userService
  • 77. Guilherme
 Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! } Utilize um event system
 e mova esta instância 
 para um listener
  • 78. Guilherme
 Blanco PHP4Adults Benefícios • Single Responsibility Principle • Baixo acoplamento • Melhor encapsulamento • Melhora testabilidade
  • 79. Guilherme
 Blanco PHP4Adults Use coleções de primeiro nível
  • 80. Guilherme
 Blanco PHP4Adults Em outros termos…
  • 81. Guilherme
 Blanco PHP4Adults Qualquer classe que contenha um array não deve conter outras propriedades
  • 82. Guilherme
 Blanco PHP4Adults ! class User! {! private $name;! // ...! ! private $albumList;! ! ! public function getPublicAlbumList()! ! {! ! $filteredAlbumList = array();! ! ! foreach ($this->albumList as $album) {! if ($album->getPrivacy() === AlbumPrivacy::PUBLIC) {! $filteredAlbumList[] = $album;! }! ! }! ! ! return $filteredAlbumList;! ! }! ! // ...! }! ! // Exemplo:! $publicAlbumList = $user->getPublicAlbumList();
  • 83. Guilherme
 Blanco PHP4Adults ! class AlbumList extends Collection! {! public function getPublic()! {! $filteredAlbumList = array();! ! foreach ($this->value as $album) {! if ($album->getPrivacy() === AlbumPrivacy::PUBLIC) {! $filteredAlbumList[] = $album;! }! }! ! return $filteredAlbumList;! }! }! ! class User! {! private $name;! private $albumList = new AlbumList();! ! // ...! }! ! // Exemplo:! $publicAlbumList = $user->getAlbumList()->getPublic();
  • 84. Guilherme
 Blanco PHP4Adults ! class AlbumList extends Collection! {! public function getPublic()! {! return new ArrayCollection(! array_filter(! $this->value,! function ($album)! {! return $album->isPublic();! }! )! );! }! }! ! class User! {! private $name;! private $albumList = new AlbumList();! ! // ...! }! ! // Exemplo:! $publicAlbumList = $user->getAlbumList()->getPublic();
  • 85. Guilherme
 Blanco PHP4Adults Benefícios • Single Responsibility Principle • Implementação de operações sobre coleções nas coleções • Usar classes de SPL • Facilidade em agrupar coleções sem se preocupar com o comportamento dos membros dela • Filtragem, ordenação, mapeamento, combinação são bons exemplos de métodos
  • 86. Guilherme
 Blanco PHP4Adults Use getters e setters
  • 87. Guilherme
 Blanco PHP4Adults ! class BankAccount ! {! public $balance = 0;! ! public function deposit($amount) ! {! $this->balance += $amount;! }! ! public function withdraw($amount)! {! $this->balance -= $amount;! }! }! ! // Exemplo:! $account = new BankAccount();! ! $account->deposit(100.00);! ! // ...! ! $account->balance = 0;! ! // ...! ! $account->withdraw(10.00);! ! echo $account->balance . PHP_EOL; Balance pode ser
 alterado sem que a 
 classe saiba, causando
 erros inesperados
  • 88. Guilherme
 Blanco PHP4Adults Benefícios • Injeção de operações • Encapsulamento de transformações • Promove Open/Close Principle 
 ("O" em SOLID)
  • 89. Guilherme
 Blanco PHP4Adults Perguntas?
  • 90. Guilherme
 Blanco PHP4Adults Thanks! =) @guilhermeblanco github.com/guilhermeblanco

×