SlideShare uma empresa Scribd logo
1 de 32
ZOOX DEV TALK 04/2016
Princípios para melhorar um código
MOTIVAÇÃO
 Por que devemos sempre melhorar o código?
 Por que um código que funciona não é suficiente?
AVISO
 Estes princípios são sugestões e não regras!
STUPID
 Singleton
 Tight Coupling
 Untestability
 Premature Optimization
 Indescriptive Naming
 Duplication
SINGLETON
 Representa um estado global do seu código
 Programas que usam estado global são difíceis de testar e debugar
 Programas que dependem do estado global mascaram suas dependências
TIGHT COUPLING
 Generalização do problema com Singleton
 Se mudar um módulo te obriga a mudar outro módulo
 Torna o código difícil de reusar e testar
 Para evitar, favorecer composição sobre herança e usar injeção de
dependência sempre que possível
UNTESTABILITY
 Testes não devem ser difíceis
 Deixar de escrever um teste economiza tempo de imediato, mas perde
muito mais depois ”caçando” bugs e testando manualmente (falho)
 Se escrever um teste é difícil, o problema está no código
 Normalmente, untestability é causada por tight coupling
PREMATURE OPTIMIZATION
 Não super complique o código para otimizá-lo
 Terá apenas custo e não benefício
 Meça a performance antes de otimizar (benchmarks)
 YAGNI = You Ain’t Gonna Need It (Você não vai precisar disso)
INDESCRIPTIVE NAMING
 Nomeie classes, métodos, atributos apropriadamente
 Não abrevie
 Se não consegue achar um nome apropriado para uma classe, talvez a
responsabilidade dela não esteja bem definida.
 Linguagem de programação é para humanos
 Para o computador, $vlna é o mesmo que $valorLitraoNoAlto
DUPLICAÇÃO
 Se duplicar código e tiver que fazer um ajuste, terá que mexer em
vários lugares (e se esquecer de um?)
 DRY = Don’t Repeat Youself
 KISS = Keep It Simple, Stupid!
SOLID
 Single Responsibility Principle
 Open/Close Principle
 Liskov Substitution Principle
 Interface Segregation Principle
 Dependency Inversion Principle
SINGLE RESPONSIBILITY PRINCIPLE
 Nunca deve haver mais de uma razão para uma classe mudar
 Divida classes grandes
 Use camadas
 Evite classes God
SRP - EXEMPLO
<?php
class Livro
{
function getAutor()
{
return 'João da Silva';
}
function getTitulo()
{
return 'Grande Livro';
}
function virarPagina()
{
// Avança ponteiro de página
}
function mostraPaginaAtual()
{
echo 'Conteúdo da página';
}
}
O que há de errado no código?
SRP – EXEMPLO MELHORADO
<?php
class Livro
{
function getTitulo()
{
return 'Grande Livro';
}
function getPaginaAtual()
{
echo 'Conteúdo da página';
}
}
interface Printer
{
function printPage($page);
}
class PlainTextPrinter implements Printer
{
function printPage($page) {
echo $page;
}
}
class HtmlPrinter implements Printer
{
function printPage($page) {
echo '<div style="single-page">' . $page . '</div>';
}
}
$livro = new Livro();
$printer = new HtmlPrinter();
$printer->printPage($livro->getPaginaAtual());
OPEN/CLOSE PRINCIPLE
 Classes devem ser abertas para expansão, mas fechadas para alteração
 Defina todos os atributos como private
 Sem variáveis globais
 Evite setter (sempre que possível)
OCP - EXEMPLO
<?php
class Retangulo
{
public $altura;
public $largura;
}
class Area
{
public function calculaArea(Retangulo $retangulo)
{
return $retangulo->altura * $retangulo->largura;
}
}
OCP – EXEMPLO DE VIOLAÇÃO
<?php
class Retangulo
{
public $altura;
public $largura;
}
class Circulo
{
public $radio;
}
class Area
{
public function calculaArea($objeto)
{
if ($objeto instanceof Retangulo) {
return $objeto->altura * $objeto->largura;
} elseif ($objeto instanceof Circulo) {
return $objeto->circulo * $objeto->circulo * PI;
}
}
}
OCP – EXEMPLO DE VIOLAÇÃO
<?php
class Retangulo
{
public $altura;
public $largura;
}
class Circulo
{
public $radio;
}
class Area
{
public function calculaArea($objeto)
{
if ($objeto instanceof Retangulo) {
return $objeto->altura * $objeto->largura;
} elseif ($objeto instanceof Circulo) {
return $objeto->circulo * $objeto->circulo * PI;
}
}
}
Tivemos que alterar a classe Area
para poder extendê-la. Ela não é
fechada para modificações = não é
aberta para expansão
OCP – EXEMPLO MELHORADO
<?php
abstract class Forma
{
abstract function calculaArea();
}
class Retangulo extends Forma
{
public $altura;
public $largura;
public function calculaArea()
{
return $this->altura * $this->largura;
}
}
class Circulo extends Forma
{
public $radio;
public function calculaArea()
{
return $this->circulo * $this->circulo * PI;
}
}
class Area
{
public function calculaArea(Forma $objeto)
{
return $objeto->calculaArea();
}
}
LISKOV SUBSTITUTION PRINCIPLE
 Subclasses devem poder ser substituidas por sua classe base
 Classes filhas não devem quebrar as definições de suas bases
 Objetos num código devem poder ser substituídos por seus subtipos
sem alterar o funcionamento correto do programa
LSP - EXEMPLO
<?php
class Retangulo
{
protected $altura;
protected $largura;
public function setLargura($largura)
{ $this->largura = $largura; }
public function setAltura($altura)
{ $this->altura = $altura; }
public function getArea()
{
return $this->altura * $this->largura;
}
}
$retangulo = new Retangulo();
$retangulo->setAltura(10);
$retangulo->setLargura(20);
if ($retangulo->getArea() !== 200) {
throw new Exception('Área errada');
}
0
LSP - EXEMPLO DE VIOLAÇÃO
<?php
class Retangulo
{
protected $altura;
protected $largura;
public function setLargura($largura) { $this->largura = $largura; }
public function setAltura($altura) { $this->altura = $altura; }
public function getArea()
{
return $this->altura * $this->largura;
}
}
class Quadrado extends Retangulo
{
public function setLargura($largura)
{ $this->largura = $this->altura = $largura; }
public function setAltura($altura)
{ $this->altura = $this->largura = $altura; }
}
$quadrado = new Quadrado();
$quadrado->setAltura(10);
$quadrado->setLargura(20);
if ($quadrado->getArea() !== 200) {
throw new Exception('Área errada');
}
INTERFACE SEGREGATION PRINCIPLE
 Melhor ter várias interfaces específicas a uma só genérica
 Uma classe não deveria implementar métodos que não usa
 Usando ISP você garante low coupling e high coersion
ISP - EXEMPLO
<?php
interface Veiculo
{
public function liga();
public function abreMala();
public function numEixos();
public function ehMensalista();
}
class Carro implements Veiculo
{
}
class Estacionamento
{
public function permiteEntrada(Veiculo $veiculo)
{
return $veiculo->ehMensalista();
}
}
class Pedagio
{
public function custo(Veiculo $veiculo)
{
return $veiculo->numEixos() * 5;
}
}
ISP – EXEMPLO DE VIOLAÇÃO
<?php
interface Veiculo
{
public function liga();
public function abreMala();
public function numEixos();
public function ehMensalista();
}
class Carro implements Veiculo {}
class Moto implements Veiculo {}
class Estacionamento
{
public function permiteEntrada(Veiculo $veiculo)
{
return $veiculo->ehMensalista();
}
}
class Pedagio
{
public function custo(Veiculo $veiculo)
{
return $veiculo->numEixos() * 5;
}
}
ISP – EXEMPLO MELHORADO
<?php
interface Veiculo
{
public function liga();
}
interface Mensalista
{
public function ehMensalista();
}
interface Mala
{
public function abreMala();
}
interface Eixos
{
public function numEixos();
}
class Carro implements Veiculo, Mensalista, Mala, Eixos {}
class Moto implements Veiculo, Mensalista, Eixos {}
class Estacionamento
{
public function permiteEntrada(Mensalista $veiculo)
{
return $veiculo->ehMensalista();
}
}
class Pedagio
{
public function custo(Eixos $veiculo)
{
return $veiculo->numEixos() * 5;
}
}
DEPENDENCY INVERSION PRINCIPLE
 Módulos de alto nível não devem depender de baixo nível, ambos
devem depender de abstrações
 Abstrações não devem depender de detalhes. Detalhes devem
depender de abstrações
 Use o mesmo nível de abstração num determinado nível
DIP - EXEMPLO
<?php
class PDFReader {
private $book;
function __construct(PDFBook $book) {
$this->book = $book;
}
function read() {
return $this->book->read();
}
}
class PDFBook {
function read() {
return "lendo um livro pdf.";
}
}
class Test extends PHPUnit_Framework_TestCase {
function testItCanReadAPDFBook() {
$b = new PDFBook();
$r = new PDFReader($b);
$this->assertRegExp('/livro pdf/', $r->read());
}
}
DIP – EXEMPLO DE VIOLAÇÃO
<?php
class EBookReader {
private $book;
function __construct(PDFBook $book) {
$this->book = $book;
}
function read() {
return $this->book->read();
}
}
class PDFBook {
function read() {
return “lendo um livro pdf.";
}
}
class Test extends PHPUnit_Framework_TestCase {
function testItCanReadAPDFBook() {
$b = new PDFBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro pdf/', $r->read());
}
}
DIP – EXEMPLO MELHORADO
<?php
interface EBook {
function read();
}
class EBookReader {
private $book;
function __construct(EBook $book) {
$this->book = $book;
}
function read() {
return $this->book->read();
}
}
class PDFBook implements Ebook {
function read() {
return " lendo um livro pdf.";
}
}
class Test extends PHPUnit_Framework_TestCase {
function testItCanReadAPDFBook() {
$b = new PDFBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro pdf/', $r->read());
}
}
DIP – EXEMPLO MELHORADO 2
<?php
interface EBook {
function read();
}
class EBookReader {
private $book;
function __construct(EBook $book) {
$this->book = $book;
}
function read() {
return $this->book->read();
}
}
class PDFBook implements EBook {
function read() {
return “lendo um livro pdf.";
}
}
class MobiBook implements EBook {
function read() {
return “lendo um livro mobi.";
}
}
class Test extends PHPUnit_Framework_TestCase {
function testItCanReadAPDFBook() {
$b = new PDFBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro pdf/', $r->read());
}
function testItCanReadAMobiBook() {
$b = new MobiBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro mobi/', $r->read());
}
}
DIP – EXEMPLO MELHORADO 2
<?php
interface EBook {
function read();
}
class EBookReader {
private $book;
function __construct(EBook $book) {
$this->book = $book;
}
function read() {
return $this->book->read();
}
}
class PDFBook implements EBook {
function read() {
return “lendo um livro pdf.";
}
}
class MobiBook implements EBook {
function read() {
return “lendo um livro mobi.";
}
}
class Test extends PHPUnit_Framework_TestCase {
function testItCanReadAPDFBook() {
$b = new PDFBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro pdf/', $r->read());
}
function testItCanReadAMobiBook() {
$b = new MobiBook();
$r = new EBookReader($b);
$this->assertRegExp('/livro mobi/', $r->read());
}
}
• Não precisamos mudar a classe EBooReader = OCP
• Separamos as responsabilidades = SRP
• Segregamos nossas interfaces = ISP
• Usamos corretamente o subtipo = LSP
• DIP nos ajuda a manter os outros 4 princípios

Mais conteúdo relacionado

Mais procurados

(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - SubalgoritmosCarlos Santos
 
CakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoCakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoIvan Rosolen
 
Zend Framework - PHPSP - 2009
Zend Framework - PHPSP - 2009Zend Framework - PHPSP - 2009
Zend Framework - PHPSP - 2009silva.edgar
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitDiego Tremper
 
Design de aplicações orientadas a objeto
Design de aplicações orientadas a objetoDesign de aplicações orientadas a objeto
Design de aplicações orientadas a objetoElaine Naomi
 
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...tdc-globalcode
 
Introdução à programação
Introdução à programação Introdução à programação
Introdução à programação João Piedade
 
Boas práticas no desenvolvimento de software
Boas práticas no desenvolvimento de softwareBoas práticas no desenvolvimento de software
Boas práticas no desenvolvimento de softwareFelipe
 
Heranca reescrita e_polimorfismo
Heranca reescrita e_polimorfismoHeranca reescrita e_polimorfismo
Heranca reescrita e_polimorfismoPedro Neto
 
Servlets E Applet
Servlets E AppletServlets E Applet
Servlets E Appletasiramage
 
Python e Django
Python e DjangoPython e Django
Python e Djangopugpe
 
Slide Aula - Curso CakePHP
Slide Aula - Curso CakePHPSlide Aula - Curso CakePHP
Slide Aula - Curso CakePHPRangel Javier
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com DjangoMarinho Brandão
 
Desenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpDesenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpRodrigo Aramburu
 

Mais procurados (20)

Spa com angular js flisol 2015 - aquidauana ms
Spa com angular js   flisol 2015 - aquidauana msSpa com angular js   flisol 2015 - aquidauana ms
Spa com angular js flisol 2015 - aquidauana ms
 
Php 08 Oo
Php 08 OoPhp 08 Oo
Php 08 Oo
 
(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos
 
Aula03 - JavaScript
Aula03 - JavaScriptAula03 - JavaScript
Aula03 - JavaScript
 
CakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoCakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápido
 
Zend Framework - PHPSP - 2009
Zend Framework - PHPSP - 2009Zend Framework - PHPSP - 2009
Zend Framework - PHPSP - 2009
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
Design de aplicações orientadas a objeto
Design de aplicações orientadas a objetoDesign de aplicações orientadas a objeto
Design de aplicações orientadas a objeto
 
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
TDC2018SP | Trilha Ruby - Design de aplicacoes orientadas a objeto: uma visao...
 
Aula05-JavaScript
Aula05-JavaScriptAula05-JavaScript
Aula05-JavaScript
 
Introdução à programação
Introdução à programação Introdução à programação
Introdução à programação
 
Boas práticas no desenvolvimento de software
Boas práticas no desenvolvimento de softwareBoas práticas no desenvolvimento de software
Boas práticas no desenvolvimento de software
 
Heranca reescrita e_polimorfismo
Heranca reescrita e_polimorfismoHeranca reescrita e_polimorfismo
Heranca reescrita e_polimorfismo
 
Servlets E Applet
Servlets E AppletServlets E Applet
Servlets E Applet
 
Python e Django
Python e DjangoPython e Django
Python e Django
 
Aula2
Aula2Aula2
Aula2
 
Java script aula 08 - formulários
Java script   aula 08 - formuláriosJava script   aula 08 - formulários
Java script aula 08 - formulários
 
Slide Aula - Curso CakePHP
Slide Aula - Curso CakePHPSlide Aula - Curso CakePHP
Slide Aula - Curso CakePHP
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com Django
 
Desenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpDesenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephp
 

Semelhante a DevTalk Zoox 04/2016

Refatoração - aquela caprichada no código
Refatoração - aquela caprichada no códigoRefatoração - aquela caprichada no código
Refatoração - aquela caprichada no códigoJuciellen Cabrera
 
Injeção de Dependências com PHP
Injeção de Dependências com PHPInjeção de Dependências com PHP
Injeção de Dependências com PHPDanilo Godoy
 
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011Luís Cobucci
 
PHP: Linguagem + Mysql + MVC + AJAX
PHP: Linguagem + Mysql + MVC + AJAX PHP: Linguagem + Mysql + MVC + AJAX
PHP: Linguagem + Mysql + MVC + AJAX Sérgio Souza Costa
 
principios_SOLID_resumo.pdf
principios_SOLID_resumo.pdfprincipios_SOLID_resumo.pdf
principios_SOLID_resumo.pdfssuser9941f1
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Rodrigo Urubatan
 
Programando Melhor - Flisol
Programando Melhor - FlisolProgramando Melhor - Flisol
Programando Melhor - FlisolLeonn Leite
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3Jose Berardo
 
Ecommerce, mais simples do que parece
Ecommerce, mais simples do que pareceEcommerce, mais simples do que parece
Ecommerce, mais simples do que pareceImpacta Eventos
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao javaArmando Daniel
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitDiego Tremper
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o JavascriptMichel Ribeiro
 
Hooks, o condimento mágico e escondido do WordPress
Hooks, o condimento mágico e escondido do WordPressHooks, o condimento mágico e escondido do WordPress
Hooks, o condimento mágico e escondido do WordPressZé Fontainhas
 
Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01joaocarlobarros
 
Introdução a programação II
Introdução a programação IIIntrodução a programação II
Introdução a programação IIClerton Leal
 

Semelhante a DevTalk Zoox 04/2016 (20)

Refatoração - aquela caprichada no código
Refatoração - aquela caprichada no códigoRefatoração - aquela caprichada no código
Refatoração - aquela caprichada no código
 
Solid
SolidSolid
Solid
 
Injeção de Dependências com PHP
Injeção de Dependências com PHPInjeção de Dependências com PHP
Injeção de Dependências com PHP
 
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011Removendo o cheiro ruim do seu código - PHPSC Conf 2011
Removendo o cheiro ruim do seu código - PHPSC Conf 2011
 
PHP: Linguagem + Mysql + MVC + AJAX
PHP: Linguagem + Mysql + MVC + AJAX PHP: Linguagem + Mysql + MVC + AJAX
PHP: Linguagem + Mysql + MVC + AJAX
 
principios_SOLID_resumo.pdf
principios_SOLID_resumo.pdfprincipios_SOLID_resumo.pdf
principios_SOLID_resumo.pdf
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
 
Programando Melhor - Flisol
Programando Melhor - FlisolProgramando Melhor - Flisol
Programando Melhor - Flisol
 
PHP 5.3 - Funções
PHP 5.3 - FunçõesPHP 5.3 - Funções
PHP 5.3 - Funções
 
O que há de novo no PHP 5.3
O que há de novo no PHP 5.3O que há de novo no PHP 5.3
O que há de novo no PHP 5.3
 
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
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
 
Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)Tema 2 | Linguagem PHP Básico (I)
Tema 2 | Linguagem PHP Básico (I)
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
 
Hooks, o condimento mágico e escondido do WordPress
Hooks, o condimento mágico e escondido do WordPressHooks, o condimento mágico e escondido do WordPress
Hooks, o condimento mágico e escondido do WordPress
 
Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01Serversidephp pptx2-120418140114-phpapp01
Serversidephp pptx2-120418140114-phpapp01
 
Encapsulamento em oo
Encapsulamento em ooEncapsulamento em oo
Encapsulamento em oo
 
Introdução a programação II
Introdução a programação IIIntrodução a programação II
Introdução a programação II
 

DevTalk Zoox 04/2016

  • 1. ZOOX DEV TALK 04/2016 Princípios para melhorar um código
  • 2. MOTIVAÇÃO  Por que devemos sempre melhorar o código?  Por que um código que funciona não é suficiente?
  • 3. AVISO  Estes princípios são sugestões e não regras!
  • 4. STUPID  Singleton  Tight Coupling  Untestability  Premature Optimization  Indescriptive Naming  Duplication
  • 5. SINGLETON  Representa um estado global do seu código  Programas que usam estado global são difíceis de testar e debugar  Programas que dependem do estado global mascaram suas dependências
  • 6. TIGHT COUPLING  Generalização do problema com Singleton  Se mudar um módulo te obriga a mudar outro módulo  Torna o código difícil de reusar e testar  Para evitar, favorecer composição sobre herança e usar injeção de dependência sempre que possível
  • 7. UNTESTABILITY  Testes não devem ser difíceis  Deixar de escrever um teste economiza tempo de imediato, mas perde muito mais depois ”caçando” bugs e testando manualmente (falho)  Se escrever um teste é difícil, o problema está no código  Normalmente, untestability é causada por tight coupling
  • 8. PREMATURE OPTIMIZATION  Não super complique o código para otimizá-lo  Terá apenas custo e não benefício  Meça a performance antes de otimizar (benchmarks)  YAGNI = You Ain’t Gonna Need It (Você não vai precisar disso)
  • 9. INDESCRIPTIVE NAMING  Nomeie classes, métodos, atributos apropriadamente  Não abrevie  Se não consegue achar um nome apropriado para uma classe, talvez a responsabilidade dela não esteja bem definida.  Linguagem de programação é para humanos  Para o computador, $vlna é o mesmo que $valorLitraoNoAlto
  • 10. DUPLICAÇÃO  Se duplicar código e tiver que fazer um ajuste, terá que mexer em vários lugares (e se esquecer de um?)  DRY = Don’t Repeat Youself  KISS = Keep It Simple, Stupid!
  • 11. SOLID  Single Responsibility Principle  Open/Close Principle  Liskov Substitution Principle  Interface Segregation Principle  Dependency Inversion Principle
  • 12. SINGLE RESPONSIBILITY PRINCIPLE  Nunca deve haver mais de uma razão para uma classe mudar  Divida classes grandes  Use camadas  Evite classes God
  • 13. SRP - EXEMPLO <?php class Livro { function getAutor() { return 'João da Silva'; } function getTitulo() { return 'Grande Livro'; } function virarPagina() { // Avança ponteiro de página } function mostraPaginaAtual() { echo 'Conteúdo da página'; } } O que há de errado no código?
  • 14. SRP – EXEMPLO MELHORADO <?php class Livro { function getTitulo() { return 'Grande Livro'; } function getPaginaAtual() { echo 'Conteúdo da página'; } } interface Printer { function printPage($page); } class PlainTextPrinter implements Printer { function printPage($page) { echo $page; } } class HtmlPrinter implements Printer { function printPage($page) { echo '<div style="single-page">' . $page . '</div>'; } } $livro = new Livro(); $printer = new HtmlPrinter(); $printer->printPage($livro->getPaginaAtual());
  • 15. OPEN/CLOSE PRINCIPLE  Classes devem ser abertas para expansão, mas fechadas para alteração  Defina todos os atributos como private  Sem variáveis globais  Evite setter (sempre que possível)
  • 16. OCP - EXEMPLO <?php class Retangulo { public $altura; public $largura; } class Area { public function calculaArea(Retangulo $retangulo) { return $retangulo->altura * $retangulo->largura; } }
  • 17. OCP – EXEMPLO DE VIOLAÇÃO <?php class Retangulo { public $altura; public $largura; } class Circulo { public $radio; } class Area { public function calculaArea($objeto) { if ($objeto instanceof Retangulo) { return $objeto->altura * $objeto->largura; } elseif ($objeto instanceof Circulo) { return $objeto->circulo * $objeto->circulo * PI; } } }
  • 18. OCP – EXEMPLO DE VIOLAÇÃO <?php class Retangulo { public $altura; public $largura; } class Circulo { public $radio; } class Area { public function calculaArea($objeto) { if ($objeto instanceof Retangulo) { return $objeto->altura * $objeto->largura; } elseif ($objeto instanceof Circulo) { return $objeto->circulo * $objeto->circulo * PI; } } } Tivemos que alterar a classe Area para poder extendê-la. Ela não é fechada para modificações = não é aberta para expansão
  • 19. OCP – EXEMPLO MELHORADO <?php abstract class Forma { abstract function calculaArea(); } class Retangulo extends Forma { public $altura; public $largura; public function calculaArea() { return $this->altura * $this->largura; } } class Circulo extends Forma { public $radio; public function calculaArea() { return $this->circulo * $this->circulo * PI; } } class Area { public function calculaArea(Forma $objeto) { return $objeto->calculaArea(); } }
  • 20. LISKOV SUBSTITUTION PRINCIPLE  Subclasses devem poder ser substituidas por sua classe base  Classes filhas não devem quebrar as definições de suas bases  Objetos num código devem poder ser substituídos por seus subtipos sem alterar o funcionamento correto do programa
  • 21. LSP - EXEMPLO <?php class Retangulo { protected $altura; protected $largura; public function setLargura($largura) { $this->largura = $largura; } public function setAltura($altura) { $this->altura = $altura; } public function getArea() { return $this->altura * $this->largura; } } $retangulo = new Retangulo(); $retangulo->setAltura(10); $retangulo->setLargura(20); if ($retangulo->getArea() !== 200) { throw new Exception('Área errada'); } 0
  • 22. LSP - EXEMPLO DE VIOLAÇÃO <?php class Retangulo { protected $altura; protected $largura; public function setLargura($largura) { $this->largura = $largura; } public function setAltura($altura) { $this->altura = $altura; } public function getArea() { return $this->altura * $this->largura; } } class Quadrado extends Retangulo { public function setLargura($largura) { $this->largura = $this->altura = $largura; } public function setAltura($altura) { $this->altura = $this->largura = $altura; } } $quadrado = new Quadrado(); $quadrado->setAltura(10); $quadrado->setLargura(20); if ($quadrado->getArea() !== 200) { throw new Exception('Área errada'); }
  • 23. INTERFACE SEGREGATION PRINCIPLE  Melhor ter várias interfaces específicas a uma só genérica  Uma classe não deveria implementar métodos que não usa  Usando ISP você garante low coupling e high coersion
  • 24. ISP - EXEMPLO <?php interface Veiculo { public function liga(); public function abreMala(); public function numEixos(); public function ehMensalista(); } class Carro implements Veiculo { } class Estacionamento { public function permiteEntrada(Veiculo $veiculo) { return $veiculo->ehMensalista(); } } class Pedagio { public function custo(Veiculo $veiculo) { return $veiculo->numEixos() * 5; } }
  • 25. ISP – EXEMPLO DE VIOLAÇÃO <?php interface Veiculo { public function liga(); public function abreMala(); public function numEixos(); public function ehMensalista(); } class Carro implements Veiculo {} class Moto implements Veiculo {} class Estacionamento { public function permiteEntrada(Veiculo $veiculo) { return $veiculo->ehMensalista(); } } class Pedagio { public function custo(Veiculo $veiculo) { return $veiculo->numEixos() * 5; } }
  • 26. ISP – EXEMPLO MELHORADO <?php interface Veiculo { public function liga(); } interface Mensalista { public function ehMensalista(); } interface Mala { public function abreMala(); } interface Eixos { public function numEixos(); } class Carro implements Veiculo, Mensalista, Mala, Eixos {} class Moto implements Veiculo, Mensalista, Eixos {} class Estacionamento { public function permiteEntrada(Mensalista $veiculo) { return $veiculo->ehMensalista(); } } class Pedagio { public function custo(Eixos $veiculo) { return $veiculo->numEixos() * 5; } }
  • 27. DEPENDENCY INVERSION PRINCIPLE  Módulos de alto nível não devem depender de baixo nível, ambos devem depender de abstrações  Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações  Use o mesmo nível de abstração num determinado nível
  • 28. DIP - EXEMPLO <?php class PDFReader { private $book; function __construct(PDFBook $book) { $this->book = $book; } function read() { return $this->book->read(); } } class PDFBook { function read() { return "lendo um livro pdf."; } } class Test extends PHPUnit_Framework_TestCase { function testItCanReadAPDFBook() { $b = new PDFBook(); $r = new PDFReader($b); $this->assertRegExp('/livro pdf/', $r->read()); } }
  • 29. DIP – EXEMPLO DE VIOLAÇÃO <?php class EBookReader { private $book; function __construct(PDFBook $book) { $this->book = $book; } function read() { return $this->book->read(); } } class PDFBook { function read() { return “lendo um livro pdf."; } } class Test extends PHPUnit_Framework_TestCase { function testItCanReadAPDFBook() { $b = new PDFBook(); $r = new EBookReader($b); $this->assertRegExp('/livro pdf/', $r->read()); } }
  • 30. DIP – EXEMPLO MELHORADO <?php interface EBook { function read(); } class EBookReader { private $book; function __construct(EBook $book) { $this->book = $book; } function read() { return $this->book->read(); } } class PDFBook implements Ebook { function read() { return " lendo um livro pdf."; } } class Test extends PHPUnit_Framework_TestCase { function testItCanReadAPDFBook() { $b = new PDFBook(); $r = new EBookReader($b); $this->assertRegExp('/livro pdf/', $r->read()); } }
  • 31. DIP – EXEMPLO MELHORADO 2 <?php interface EBook { function read(); } class EBookReader { private $book; function __construct(EBook $book) { $this->book = $book; } function read() { return $this->book->read(); } } class PDFBook implements EBook { function read() { return “lendo um livro pdf."; } } class MobiBook implements EBook { function read() { return “lendo um livro mobi."; } } class Test extends PHPUnit_Framework_TestCase { function testItCanReadAPDFBook() { $b = new PDFBook(); $r = new EBookReader($b); $this->assertRegExp('/livro pdf/', $r->read()); } function testItCanReadAMobiBook() { $b = new MobiBook(); $r = new EBookReader($b); $this->assertRegExp('/livro mobi/', $r->read()); } }
  • 32. DIP – EXEMPLO MELHORADO 2 <?php interface EBook { function read(); } class EBookReader { private $book; function __construct(EBook $book) { $this->book = $book; } function read() { return $this->book->read(); } } class PDFBook implements EBook { function read() { return “lendo um livro pdf."; } } class MobiBook implements EBook { function read() { return “lendo um livro mobi."; } } class Test extends PHPUnit_Framework_TestCase { function testItCanReadAPDFBook() { $b = new PDFBook(); $r = new EBookReader($b); $this->assertRegExp('/livro pdf/', $r->read()); } function testItCanReadAMobiBook() { $b = new MobiBook(); $r = new EBookReader($b); $this->assertRegExp('/livro mobi/', $r->read()); } } • Não precisamos mudar a classe EBooReader = OCP • Separamos as responsabilidades = SRP • Segregamos nossas interfaces = ISP • Usamos corretamente o subtipo = LSP • DIP nos ajuda a manter os outros 4 princípios