PHP para Adultos: Clean Code e Object Calisthenics

Download PHP para Adultos: Clean Code e Object Calisthenics

Post on 27-Aug-2014

1.425 views

Category:

Software

10 download

DESCRIPTION

Palestra apresentada no InterconPHP em So Paulo. Data do evento: 2014-07-19

TRANSCRIPT

  • TitleText Guilherme Blanco PHP4Adults Object Calisthenics Clean Code
  • Guilherme Blanco PHP4Adults Who speaks English?
  • Guilherme Blanco PHP4Adults "Vamos l, Sucker! Mexa esse traseiro gordo!" Fucker & Sucker: A Pair of Two Double Cops
  • Guilherme Blanco PHP4Adults Guilherme Blanco @guilhermeblanco github.com/guilhermeblanco
  • Guilherme Blanco PHP4Adults Instaclick ~300 empregados Mais de 67 milhes de usurios (somente em um website) 12000 requisies/segundo Ns usamos PHP!
  • Guilherme Blanco PHP4Adults Motivao Legibilidade Mantenabilidade Reusabilidade Testabilidade
  • Guilherme Blanco PHP4Adults Resumindo
  • Guilherme Blanco PHP4Adults
  • Guilherme Blanco PHP4Adults Clean Code
  • Guilherme Blanco PHP4Adults S T U P I Dingleton ightcoupling ntestability rematureoptimization ndescriptivenaming uplication
  • Guilherme Blanco PHP4Adults S O L I D ingleresponsibility pen/closeprinciple iskovsubstitution nterfacesegregation ependencyinversion
  • Guilherme Blanco PHP4Adults Liskov Substitution Principle
  • Guilherme Blanco PHP4Adults ! interface Bird! {! public function setLocation($longitude, $latitude);! ! public function setAltitude($altitude);! ! public function draw();! }!
  • Guilherme Blanco PHP4Adults ! class Penguim implements Bird! {! public function setAltitude($altitude)! {! // Do nothing! }! }!
  • Guilherme Blanco PHP4Adults ! interface Bird! {! public function setLocation($longitude, $latitude);! ! public function draw($altitude);! }! ! interface FlightfulBird extends Bird! {! ! public function setAltitude($altitude);! }!
  • Guilherme Blanco PHP4Adults Dependency Inversion Principle
  • Guilherme Blanco PHP4Adults ! namespace DatingUserBundleEntity! {! class User! {! /**! * @var DatingUserBundleEntityImage! */! ! protected $avatar;! }! }! ! namespace DatingMediaBundleEntity! {! class Image! {! /**! * @var DatingUserBundleEntityUser! */! ! protected $owner;! ! }! }
  • 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;! ! }! }!
  • Guilherme Blanco PHP4Adults Object Calisthenics Termo grego, significa "exerccio"
  • Guilherme Blanco PHP4Adults Somente um nvel de indentao por mtodo
  • 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;! }
  • 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
  • Guilherme Blanco PHP4Adults Early returns
  • 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;! } !
  • 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
  • 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;! } !
  • 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
  • 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;! } !
  • 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
  • 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;! } !
  • Guilherme Blanco PHP4Adults Benefcios Single Responsibility Principle ("S" de SOLID) Favorece reusabilidade
  • Guilherme Blanco PHP4Adults No existe "else"
  • 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 cdigo em blocos. Considere como pargrafos! Espaamento
  • 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);! } ! }!
  • 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);! } ! }!
  • 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);! } ! }!
  • Guilherme Blanco PHP4Adults UML Normal vs. Alternate flows
  • 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);! } ! }!
  • 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);! } ! }!
  • 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);! } ! }!
  • 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);! }! }!
  • 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);! }! }!
  • 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');! }
  • 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');! }
  • Guilherme Blanco PHP4Adults Benefcios Evita duplicao de cdigo Aumenta legibilidade Reduz cyclomatic complexity
  • Guilherme Blanco PHP4Adults Encapsule todos os tipos primitivos e strings
  • Guilherme Blanco PHP4Adults Encapsule todos os tipos primitivos e strings Caso haja comportamento
  • Guilherme Blanco PHP4Adults Mas por que?
  • Guilherme Blanco PHP4Adults O uso excessivo de objetos no PHP aumenta significativamente o consumo de memria
  • 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 ...! }! }
  • 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 ...! }! }
  • 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 ...! }! }
  • 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;! }! }!
  • 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 ...! }! }
  • Guilherme Blanco PHP4Adults Benefcios Type hinting Encapsulamento de cdigo Auxilia na preveno de cdigo duplicado
  • Guilherme Blanco PHP4Adults Um nico operador de objeto (->) por linha
  • Guilherme Blanco PHP4Adults $this->manager->getConfig()->getSegment()->setName("foo"); Propriedades so difceis de "mockar" E se a chamada ao mtodo anterior retornasse NULL?
  • Guilherme Blanco PHP4Adults NULL Object?
  • 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';! ! }! }
  • Guilherme Blanco PHP4Adults Por que ruim? Esconde um problema de encapsulamento Difcil de debugar e tratar excees Cdigo deve ser todo estruturado para utilizar NullObject Difcil de ler e entender
  • Guilherme Blanco PHP4Adults Exceo a interface fluente com o mesmo nome de mtodo
  • Guilherme Blanco PHP4Adults $filterChain ->addFilter(new Zend_Filter_Alpha())! ->addFilter(new Zend_Filter_StringToLower());
  • Guilherme Blanco PHP4Adults Benefcios Lei de Demeter Legibilidade Aumenta testabilidade (mais fcil "mockar") Facilidade para debugar
  • Guilherme Blanco PHP4Adults No abrevie
  • Guilherme Blanco PHP4Adults Tim Bray (mencionando Phil Karlton) H apenas 2 problemas difceis na computao: invalidao de cache, nomear coisas e errar por 1.
  • Guilherme Blanco PHP4Adults Por que voc abrevia?
  • TitleText Guilherme Blanco PHP4Adults Problema de duplicao de cdigo! Escrever o mesmo nome repetidamente
  • TitleText Guilherme Blanco PHP4Adults Problema de mltiplas responsabilidades Nome muito longo
  • 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()
  • Guilherme Blanco PHP4Adults Benefcios Melhora na comunicao e legibilidade Melhora mantenabilidade Bom indicador para problemas de encapsulamento e duplicao de cdigo
  • Guilherme Blanco PHP4Adults Mantenha suas classes pequenas
  • Guilherme Blanco PHP4Adults Objetivo Mximo 200 linhas por classe (incluindo docblocks/documentao) 10 mtodos por classe At 20 linhas por mtodo 15 classes por namespace (folder/pasta)
  • Guilherme Blanco PHP4Adults Benefcios Single Responsibility Principle Mtodos claros e objetivos Melhor segregao de cdigo Namespaces mais limpos
  • Guilherme Blanco PHP4Adults Limite o nmero de variveis de instncia numa classe (2 a 5)
  • Guilherme Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! }
  • Guilherme Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! } Interaes com o banco de dados devem estar em $userService
  • Guilherme Blanco PHP4Adults class MyRegistrationService! {! protected $userService;! protected $passwordService;! protected $logger;! protected $translator;! protected $entityManager;! protected $imageCropper;! ! // ...! } Utilize um event system e mova esta instncia para um listener
  • Guilherme Blanco PHP4Adults Benefcios Single Responsibility Principle Baixo acoplamento Melhor encapsulamento Melhora testabilidade
  • Guilherme Blanco PHP4Adults Use colees de primeiro nvel
  • Guilherme Blanco PHP4Adults Em outros termos
  • Guilherme Blanco PHP4Adults Qualquer classe que contenha um array no deve conter outras propriedades
  • 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();
  • 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();
  • 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();
  • Guilherme Blanco PHP4Adults Benefcios Single Responsibility Principle Implementao de operaes sobre colees nas colees Usar classes de SPL Facilidade em agrupar colees sem se preocupar com o comportamento dos membros dela Filtragem, ordenao, mapeamento, combinao so bons exemplos de mtodos
  • Guilherme Blanco PHP4Adults Use getters e setters
  • 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
  • Guilherme Blanco PHP4Adults Benefcios Injeo de operaes Encapsulamento de transformaes Promove Open/Close Principle ("O" em SOLID)
  • Guilherme Blanco PHP4Adults Perguntas?
  • Guilherme Blanco PHP4Adults Thanks! =) @guilhermeblanco github.com/guilhermeblanco