Exemple
Je suis tombé sur un code monolithique qui fait "tout" en un seul endroit - charger des données à partir de la base de données, montrer le balisage HTML, agir comme un routeur / contrôleur / action. J'ai commencé à appliquer le code de base de données mobile SRP dans son propre fichier, fournissant une meilleure dénomination des choses, et tout semblait bien, mais j'ai ensuite commencé à douter de la raison pour laquelle je fais cela.
Pourquoi refactoriser? Quel est le but? Est-ce inutile? Quel est l'avantage? Notez que j'ai principalement laissé le fichier monolithique tel quel, mais que je n'ai refactorisé que la plus petite partie qui était pertinente pour la zone où j'avais besoin de faire un peu de travail.
Code d'origine:
Pour donner un exemple concret, je suis tombé sur cet extrait de code - il charge les spécifications du produit soit par un identifiant de produit connu, soit par un identifiant de version sélectionné par l'utilisateur:
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 */
Refactoring:
Étant donné que je fais un travail me demandant de changer les choses dans cette partie spécifique du code, je l'ai changé pour utiliser le modèle de référentiel et l'ai mis à niveau pour utiliser les fonctionnalités MySQL orientées objet:
//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();
}
}
Dois-je faire ça?
En regardant les changements, le code est toujours là, code avec la même fonctionnalité, mais dans des fichiers différents, des noms et des endroits différents, en utilisant un style plus orienté objet plutôt que procédural. En fait, il est amusant de noter que le code refactorisé semble beaucoup plus gonflé malgré les mêmes fonctionnalités.
Je prévois quelques réponses disant "si vous ne connaissez pas les raisons pour lesquelles vous refactorisez, ne le faites pas", et peut-être que je pourrais être d'accord. Mes raisons sont d'améliorer la qualité du code au fil du temps (et j'espère que je le ferai en suivant SRP et d'autres principes).
Ces raisons sont-elles suffisantes ou suis-je en train de perdre mon temps à "réorganiser le code" de cette façon? Pour être honnête, le refactoring global ressemble un peu à de l'eau - cela prend du temps et il devient plus "séparé" en ce qui concerne SRP, mais malgré mes bonnes intentions, je n'ai pas l'impression de faire des améliorations incroyables. Par conséquent, débattre s'il est préférable de laisser le code comme avant et non de refactoriser.
Pourquoi ai-je refactorisé en premier lieu?
Dans mon cas, j'ajoute de nouvelles fonctionnalités pour une nouvelle gamme de produits, je dois donc soit suivre la structure de code existante pour des gammes de produits similaires, soit écrire la mienne.
select *
devient une "meilleure pratique".
Select * from ..
peut être considéré comme un anti-modèle. Voir stackoverflow.com/q/3639861/31326