Exemplo
Me deparei com um código monolítico que faz "tudo" em um só lugar - carregando dados do banco de dados, mostrando a marcação HTML, agindo como um roteador / controlador / ação. Comecei a aplicar o código do banco de dados móvel SRP em seu próprio arquivo, fornecendo nomes melhores para as coisas, e tudo parecia bom, mas comecei a ter dúvidas sobre o motivo de estar fazendo isso.
Por que refatorar? Qual é o propósito? Isso é inútil? Qual o benefício? Observe que na maioria das vezes deixei o arquivo monolítico como está, mas refatorei apenas a parte menor que era relevante para a área em que eu precisava fazer algum trabalho.
Código original:
Para dar um exemplo concreto, deparei-me com esse trecho de código - ele carrega as especificações do produto por um ID de produto conhecido ou por um ID de versão selecionado pelo usuário:
if ($verid)
$sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
$sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */
Reestruturação:
Como estou fazendo algum trabalho exigindo que eu mude as coisas nesta parte específica do código, mudei para usar o padrão de repositório e atualizei-o para usar os recursos MySQL orientados a objetos:
//some implementation details omitted
$this->repository = new SpecRepository($mysql);
if ($verid)
$row1 = $this->repository->getSpecByVersion($verid);
else
$row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/
//added new class:
class SpecRepository extends MySqlRepository
{
function getSpecByVersion(int $verid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE id = ?
", $verid)->getSingleArray();
}
function getSpecByProductId(int $productid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE product_id = ?
", $productid)->getSingleArray();
}
}
Devo fazer isso?
Olhando para as mudanças, o código ainda está lá, com a mesma funcionalidade, mas em arquivos diferentes, nomes diferentes, lugares, usando mais estilo orientado a objetos do que procedimental. Na verdade, é engraçado notar que o código refatorado parece muito mais inchado, apesar de ter a mesma funcionalidade.
Prevejo algumas respostas dizendo "se você não sabe as razões pelas quais refatorar, não faça", e talvez eu concorde. Minha razão é melhorar a qualidade do código ao longo do tempo (e minha esperança é que eu o faça seguindo o SRP e outros princípios).
Essas são boas razões ou estou desperdiçando meu tempo em "reorganizar o código" dessa maneira? A refatoração geral parece um pouco como pisar na água para ser honesto - leva tempo e fica mais "separado" no que diz respeito ao SRP, mas, apesar das minhas boas intenções, não sinto que estou fazendo melhorias incríveis. Portanto, debatendo se é melhor deixar o código como antes e não refatorar.
Por que refatorei em primeiro lugar?
No meu caso, estou adicionando novas funcionalidades a uma nova linha de produtos; portanto, devo seguir a estrutura de código existente para linhas de produtos similares ou escrever a minha.
select *
torna-se uma "melhor prática".
Select * from ..
pode ser considerado um antipadrão. Veja stackoverflow.com/q/3639861/31326