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 Unite 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 Unite, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 10 | class Unite { |
||
| 11 | private $coef_unite; |
||
| 12 | private $pour_recruter; |
||
| 13 | private $temps_recrutement; |
||
| 14 | private $ameliorations; |
||
| 15 | |||
| 16 | |||
| 17 | //-------------------------- BUILDER ----------------------------------------------------------------------------// |
||
| 18 | public function __construct() { |
||
| 21 | //-------------------------- END BUILDER ----------------------------------------------------------------------------// |
||
| 22 | |||
| 23 | |||
| 24 | //-------------------------- GETTER ----------------------------------------------------------------------------// |
||
| 25 | /** |
||
| 26 | * @param $caracteristique |
||
| 27 | * @param $force |
||
| 28 | * @param $niveau |
||
| 29 | * @return float |
||
| 30 | * fonction qui permet de renvoyer la puissance d'une unité dans un élément spécifique |
||
| 31 | */ |
||
| 32 | private function getAmeliorationUnite($caracteristique, $force, $niveau) { |
||
| 42 | |||
| 43 | |||
| 44 | /** |
||
| 45 | * @param $unite |
||
| 46 | * @param $niveau |
||
| 47 | * @param $type |
||
| 48 | * @return array |
||
| 49 | * récupère les caractéristiques de l'unité en fonction de son niveau |
||
| 50 | */ |
||
| 51 | public function getCaracteristiqueUnite($unite, $niveau, $type) { |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @return array |
||
| 96 | * fonction qui renvoit tous les types d'unités qu'il est possible de recruter |
||
| 97 | */ |
||
| 98 | private function getAllType() { |
||
| 101 | |||
| 102 | /** |
||
| 103 | * @param $type |
||
| 104 | * fonction qui permet de récupérer les unités qu'i est possible de recruter en fonction |
||
| 105 | * du type (batiment sur lequel on a cliqué) |
||
| 106 | */ |
||
| 107 | public function getUnitePossibleRecruter($type) { |
||
| 119 | |||
| 120 | /** |
||
| 121 | * fonction qui renvoi les unité en cours de recrutement |
||
| 122 | */ |
||
| 123 | public function getRecrutement() { |
||
| 149 | |||
| 150 | /** |
||
| 151 | * @param null $id_base |
||
| 152 | * @param null $id_groupe |
||
| 153 | * fonction qui récupère toutes les unités qui sont dans la base |
||
| 154 | */ |
||
| 155 | public function getAllUnites($id_base = null, $id_groupe = null) { |
||
| 156 | |||
| 157 | if ($id_base == null) $id_base = Bataille::getIdBase(); |
||
| 158 | |||
| 159 | $types = $this->getAllType(); |
||
| 160 | $count_type = count($types); |
||
| 161 | $unites = []; |
||
| 162 | |||
| 163 | for ($i=0 ; $i<$count_type ; $i++) { |
||
| 164 | $type_unite = $this->getAllUniteType($types[$i], $id_base, $id_groupe); |
||
| 165 | |||
| 166 | $unites = array_merge($unites, $type_unite); |
||
| 167 | } |
||
| 168 | |||
| 169 | if (count($unites) > 0) { |
||
| 170 | if ($id_groupe == null) { |
||
| 171 | Bataille::setValues(["unites" => $unites]); |
||
| 172 | } |
||
| 173 | |||
| 174 | return $unites; |
||
| 175 | } |
||
| 176 | |||
| 177 | return 0; |
||
| 178 | } |
||
| 179 | |||
| 180 | /** |
||
| 181 | * @param $type |
||
| 182 | * @param $id_base |
||
| 183 | * @param null $id_groupe |
||
| 184 | * @return array |
||
| 185 | * fonction qui récupère toutes les unités en fonction d'un type précis |
||
| 186 | */ |
||
| 187 | private function getAllUniteType($type, $id_base, $id_groupe = null) { |
||
| 223 | |||
| 224 | /** |
||
| 225 | * @param $type |
||
| 226 | * @param $nom |
||
| 227 | * @return int |
||
| 228 | * renvoi le nombre d'unite en fonction d'un type et d'un nom qui ne sont ni dans un groupe ni |
||
| 229 | * en mission |
||
| 230 | */ |
||
| 231 | protected function getNombreUniteNom($type, $nom) { |
||
| 245 | |||
| 246 | /** |
||
| 247 | * @return int |
||
| 248 | * fonction qui renvoi le nombre d'unité vivante dans la base qui consomme de la nourriture |
||
| 249 | */ |
||
| 250 | View Code Duplication | public function getNombreUniteHumaine() { |
|
| 260 | |||
| 261 | /** |
||
| 262 | * @param $id_mission |
||
| 263 | * @return int |
||
| 264 | * fonction qui renvoi le nombre d'unités envoyées sur une mission en particulier |
||
| 265 | */ |
||
| 266 | View Code Duplication | public function getUnitesMission($id_mission) { |
|
| 276 | |||
| 277 | /** |
||
| 278 | * @param $type |
||
| 279 | * @param $nom |
||
| 280 | * récupération du temmp de recrutement + les ressources nécéssaires |
||
| 281 | */ |
||
| 282 | private function getInfosRecrutementUnite($type, $nom) { |
||
| 283 | $dbc1 = Bataille::getDb(); |
||
| 284 | |||
| 285 | $query = $dbc1->select("temps_recrutement") |
||
| 286 | ->select("pour_recruter") |
||
| 287 | ->from("unites") |
||
| 288 | ->where("nom", "=", $nom, "AND") |
||
| 289 | ->where("type", "=", $type, "") |
||
| 290 | ->get(); |
||
| 291 | |||
| 292 | if ((is_array($query)) && (count($query) == 1)) { |
||
| 293 | foreach ($query as $obj) { |
||
| 294 | $this->pour_recruter = unserialize($obj->pour_recruter); |
||
| 295 | $this->temps_recrutement = round($obj->temps_recrutement-($obj->temps_recrutement*Bataille::getBatiment()->getNiveauBatiment("caserne")/100)); |
||
| 296 | } |
||
| 297 | } |
||
| 298 | } |
||
| 299 | //-------------------------- END GETTER ----------------------------------------------------------------------------// |
||
| 300 | |||
| 301 | |||
| 302 | //-------------------------- SETTER ----------------------------------------------------------------------------// |
||
| 303 | /** |
||
| 304 | * @param $nom -> nom de l'unité à recruter |
||
| 305 | * @param $type -> type de l'unité à recruter |
||
| 306 | * @param $nombre -> nombre d'unité à recruter |
||
| 307 | * fonction qui permet d'initialiser le début du recrutement d'unités |
||
| 308 | */ |
||
| 309 | public function setCommencerRecruter($nom, $type, $nombre) { |
||
| 347 | |||
| 348 | /** |
||
| 349 | * @param $id_recrutement |
||
| 350 | * fonction appellée dans celle qui récupère les recrutement uniquement quand celui ci est finit |
||
| 351 | * fonction qui sert à terminer un rcrutement et ajouter les unités dans la base |
||
| 352 | */ |
||
| 353 | private function setTerminerRecrutement($id_recrutement) { |
||
| 376 | |||
| 377 | /** |
||
| 378 | * @param $nombre_unite |
||
| 379 | * @param $nom_unite |
||
| 380 | * @param $type_unite |
||
| 381 | * @param $id_mission |
||
| 382 | * @return bool |
||
| 383 | * permet de lancer des unites en expédition en ajoutant à chaque unité un id_mission |
||
| 384 | */ |
||
| 385 | public function setCommencerExpedition($nombre_unite, $nom_unite, $type_unite, $id_mission) { |
||
| 386 | $dbc = App::getDb(); |
||
| 387 | |||
| 388 | $nombre_unite_base = $this->getNombreUniteNom($type_unite, $nom_unite); |
||
| 389 | |||
| 390 | if ($nombre_unite > $nombre_unite_base) { |
||
| 391 | FlashMessage::setFlash("Pas assez d'unités ".$nom_unite." disponibles dans la base pour partir en mission"); |
||
| 392 | return false; |
||
| 393 | } |
||
| 394 | |||
| 395 | $dbc->update("ID_mission", $id_mission) |
||
| 396 | ->from("_bataille_unite") |
||
| 397 | ->where("type", "=", $type_unite, "AND") |
||
| 398 | ->where("nom", "=", $nom_unite, "AND") |
||
| 399 | ->where("ID_base", "=", Bataille::getIdBase(), "AND") |
||
| 400 | ->where("(ID_groupe IS NULL OR ID_groupe = 0)", "", "", "AND", true) |
||
| 401 | ->where("(ID_mission IS NULL OR ID_mission = 0)", "", "", "", true) |
||
| 402 | ->limit($nombre_unite, "no") |
||
| 403 | ->set(); |
||
| 404 | |||
| 405 | return true; |
||
| 406 | } |
||
| 407 | |||
| 408 | /** |
||
| 409 | * @param $id_mission |
||
| 410 | * @param $pourcentage_perte |
||
| 411 | * @return int |
||
| 412 | * fonction qui termine une expdedition au niveau des troupes, cette fonction s'occupe d'en |
||
| 413 | * supprimer de la bdd en fonction du nombre de troupe envoyé et du cpourcentage de perte |
||
| 414 | */ |
||
| 415 | public function setTerminerExpedition($id_mission, $pourcentage_perte) { |
||
| 448 | |||
| 449 | /** |
||
| 450 | * @param $nombre |
||
| 451 | * fonction qui permet de tuer des unites |
||
| 452 | */ |
||
| 453 | public function setTuerUnites($nombre) { |
||
| 466 | //-------------------------- END SETTER ----------------------------------------------------------------------------// |
||
| 467 | } |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: