SlideShare uma empresa Scribd logo
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 milhões de usuários 

(somente em um website)
• 12000 requisições/segundo
• Nós usamos PHP!
Guilherme

Blanco
PHP4Adults
Motivação
• 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 "exercício"
Guilherme

Blanco
PHP4Adults
Somente um nível
de indentação por
método
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
Benefícios
• Single Responsibility Principle 

("S" de SOLID)
• Favorece reusabilidade
Guilherme

Blanco
PHP4Adults
Não 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 código 

em blocos.



Considere como

parágrafos!
Espaçamento
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
Benefícios
• Evita duplicação de código
• 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 memória
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
Benefícios
• Type hinting
• Encapsulamento de código
• Auxilia na prevenção de código duplicado
Guilherme

Blanco
PHP4Adults
Um único operador
de objeto (->) por
linha
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?
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
• Difícil de debugar e tratar exceções
• Código deve ser todo estruturado para
utilizar NullObject
• Difícil de ler e entender
Guilherme

Blanco
PHP4Adults
Exceção a interface
fluente com o mesmo
nome de método
Guilherme

Blanco
PHP4Adults
$filterChain

->addFilter(new Zend_Filter_Alpha())!
->addFilter(new Zend_Filter_StringToLower());
Guilherme

Blanco
PHP4Adults
Benefícios
• Lei de Demeter
• Legibilidade
• Aumenta testabilidade (mais fácil "mockar")
• Facilidade para debugar
Guilherme

Blanco
PHP4Adults
Não abrevie
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.”
Guilherme

Blanco
PHP4Adults
Por que você
abrevia?
TitleText
Guilherme

Blanco
PHP4Adults
Problema de duplicação de
código!
Escrever o mesmo nome repetidamente
TitleText
Guilherme

Blanco
PHP4Adults
Problema de múltiplas
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
Benefícios
• Melhora na comunicação e legibilidade
• Melhora mantenabilidade
• Bom indicador para problemas de
encapsulamento e duplicação de código
Guilherme

Blanco
PHP4Adults
Mantenha suas
classes pequenas
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)
Guilherme

Blanco
PHP4Adults
Benefícios
• Single Responsibility Principle
• Métodos claros e objetivos
• Melhor segregação de código
• Namespaces mais limpos
Guilherme

Blanco
PHP4Adults
Limite o número de
variáveis de instância
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;!
!
// ...!
}
Interações 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 instância 

para um listener
Guilherme

Blanco
PHP4Adults
Benefícios
• Single Responsibility Principle
• Baixo acoplamento
• Melhor encapsulamento
• Melhora testabilidade
Guilherme

Blanco
PHP4Adults
Use coleções de
primeiro nível
Guilherme

Blanco
PHP4Adults
Em outros
termos…
Guilherme

Blanco
PHP4Adults
Qualquer classe que
contenha um array não
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
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
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
Benefícios
• Injeção de operações
• Encapsulamento de transformações
• Promove Open/Close Principle 

("O" em SOLID)
Guilherme

Blanco
PHP4Adults
Perguntas?
Guilherme

Blanco
PHP4Adults
Thanks! =)
@guilhermeblanco
github.com/guilhermeblanco

Mais conteúdo relacionado

Mais procurados

Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Edureka!
 
4.2 PHP Function
4.2 PHP Function4.2 PHP Function
4.2 PHP Function
Jalpesh Vasa
 
PHP - PDO.pdf
PHP - PDO.pdfPHP - PDO.pdf
PHP - PDO.pdf
ssuser1e29f11
 
Introducing Modern Perl
Introducing Modern PerlIntroducing Modern Perl
Introducing Modern Perl
Dave Cross
 
webpack 101 slides
webpack 101 slideswebpack 101 slides
webpack 101 slides
mattysmith
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Edureka!
 
Php
PhpPhp
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
Dave Cross
 
Php mysql ppt
Php mysql pptPhp mysql ppt
PHP
PHPPHP
Introduction to Perl - Day 2
Introduction to Perl - Day 2Introduction to Perl - Day 2
Introduction to Perl - Day 2
Dave Cross
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
Stoyan Stefanov
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
Adieu
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Designveloper
 
Cookie and session
Cookie and sessionCookie and session
Cookie and session
Aashish Ghale
 
Php mysql
Php mysqlPhp mysql
PHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginnersPHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginners
Mohammed Mushtaq Ahmed
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
Bradley Holt
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
Caserta
 
Php
PhpPhp

Mais procurados (20)

Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
Python Flask Tutorial For Beginners | Flask Web Development Tutorial | Python...
 
4.2 PHP Function
4.2 PHP Function4.2 PHP Function
4.2 PHP Function
 
PHP - PDO.pdf
PHP - PDO.pdfPHP - PDO.pdf
PHP - PDO.pdf
 
Introducing Modern Perl
Introducing Modern PerlIntroducing Modern Perl
Introducing Modern Perl
 
webpack 101 slides
webpack 101 slideswebpack 101 slides
webpack 101 slides
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
 
Php
PhpPhp
Php
 
Introduction to Perl - Day 1
Introduction to Perl - Day 1Introduction to Perl - Day 1
Introduction to Perl - Day 1
 
Php mysql ppt
Php mysql pptPhp mysql ppt
Php mysql ppt
 
PHP
PHPPHP
PHP
 
Introduction to Perl - Day 2
Introduction to Perl - Day 2Introduction to Perl - Day 2
Introduction to Perl - Day 2
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Cookie and session
Cookie and sessionCookie and session
Cookie and session
 
Php mysql
Php mysqlPhp mysql
Php mysql
 
PHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginnersPHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginners
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Php
PhpPhp
Php
 

Destaque

You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
Rafael Dohms
 
PHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHPPHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHP
Guilherme Blanco
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
Guilherme Blanco
 
ORM dont kill your DB, developers do
ORM dont kill your DB, developers doORM dont kill your DB, developers do
ORM dont kill your DB, developers do
Guilherme Blanco
 
Writing Code That Lasts - #Magento2Seminar, Utrecht
Writing Code That Lasts - #Magento2Seminar, UtrechtWriting Code That Lasts - #Magento2Seminar, Utrecht
Writing Code That Lasts - #Magento2Seminar, Utrecht
Rafael Dohms
 
PHP 7
PHP 7PHP 7
Refatorar é preciso! 2.0
Refatorar é preciso! 2.0Refatorar é preciso! 2.0
Refatorar é preciso! 2.0
Daniel Archer Marques Cramer
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
Andréia Bohner
 
Refatorar é preciso. Palestra TDC 2014
Refatorar é preciso. Palestra TDC 2014Refatorar é preciso. Palestra TDC 2014
Refatorar é preciso. Palestra TDC 2014
Daniel Archer Marques Cramer
 
Forms Suck
Forms SuckForms Suck
Forms Suck
jwegesin
 
Apresentação Clean Code
Apresentação Clean CodeApresentação Clean Code
Apresentação Clean Code
André Leoni
 
Lei de Demeter parte
Lei de Demeter parteLei de Demeter parte
Lei de Demeter parte
Jorge Oleques
 
Conhecendo o-composer-por-nandokstronet
Conhecendo o-composer-por-nandokstronetConhecendo o-composer-por-nandokstronet
Conhecendo o-composer-por-nandokstronet
Code Experts Learning
 
Clean Code (Robert C. Martin)
Clean Code (Robert C. Martin)Clean Code (Robert C. Martin)
Clean Code (Robert C. Martin)
Yasser Veleda
 
Clean code - Mantenha seu código limpo
Clean code - Mantenha seu código limpoClean code - Mantenha seu código limpo
Clean code - Mantenha seu código limpo
Tiago Bencardino
 
Desenvolvendo APIs em Go usando Middlewares
Desenvolvendo APIs em Go usando MiddlewaresDesenvolvendo APIs em Go usando Middlewares
Desenvolvendo APIs em Go usando Middlewares
Elton Minetto
 
“Writing code that lasts” … or writing code you won’t hate tomorrow.
“Writing code that lasts” … or writing code you won’t hate tomorrow.“Writing code that lasts” … or writing code you won’t hate tomorrow.
“Writing code that lasts” … or writing code you won’t hate tomorrow.
Rafael Dohms
 
Clean Code
Clean CodeClean Code
Clean Code
Rodrigo Branas
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworksPSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworks
Elton Minetto
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
Rafael Dohms
 

Destaque (20)

You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
PHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHPPHPubSP Object Calisthenics aplicado ao PHP
PHPubSP Object Calisthenics aplicado ao PHP
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
ORM dont kill your DB, developers do
ORM dont kill your DB, developers doORM dont kill your DB, developers do
ORM dont kill your DB, developers do
 
Writing Code That Lasts - #Magento2Seminar, Utrecht
Writing Code That Lasts - #Magento2Seminar, UtrechtWriting Code That Lasts - #Magento2Seminar, Utrecht
Writing Code That Lasts - #Magento2Seminar, Utrecht
 
PHP 7
PHP 7PHP 7
PHP 7
 
Refatorar é preciso! 2.0
Refatorar é preciso! 2.0Refatorar é preciso! 2.0
Refatorar é preciso! 2.0
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Refatorar é preciso. Palestra TDC 2014
Refatorar é preciso. Palestra TDC 2014Refatorar é preciso. Palestra TDC 2014
Refatorar é preciso. Palestra TDC 2014
 
Forms Suck
Forms SuckForms Suck
Forms Suck
 
Apresentação Clean Code
Apresentação Clean CodeApresentação Clean Code
Apresentação Clean Code
 
Lei de Demeter parte
Lei de Demeter parteLei de Demeter parte
Lei de Demeter parte
 
Conhecendo o-composer-por-nandokstronet
Conhecendo o-composer-por-nandokstronetConhecendo o-composer-por-nandokstronet
Conhecendo o-composer-por-nandokstronet
 
Clean Code (Robert C. Martin)
Clean Code (Robert C. Martin)Clean Code (Robert C. Martin)
Clean Code (Robert C. Martin)
 
Clean code - Mantenha seu código limpo
Clean code - Mantenha seu código limpoClean code - Mantenha seu código limpo
Clean code - Mantenha seu código limpo
 
Desenvolvendo APIs em Go usando Middlewares
Desenvolvendo APIs em Go usando MiddlewaresDesenvolvendo APIs em Go usando Middlewares
Desenvolvendo APIs em Go usando Middlewares
 
“Writing code that lasts” … or writing code you won’t hate tomorrow.
“Writing code that lasts” … or writing code you won’t hate tomorrow.“Writing code that lasts” … or writing code you won’t hate tomorrow.
“Writing code that lasts” … or writing code you won’t hate tomorrow.
 
Clean Code
Clean CodeClean Code
Clean Code
 
PSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworksPSR-7, middlewares e o futuro dos frameworks
PSR-7, middlewares e o futuro dos frameworks
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 

Semelhante a PHP para Adultos: Clean Code e Object Calisthenics

apostila.pdf
apostila.pdfapostila.pdf
apostila.pdf
DenilsonNunes13
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
Michael Castillo Granados
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
Impacta Eventos
 
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveisLabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
Carlos Santos
 
iOS 8 com swift
iOS 8 com swiftiOS 8 com swift
PHP ao Extremo
PHP ao ExtremoPHP ao Extremo
PHP ao Extremo
Thiago Rigo
 
Curso PHP UNIFACS 2014.1 – 2ª aula
Curso PHP UNIFACS 2014.1 – 2ª aulaCurso PHP UNIFACS 2014.1 – 2ª aula
Curso PHP UNIFACS 2014.1 – 2ª aula
Jonata Weber
 
modernizando a arquitertura de sua aplicação
modernizando a arquitertura  de sua aplicaçãomodernizando a arquitertura  de sua aplicação
modernizando a arquitertura de sua aplicação
Antonio Spinelli
 
Php 02 Primeiros Passos
Php 02 Primeiros PassosPhp 02 Primeiros Passos
Php 02 Primeiros Passos
Regis Magalhães
 
Prog web 02-php-primeiros-passos
Prog web 02-php-primeiros-passosProg web 02-php-primeiros-passos
Prog web 02-php-primeiros-passos
Regis Magalhães
 
Introdução ao PHP Parte 2
Introdução ao PHP Parte 2Introdução ao PHP Parte 2
Introdução ao PHP Parte 2
Wellington Oliveira
 
LabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - FunçõesLabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - Funções
Carlos Santos
 
PHP Day - PHP para iniciantes
PHP Day - PHP para iniciantesPHP Day - PHP para iniciantes
PHP Day - PHP para iniciantes
Almir Mendes
 
Criando controle de acesso com php e my sql
Criando controle de acesso com php e my sqlCriando controle de acesso com php e my sql
Criando controle de acesso com php e my sql
Paulo Damas
 
Design patterns
Design patternsDesign patterns
Design patterns
DouglasSoaresAndrSch
 
PHP GERAL
PHP GERALPHP GERAL
PHP GERAL
Lucas Batistussi
 
Aula 12 Relatório - Tabelas
Aula 12   Relatório - TabelasAula 12   Relatório - Tabelas
Aula 12 Relatório - Tabelas
Dalton Martins
 
Aula 8 php
Aula 8 phpAula 8 php
Aula 8 php
sergio_henrique
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantes
Eduardo Mendes
 
Aula 02 - Introdução ao PHP - Programação Web
Aula 02  - Introdução ao PHP - Programação WebAula 02  - Introdução ao PHP - Programação Web
Aula 02 - Introdução ao PHP - Programação Web
Dalton Martins
 

Semelhante a PHP para Adultos: Clean Code e Object Calisthenics (20)

apostila.pdf
apostila.pdfapostila.pdf
apostila.pdf
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que parece
 
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveisLabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
LabMM4 (T11 - 12/13) - PHP - Tipos de dados e variáveis
 
iOS 8 com swift
iOS 8 com swiftiOS 8 com swift
iOS 8 com swift
 
PHP ao Extremo
PHP ao ExtremoPHP ao Extremo
PHP ao Extremo
 
Curso PHP UNIFACS 2014.1 – 2ª aula
Curso PHP UNIFACS 2014.1 – 2ª aulaCurso PHP UNIFACS 2014.1 – 2ª aula
Curso PHP UNIFACS 2014.1 – 2ª aula
 
modernizando a arquitertura de sua aplicação
modernizando a arquitertura  de sua aplicaçãomodernizando a arquitertura  de sua aplicação
modernizando a arquitertura de sua aplicação
 
Php 02 Primeiros Passos
Php 02 Primeiros PassosPhp 02 Primeiros Passos
Php 02 Primeiros Passos
 
Prog web 02-php-primeiros-passos
Prog web 02-php-primeiros-passosProg web 02-php-primeiros-passos
Prog web 02-php-primeiros-passos
 
Introdução ao PHP Parte 2
Introdução ao PHP Parte 2Introdução ao PHP Parte 2
Introdução ao PHP Parte 2
 
LabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - FunçõesLabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - Funções
 
PHP Day - PHP para iniciantes
PHP Day - PHP para iniciantesPHP Day - PHP para iniciantes
PHP Day - PHP para iniciantes
 
Criando controle de acesso com php e my sql
Criando controle de acesso com php e my sqlCriando controle de acesso com php e my sql
Criando controle de acesso com php e my sql
 
Design patterns
Design patternsDesign patterns
Design patterns
 
PHP GERAL
PHP GERALPHP GERAL
PHP GERAL
 
Aula 12 Relatório - Tabelas
Aula 12   Relatório - TabelasAula 12   Relatório - Tabelas
Aula 12 Relatório - Tabelas
 
Aula 8 php
Aula 8 phpAula 8 php
Aula 8 php
 
PHP básico para iniciantes
PHP básico para iniciantesPHP básico para iniciantes
PHP básico para iniciantes
 
Aula 02 - Introdução ao PHP - Programação Web
Aula 02  - Introdução ao PHP - Programação WebAula 02  - Introdução ao PHP - Programação Web
Aula 02 - Introdução ao PHP - Programação Web
 

Mais de Guilherme Blanco

Enterprise php
Enterprise phpEnterprise php
Enterprise php
Guilherme Blanco
 
Javascript para adultos
Javascript para adultosJavascript para adultos
Javascript para adultos
Guilherme Blanco
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
Guilherme Blanco
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
Guilherme Blanco
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHP
Guilherme Blanco
 
PHP, Daemons e Multimedia
PHP, Daemons e MultimediaPHP, Daemons e Multimedia
PHP, Daemons e Multimedia
Guilherme Blanco
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
Guilherme Blanco
 

Mais de Guilherme Blanco (9)

Enterprise php
Enterprise phpEnterprise php
Enterprise php
 
Javascript para adultos
Javascript para adultosJavascript para adultos
Javascript para adultos
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Doctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHPDoctrine 2.0: A evolução da persistência em PHP
Doctrine 2.0: A evolução da persistência em PHP
 
PHP, Daemons e Multimedia
PHP, Daemons e MultimediaPHP, Daemons e Multimedia
PHP, Daemons e Multimedia
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 

PHP para Adultos: Clean Code e Object Calisthenics