Slide 1

Slide 1 text

Marcel Gonçalves dos Santos @marcelgsantos orientado a objetos projetando software com qualidade

Slide 2

Slide 2 text

pensandonaweb.com.br desenvolvedor web full-stack Marcel Gonçalves dos Santos @marcelgsantos

Slide 3

Slide 3 text

@phpsp phpsp.org.br

Slide 4

Slide 4 text

Interaja nas mídias sociais!
 
 - fale sobre o evento, palestrantes e conteúdo - tire fotos do evento e publique
 - interaja com outros participantes do evento - tire dúvidas ou dê feedbacks para os palestrantes

Slide 5

Slide 5 text

O que é Orientação a Objetos?

Slide 6

Slide 6 text

é um paradigma de programação que trata da comunicação entre objetos através da troca de mensagens

Slide 7

Slide 7 text

um objeto é uma representação concreta de uma abstração…

Slide 8

Slide 8 text

…que possui características, comportamentos e estado atual

Slide 9

Slide 9 text

a orientação a objetos pode ser baseada em classes ou baseada em protótipos

Slide 10

Slide 10 text

!// class to create a User object class User { private string $name; private int $age; public function !__construct(string $name, int $age) { $this!->name = $name; $this!->age = $age; } public function sayName() : void { echo "Hello, my name is {$this!->name}!"; } }

Slide 11

Slide 11 text

!// two objects representing user abstractions $alice = new User('Alice', 22); $bob = new User('Bob', 27); $alice!->sayName(); !// Hello, my name is Alice! $bob!->sayName(); !// Hello, my name is Bob!

Slide 12

Slide 12 text

!// current state of $alice object var_dump($alice); !/* class User#3 (2) { private $name !=> string(5) "Alice" private $age !=> int(22) } !*/

Slide 13

Slide 13 text

Pilares da Orientação a Objetos

Slide 14

Slide 14 text

abstração
 trata da representação de um conceito da vida real dentro do sistema

Slide 15

Slide 15 text

!// class to create a User object class User { private string $name; private int $age; public function !__construct(string $name, int $age) { $this!->name = $name; $this!->age = $age; } public function sayName() : void { echo "Hello, my name is {$this!->name}!"; } }

Slide 16

Slide 16 text

!// two objects representing user abstractions $alice = new User('Alice', 22); $bob = new User('Bob', 27); $alice!->sayName(); !// Hello, my name is Alice! $bob!->sayName(); !// Hello, my name is Bob!

Slide 17

Slide 17 text

!// current state of $alice object var_dump($alice); !/* class User#3 (2) { private $name !=> string(5) "Alice" private $age !=> int(22) } !*/

Slide 18

Slide 18 text

herança
 permite o reaproveitamento de código em que uma classe herda características e atributos de uma classe base

Slide 19

Slide 19 text

encapsulamento
 permite ocultar a implementação interna de um objeto

Slide 20

Slide 20 text

polimorfismo
 consiste na alteração do funcionamento interno de um método herdado do pai

Slide 21

Slide 21 text

Os maus cheiros do projeto

Slide 22

Slide 22 text

rigidez
 tendência do software de ser difícil de alterar, mesmo de maneira simples

Slide 23

Slide 23 text

fragilidade
 tendência de um programa estragar em muitos lugares quando uma única alteração é feita

Slide 24

Slide 24 text

imobilidade
 quando existem partes que poderiam ser úteis em outro sistema…

Slide 25

Slide 25 text

imobilidade
 …mas o trabalho e riscos na separação dessas partes são muito grandes (cont.)

Slide 26

Slide 26 text

viscosidade
 característica que diz o quão difícil é de preservar um software

Slide 27

Slide 27 text

complexidade desnecessária
 quando existem elementos que não serão úteis no momento

Slide 28

Slide 28 text

repetição desnecessária
 é quando um mesmo código aparece inúmeras vezes, de formas pouco diferentes

Slide 29

Slide 29 text

opacidade
 refere-se a dificuldade de compreensão de um módulo

Slide 30

Slide 30 text

Princípios da Orientação a Objetos

Slide 31

Slide 31 text

coesão
 indica o grau de relação entre os membros de um módulo

Slide 32

Slide 32 text

!// is this class cohesive or not cohesive? class Cart { private array $items; public function !__construct() { $this!->items = []; } public function numberOfItems() : int { return count($this!->items); } public function calculateDeliveryPrice() : float { !// calculates the delivery price } }

Slide 33

Slide 33 text

acoplamento
 indica o grau de dependência entre módulos

Slide 34

Slide 34 text

o acoplamento ocorre quando o código de um módulo utiliza código de outro módulo, seja ao chamar uma função ou acessar algum dado

Slide 35

Slide 35 text

!// class Car is coupled to Engine class class Car { private $engine; public function !__construct() { $this!->engine = new Engine(); } public function start() { $this!->engine!->start(); !// engine is a dependency } } $car = new Car(); $car!->start(); !// Starting the engine

Slide 36

Slide 36 text

o acoplamento é algo desejado, porém, que deve ser controlado

Slide 37

Slide 37 text

ao controlar o acoplamento, o software torna-se mais flexível e fácil de manter

Slide 38

Slide 38 text

e como podemos reduzir o acoplamento entre classes ou módulos?

Slide 39

Slide 39 text

Injeção de dependência

Slide 40

Slide 40 text

a injeção de dependência é uma técnica que permite reduzir o acoplamento entre classes ou módulos…

Slide 41

Slide 41 text

…e consiste em fornecer uma dependência do mundo externo para uma classe

Slide 42

Slide 42 text

!// dependency injection via constructor class Car { private $engine; public function !__construct(Engine $engine) { $this!->engine = $engine; } public function start() { $this!->engine!->start(); } }

Slide 43

Slide 43 text

!// inject an engine dependency into the car $engine = new Engine(); $car = new Car($engine); $car!->start(); !// Starting the engine

Slide 44

Slide 44 text

utilizar injeção de dependências auxilia nos testes unitários pois tornam os módulos fracamente acoplados, altamente coesos e facilita o mocking de objetos

Slide 45

Slide 45 text

“prefira classes com alta coesão e baixo acoplamento”

Slide 46

Slide 46 text

Princípio da inversão de dependência Dependency Inversion Principle

Slide 47

Slide 47 text

o princípio de inversão de dependência é a letra “D” do SOLID

Slide 48

Slide 48 text

3. módulos de baixo nível também devem
 depender de abstrações 2. módulos de alto nível devem depender 
 de abstrações e não de implementações 1. módulos de alto nível não devem 
 depender de módulos de baixo nível o princípio de inversão de dependência diz:

Slide 49

Slide 49 text

Classe A Classe B referencia

Slide 50

Slide 50 text

!// concrete implementation in order to get coordinates !// from address in Google Maps and OpenStreetMap class GoogleMaps { public function getCoordinatesFromAddress($address) { !// calls Google Maps webservice } } class OpenStreetMap { public function getCoordinatesFromAddress($address) { !// calls OpenStreetMap webservice } }

Slide 51

Slide 51 text

!// class StoreService depends on a concrete implementation !// of GoogleMaps geolocation service class StoreService { public function getStoreCoordinates($store) { $geolocationService = new GoogleMaps(); return $geolocationService !->getCoordinatesFromAddress($store!->getAddress()); } }

Slide 52

Slide 52 text

StoreService GoogleMaps referencia

Slide 53

Slide 53 text

uma classe não deve depender de um módulo de baixo nível

Slide 54

Slide 54 text

Classe B referencia Classe A Interface implementa

Slide 55

Slide 55 text

!// geolocation services abstraction (contract) !// each concrete implementation must follow this contract interface GeolocationService { public function getCoordinatesFromAddress($address); }

Slide 56

Slide 56 text

!// concrete implementation must follow the contract class GoogleMaps implements GeolocationService { public function getCoordinatesFromAddress($address) { !// calls Google Maps webservice } } class OpenStreetMap implements GeolocationService { public function getCoordinatesFromAddress($address) { !// calls OpenStreetMap webservice } }

Slide 57

Slide 57 text

!// the class should depends on abstraction (GeolocationService) class StoreService { private $geolocationService; public function !__construct(GeolocationService $geolocationService) { $this!->geolocationService = $geolocationService; } public function getStoreCoordinates($store) { return $this!->geolocationService !->getCoordinatesFromAddress($store!->getAddress()); } }

Slide 58

Slide 58 text

GoogleMaps referencia StoreService GeolocationService implementa

Slide 59

Slide 59 text

uma classe deve depender de um contrato, abstração ou interface

Slide 60

Slide 60 text

ao depender de abstrações você desacopla o seu código da dependência

Slide 61

Slide 61 text

Objetos de valor
 Value objects

Slide 62

Slide 62 text

são objetos simples e pequenos em que a igualdade não é baseada em identidade

Slide 63

Slide 63 text

!// value objects that represent 30 dollars $priceBook = new Money(30, new Currency('USD')); $priceMeal = new Money(30, new Currency('USD')); $priceBook!->equals($priceMeal); !// true

Slide 64

Slide 64 text

um objeto de valor deve ser imutável e existir em um estado consistente

Slide 65

Slide 65 text

ele permite centralizar a regra de negócio e evitar que ela fique espalhada pelo código

Slide 66

Slide 66 text

!// User class accepts an invalid email class User { private string $name; private string $email; public function !__construct(string $name, string $email) { $this!->name = $name; $this!->email = $email; } } $alice = new User('Alice', '[email protected]'); $bob = new User('Bob', '123456');

Slide 67

Slide 67 text

!// email value object class Email { private $email; public function !__construct(string $email) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidArgumentException('invalid format'); } $this!->email = $email; } } $alice = new User('Alice', new Email('[email protected]')); $bob = new User('Bob', new Email('123456')); !// throws an exception

Slide 68

Slide 68 text

recomenda-se utilizar value objects no caso de valores que possuem validação, regras de negócio ou comportamento

Slide 69

Slide 69 text

pele permite representar a linguagem ubíqua no seu código

Slide 70

Slide 70 text

utilizá-los ajuda a evitar o anti-padrão conhecido como primitive obsession

Slide 71

Slide 71 text

primitive obsession
 trata-se de utilizar tipos de dados primitivos para representar ideias de domínio

Slide 72

Slide 72 text

Tell Don’t Ask

Slide 73

Slide 73 text

não peça informações para um objeto para fazer o seu trabalho…

Slide 74

Slide 74 text

…apenas diga para o objeto que possui a informação para fazer o trabalho para você

Slide 75

Slide 75 text

class Game 
 { private $score; public function setScore($score) { $this!->score = $score; } public function getScore() { return $this!->score; } } $game!->setScore($game!->getScore() + ENEMY_DESTROYED_SCORE); está pedindo informações para realizar seu trabalho

Slide 76

Slide 76 text

class Game { private $score; public function addScore($delta) { this!->score += $delta; } } $game!->addScore(ENEMY_DESTROYED_SCORE); está dizendo para o objeto realizar o trabalho para você

Slide 77

Slide 77 text

Law of Demeter

Slide 78

Slide 78 text

fale com seus amigos mais próximos e não fale com estranhos

Slide 79

Slide 79 text

$objectA!->getObjectB()!->getObjectC();

Slide 80

Slide 80 text

Object Calisthenics

Slide 81

Slide 81 text

são exercícios de programação formalizados em 9 regras…

Slide 82

Slide 82 text

… o exercício dessas regras ajudará a escrever código melhor

Slide 83

Slide 83 text

object calisthenics
 1. somente um nível de indentação por método 2. não utilizar a palavra-chave else 3. encapsular todos tipos primitivos e strings 4. coleções de primeira classe 5. um ponto por linha

Slide 84

Slide 84 text

object calisthenics
 6. não abrevie
 7. mantenha todas as entidades pequenas 8. nenhuma classe com mais de duas variáveis de instância 9. sem getters, setters ou propriedades (cont.)

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

as regras não estão escritas em pedra!

Slide 87

Slide 87 text

utilize aquelas que se sentir mais confortável

Slide 88

Slide 88 text

Conclusão

Slide 89

Slide 89 text

os princípios de design ajudam a projetar códigos melhores

Slide 90

Slide 90 text

um código mau projetado é um código difícil de mudar

Slide 91

Slide 91 text

uma classe não deve ser forçada a depender de uma implementação específica

Slide 92

Slide 92 text

uma classe deve depender de um contrato, abstração ou interface

Slide 93

Slide 93 text

prefira classes com alta coesão e baixo acoplamento

Slide 94

Slide 94 text

Referências

Slide 95

Slide 95 text

Learning OOP in PHP Tutoriais, vídeos, slides, livros sobre OOP, OOD, design patterns, refatoração e arquitetura. bit.ly/Learning-OOP-in-PHP

Slide 96

Slide 96 text

Avalie!

Slide 97

Slide 97 text

@marcelgsantos speakerdeck.com/marcelgsantos Obrigado. Perguntas?