lidando com código duplicado - php conference brasil 2013

Post on 14-Jun-2015

1.395 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides da minha palestra sobre código duplicado na PHP Conference Brasil 2013

TRANSCRIPT

LIDANDO COM CÓDIGODUPLICADO

Evaldo Junior Bento

29/11/2013

CC BY-NC-SA

EVALDO JUNIORTecnólogo em Processamento de DadosMBA em Gestão Estratégica de TIDesenvolvedor WebUso principalmente PHP

HTML, CSS, JavaScript, SQL...GNU/Linux - Python - VimDafitiUnimonte

ESCREVI UM LIVRO DE PHP E MYSQLCASA DO CÓDIGO

EVALDO10

CONTEÚDO DESTA APRESENTAÇÃODéjà vuOs problemas da duplicação de códigoManeiras de identificar código duplicadoTécnicas para corrigir a duplicação de código

CÓDIGO DUPLICADOProgramando de boa na lagoa quando...

As vezes não sabemos que é um códigoduplicado, apenas ficamos com a sensação de

Déjà vu

RELATIVAMENTE COMUMVocê não está sozinhoDuplicação é o número 1 dos "bad smells"

O QUE A DUPLICAÇÃO CAUSA?

TAMANHO DA BASE DE CÓDIGO AUMENTA;

COMPREENSÃO É PREJUDICADA;

MANUTENÇÃO É MAIS TRABALHOSA E MAIS PROPENSA ÀFALHAS.

Alterar uma parte pode quebrar outrasA correção de uma parte não corrige outras

COMO O PROBLEMA É CRIADO?

MAIS DE UM PROGRAMADOR;Equipe do eu sozinho também

FUNCIONALIDADES PARECIDAS NO MESMO SOFTWARE;Copiar e colarPreguiça de isolarDesconhecimento de outras partes

FUNCIONALIDADES PARECIDAS EM SOFTWARES DIFERENTESDO MESMO PROGRAMADOR/EMPRESA.

Copiar e colarPoderia ser isolado

UM EXEMPLO DO PROBLEMA:PÁGINA DE LOGIN

1 - BLOCO COM FORM DE LOGIN2 - PÁGINA APENAS DE LOGIN

Login com e-mail e senha

EM COMUM:Terão o mesmo formulárioAs mesmas validaçõesO mesmo comportamento

COMO COSTUMA SER FEITO?Uma das opções é criada e então é copiada

E OS PROBLEMAS...Alterações ficam complicadasE se a autenticação for por CPF ou e-mail?E se entrar uma API para login via Twitter?

COMO IDENTIFICAR CÓDIGO DUPLICADO

IDENTIFICAÇÃO MANUAL;Complexa e não exata (além de trabalhosa)Acontece quando sem querer se esbarra em duplicaçõesPode ser encontrada quando se procura

USO DE FERRAMENTAS COMO DIFF, MELD ETC;Bom, mas tem que saber o que querExemplo:

Classes de clientes e funcionários que podem sersemelhantes

USO DE FERRAMENTAS DE DETECÇÃO.CPD (Copy/PasteDetector)

UM EXEMPLO DO PHPCPD:$ phpcpd --progress application

Processing files268 / 268 [++++++++++++++++++++++++++++++++++++++++++++++>] 100.00%

Found 22 exact clones with 275 duplicated lines in 31 files:- application/models/Conta_receber.php:30-65 application/models/Conta_pagar.php:30-65

IDENTIFIQUEI! E AGORA?

DRYDon't Repeat Yourself

DRYEvery piece of knowledge must have a single,unambiguous, authoritative representation

within a system.

Andy Hunt e Dave Thomas - The Pragmatic Programmer

TÉCNICAS PROCEDURAIS

BIBLIOTECAS DE FUNÇÕES;HelpersExtraia as partes repetidas para uma função

UM EXEMPLO BÁSICO echo 'R$' . number_format($amount, 2, '.', ',');

echo 'R$' . number_format($amount, 2, '.', ',');

echo 'R$' . number_format($amount, 2, '.', ',');

echo 'R$' . number_format($amount, 2, '.', ',');

PODE FICAR MELHOR ASSIM: function currency_format( $amount, $money_symbol = 'R$', $decimals = 2, $dec = ',', $thousands = '.') { return $money_symbol . number_format($amount, $decimals, $dec, $thousands);}

echo currency_format($amount);

OUTRO EXEMPLO function sum_posts_and_pages_comments($posts, $pages) { $total_comments = 0;

foreach ($posts as $post) { $total_comments += count($post->comments); }

foreach ($pages as $page) { $total_comments += count($page->comments); }

return $total_comments;}

OUTRO SEM REPETIR: function sum_comments($commentables) { $total_comments = 0;

foreach ($commentables as $commentable) { $total_comments += count($commentable->comments); }

return $total_comments;}

function sum_posts_and_pages_comments($posts, $pages) { $total_comments = sum_comments($posts); $total_comments += sum_comments($pages);

return $total_comments;}

CLASSES UTILITÁRIAS.HelpersExtraia as partes repetidas para um método

TÉCNICAS OO

EXTRACT METHOD;

EXTRACT METHOD;Métodos com trechos semelhantesExtraia para apenas um método e use nos outrosTambém pode ser usado para simplificar métodos grandes

EXTRACT METHOD public function someAction(){ if (! $this->getUser()->canAccess('SomeSection', 'Admin')) { $this->redirect('/notauthorized'); } if ($this->env->isDev()) { $this->enableProfiler(); } // ...}

public function anotherAction(){ if (! $this->getUser()->canAccess('SomeSection', 'Admin')) { $this->redirect('/notauthorized'); } if ($this->env->isDev()) { $this->enableProfiler(); } // ...}

EXTRACT METHOD private function checkPermissionAdmin($section){ if (! $this->getUser()->canAccess($section, 'Admin')) { $this->redirect('/notauthorized'); }}private function enableProfiler(){ if ($this->env->isDev()) { $this->enableProfiler(); }}public function someAction(){ $this->checkPermissionAdmin('SomeSection'); $this->enableProfiler(); // ...}

public function anotherAction(){ $this->checkPermissionAdmin('SomeSection'); $this->enableProfiler(); // ...}

EXTRACT CLASS;

EXTRACT CLASS;Métodos parecidos/iguais em mais de uma classeAs classes não precisam ser relacionadasExtraia para outra classe e use como um componente

EXTRACT CLASS // Repetido em vários controllersprivate function checkPermissionAdmin($section){ if (! $this->getUser()->canAccess($section, 'Admin')) { $this->redirect('/notauthorized'); }}// Repetido em vários controllersprivate function enableProfiler(){ if ($this->env->isDev()) { $this->enableProfiler(); }}

EXTRACT CLASS class Acl { public function checkPermission($section, $role) { $app = App::getInstance(); if (! $app->getUser()->canAccess($section, $role)) { $app->redirect('/notauthorized'); } }}

EXTRACT CLASS class Profiler { private function enableProfiler() { $app = App::getInstance(); if ($app->env->isDev()) { $app->enableProfiler(); } }}

EXTRACT CLASS public function __construct(){ $p = new Profiler(); $p->enableProfiler();}public function someAction(){ $acl = new Acl(); $acl->checkPermission('SomeSection', 'Admin'); // ...}

PULL UP FIELD;

PULL UP FIELD;Duas subclasses com o mesmo campoMova o campo para a super classe

FORM TEMPLATE METHOD;

FORM TEMPLATE METHOD;Métodos praticamente iguais em subclassesPoucas variaçõesNão é possível simplesmente mover o método para asuperclasseSepare as diferenças em métodos com a mesma assinaturaUse os novos métodos no método principal

FORM TEMPLATE METHOD;

DESIGN PATTERNS.Foco em reusoVale muito a pena entender os conceitosForm Template Method == Template Method

RESUMODuplicação é ruim

Causada por preguiça ou desconhecimentoFerramentas de detecção ajudam

Mas não adianta apenas saber que existe duplicaçãoTécnicas podem ser usadasDesign Patterns importam

REFERÊNCIAShttp://phpqatools.org/http://es.wikipedia.org/wiki/C%C3%B3digo_duplicadohttp://en.wikipedia.org/wiki/Duplicate_codehttp://en.wikipedia.org/wiki/Don%27t_repeat_yourselfhttp://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysishttp://en.wikipedia.org/wiki/Template_method_patternhttp://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithmhttps://github.com/sebastianbergmann/phpcpdhttp://sourcemaking.com/refactoring/bad-smells-in-codehttp://sourcemaking.com/refactoring/duplicated-codehttp://sourcemaking.com/refactoring/extract-methodhttp://sourcemaking.com/refactoring/pull-up-fieldhttp://sourcemaking.com/refactoring/form-template-methodhttp://sourcemaking.com/refactoring/extract-class

PERGUNTAS?

OBRIGADO!CONTATOS

Site: evaldojunior.com.brE-mail: evaldojuniorbento@gmail.comabout.me/evaldojuniortwitter.com/InFog9

top related