Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like OledrionOledrion_caddyHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OledrionOledrion_caddyHandler, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 69 | class OledrionOledrion_caddyHandler extends Oledrion_XoopsPersistableObjectHandler |
||
| 70 | { |
||
| 71 | const CADDY_NAME = 'oledrion_caddie'; // Nom du panier en session |
||
| 72 | |||
| 73 | /** |
||
| 74 | * OledrionOledrion_caddyHandler constructor. |
||
| 75 | * @param XoopsDatabase|null $db |
||
| 76 | */ |
||
| 77 | public function __construct(XoopsDatabase $db) |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Renvoie, si on en trouve un, un produit qui s'est bien vendu avec un produit particulier |
||
| 84 | * |
||
| 85 | * @param integer $caddy_product_id Identifiant du produit dont on recherche le jumeau |
||
| 86 | * @return integer Le n° du produit le plus vendu avec le produit en question |
||
| 87 | */ |
||
| 88 | public function getBestWith($caddy_product_id) |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Renvoie la liste des produits les plus vendus toutes catégories confondues |
||
| 107 | * |
||
| 108 | * @param integer $start Début de la recherche |
||
| 109 | * @param integer $limit Nombre maximum d'enregistrements à retourner |
||
| 110 | * @param int $product_cid |
||
| 111 | * @param bool $withQuantity |
||
| 112 | * @return array Les identifiants des X produits les plus vendus dans cette catégorie |
||
| 113 | */ |
||
| 114 | public function getMostSoldProducts($start = 0, $limit = 0, $product_cid = 0, $withQuantity = false) |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Retourne la liste des ID de produits vendus récemment |
||
| 151 | * |
||
| 152 | * @param integer $start |
||
| 153 | * @param integer $limit |
||
| 154 | * @return array |
||
| 155 | * @since 2.3.2009.04.08 |
||
| 156 | */ |
||
| 157 | public function getRecentlySoldProducts($start = 0, $limit = 0) |
||
| 179 | |||
| 180 | /** |
||
| 181 | * Indique si le caddy est vide ou pas |
||
| 182 | * |
||
| 183 | * @return boolean vide, ou pas... |
||
| 184 | */ |
||
| 185 | public function isCartEmpty() |
||
| 193 | |||
| 194 | /** |
||
| 195 | * Vidage du caddy, s'il existe |
||
| 196 | */ |
||
| 197 | public function emptyCart() |
||
| 207 | |||
| 208 | /** |
||
| 209 | * Recharge le dernier panier de l'utilisateur |
||
| 210 | * |
||
| 211 | * @return boolean |
||
| 212 | */ |
||
| 213 | public function reloadPersistentCart() |
||
| 231 | |||
| 232 | /** |
||
| 233 | * Ajout d'un produit au caddy |
||
| 234 | * |
||
| 235 | * @param integer $product_id Identifiant du produit |
||
| 236 | * @param integer $quantity Quantité à ajouter |
||
| 237 | * @param array $attributes Les attributs du produit |
||
| 238 | * @return void |
||
| 239 | * @note : Structure du panier (tableau en session) : |
||
| 240 | * [clé] = numéro de 1 à N |
||
| 241 | * [valeur] = array ( |
||
| 242 | * 'number' => numéro de 1 à N |
||
| 243 | * 'id' => ID du produit |
||
| 244 | * 'qty' => Quantité de produit |
||
| 245 | * 'attributes' => array( |
||
| 246 | * 'attr_id' => id attribut (son numéro dans la base) |
||
| 247 | * 'values' => array(valueId1, valueId2 ...) |
||
| 248 | * ) |
||
| 249 | * ) |
||
| 250 | */ |
||
| 251 | public function addProduct($product_id, $quantity, $attributes = null) |
||
| 286 | |||
| 287 | /** |
||
| 288 | * Inidique si un produit est dans le caddy |
||
| 289 | * |
||
| 290 | * @param integer $caddy_product_id Le numéro interne du produit dans la table Produits |
||
| 291 | * @return mixed False si le produit n'est pas dans le caddy sinon son indice dans le caddy |
||
| 292 | * @since 2.3.2009.03.15 |
||
| 293 | */ |
||
| 294 | View Code Duplication | public function isInCart($caddy_product_id) |
|
| 312 | |||
| 313 | /** |
||
| 314 | * Retourne les attributs d'un produit depuis le panier |
||
| 315 | * |
||
| 316 | * @param integer $caddy_product_id Le numéro interne du produit dans la table Produits |
||
| 317 | * @return mixed False si le produit n'est pas dans le caddy sinon ses attributs sous la forme d'un tableau |
||
| 318 | * @since 2.3.2009.03.15 |
||
| 319 | */ |
||
| 320 | View Code Duplication | public function getProductAttributesFromCart($caddy_product_id) |
|
| 336 | |||
| 337 | /** |
||
| 338 | * Renumérotage des produits dans le caddy après une suppression |
||
| 339 | * |
||
| 340 | * @param array $caddy Le caddy actuel |
||
| 341 | * @return array Le caddy avec 'number' renuméroté |
||
| 342 | */ |
||
| 343 | private function renumberCart($caddy) |
||
| 359 | |||
| 360 | /** |
||
| 361 | * Suppression d'un produit du caddy |
||
| 362 | * |
||
| 363 | * @param integer $indice Indice de l'élément à supprimer |
||
| 364 | */ |
||
| 365 | public function deleteProduct($indice) |
||
| 387 | |||
| 388 | /** |
||
| 389 | * Mise à jour des quantités du caddy suite à la validation du formulaire du caddy |
||
| 390 | */ |
||
| 391 | public function updateQuantites() |
||
| 430 | |||
| 431 | /** |
||
| 432 | * Renvoie les éléments constituants une commande |
||
| 433 | * |
||
| 434 | * @param integer $caddy_cmd_id Identifiant de la commande |
||
| 435 | * @return array Tableau d'objets caddy |
||
| 436 | */ |
||
| 437 | public function getCaddyFromCommand($caddy_cmd_id) |
||
| 445 | |||
| 446 | /** |
||
| 447 | * Retourne tous les produits d'un caddy |
||
| 448 | * |
||
| 449 | * @param array $carts Objets de type oledrion_caddy |
||
| 450 | * @return array Tableau d'objets de type oledrion_products, Clé = Id produit |
||
| 451 | * @since 2.31.2009.07.25 |
||
| 452 | */ |
||
| 453 | public function getProductsFromCaddy($carts) |
||
| 466 | |||
| 467 | /** |
||
| 468 | * Renvoie les ID de commandes pour un produit acheté |
||
| 469 | * |
||
| 470 | * @param integer $product_id Identifiant du produit |
||
| 471 | * @return array Les ID des commandes dans lesquelles ce produit a été commandé |
||
| 472 | */ |
||
| 473 | View Code Duplication | public function getCommandIdFromProduct($product_id) |
|
| 487 | |||
| 488 | /** |
||
| 489 | * Retourne un caddy à partir de son mot de passe |
||
| 490 | * |
||
| 491 | * @param string $caddy_pass Le mot de passe à utiliser |
||
| 492 | * @return mixed Soit un object de type oledrion_caddy ou null |
||
| 493 | */ |
||
| 494 | public function getCaddyFromPassword($caddy_pass) |
||
| 506 | |||
| 507 | /** |
||
| 508 | * Marque un caddy comme ayant été téléchargé |
||
| 509 | * |
||
| 510 | * @param oledrion_caddy $caddy |
||
| 511 | * @return boolean Le résultat de la mise à jour |
||
| 512 | */ |
||
| 513 | public function markCaddyAsNotDownloadableAnyMore(Oledrion_caddy $caddy) |
||
| 519 | |||
| 520 | /** |
||
| 521 | * Supprime les caddies associés à une commande |
||
| 522 | * |
||
| 523 | * @param integer $caddy_cmd_id |
||
| 524 | * @return boolean |
||
| 525 | */ |
||
| 526 | public function removeCartsFromOrderId($caddy_cmd_id) |
||
| 532 | } |
||
| 533 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.