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 | |||
13 | |||
14 | |||
15 | //-------------------------- BUILDER ----------------------------------------------------------------------------// |
||
16 | View Code Duplication | public function __construct() { |
|
25 | //-------------------------- END BUILDER ----------------------------------------------------------------------------// |
||
26 | |||
27 | |||
28 | //-------------------------- GETTER ----------------------------------------------------------------------------// |
||
29 | |||
30 | /** |
||
31 | * @param $unite |
||
32 | * @param $niveau |
||
33 | * @param $type |
||
34 | * @return array |
||
35 | * récupère les caractéristiques de l'unité en fonction de son niveau |
||
36 | */ |
||
37 | public function getCaracteristiqueUnite($unite, $niveau, $type) { |
||
77 | |||
78 | /** |
||
79 | * @return array |
||
80 | * fonction qui renvoit tous les types d'unités qu'il est possible de recruter |
||
81 | */ |
||
82 | View Code Duplication | private function getAllType() { |
|
91 | |||
92 | /** |
||
93 | * @param $type |
||
94 | * fonction qui permet de récupérer les unités qu'i est possible de recruter en fonction |
||
95 | * du type (batiment sur lequel on a cliqué) |
||
96 | */ |
||
97 | public function getUnitePossibleRecruter($type) { |
||
98 | //on recup toutes les unites deja recherchée donc que l'on peut faire |
||
99 | $unites = Bataille::getCentreRecherche()->getAllRechercheType($type); |
||
100 | |||
101 | //recupérer les caractéristiques de l'unité en question |
||
102 | for ($i=0 ; $i<count($unites) ; $i++) { |
||
103 | $unites[$i] += $this->getCaracteristiqueUnite($unites[$i]["recherche"], $unites[$i]["niveau"], $type); |
||
104 | $unites[$i] += ["type" => $type]; |
||
105 | } |
||
106 | |||
107 | Bataille::setValues(["unites" => $unites]); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * fonction qui renvoi les unité en cours de recrutement |
||
112 | */ |
||
113 | public function getRecrutement() { |
||
139 | |||
140 | /** |
||
141 | * @param null $id_base |
||
142 | * fonction qui récupère toutes les unités qui sont dans la base |
||
143 | */ |
||
144 | public function getAllUnites($id_base = null) { |
||
145 | |||
146 | if ($id_base == null) $id_base = Bataille::getIdBase(); |
||
147 | |||
148 | $types = $this->getAllType(); |
||
149 | $count_type = count($types); |
||
150 | $unites = []; |
||
151 | |||
152 | for ($i=0 ; $i<$count_type ; $i++) { |
||
153 | $type_unite = $this->getAllUniteType($types[$i], $id_base); |
||
154 | |||
155 | $unites = array_merge($unites, $type_unite); |
||
156 | } |
||
157 | |||
158 | Bataille::setValues(["unites" => $unites]); |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * @param $type |
||
163 | * @param $id_base |
||
164 | * @return mixed |
||
165 | * fonction qui récupère toutes les unités en fonction d'un type précis |
||
166 | */ |
||
167 | private function getAllUniteType($type, $id_base) { |
||
168 | $dbc = App::getDb(); |
||
169 | |||
170 | $query = $dbc->select("nom")->from("_bataille_unite") |
||
171 | ->where("type", "=", $type, "AND") |
||
172 | ->where("ID_base", "=", $id_base, "AND") |
||
173 | ->where("(ID_groupe IS NULL OR ID_groupe = 0)", "", "", "AND", true) |
||
174 | ->where("(ID_mission IS NULL OR ID_mission = 0)", "", "", "", true) |
||
175 | ->orderBy("nom") |
||
176 | ->get(); |
||
177 | |||
178 | if ((is_array($query)) && (count($query) > 0)) { |
||
179 | $count = 1; |
||
180 | $nom = ""; |
||
181 | foreach ($query as $obj) { |
||
182 | if ($nom != $obj->nom) { |
||
183 | $count = 1; |
||
184 | } |
||
185 | $unite[] = $unites[$type][$obj->nom] = [ |
||
186 | "nom" => $obj->nom, |
||
187 | "nombre" => $count++ |
||
188 | ]; |
||
189 | $nom = $obj->nom; |
||
190 | } |
||
191 | |||
192 | return $unites; |
||
193 | } |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * @param $type |
||
198 | * @param $nom |
||
199 | * @return int |
||
200 | * renvoi le nombre d'unite en fonction d'un type et d'un nom qui ne sont ni dans un groupe ni |
||
201 | * en mission |
||
202 | */ |
||
203 | private function getNombreUniteNom($type, $nom) { |
||
204 | $dbc = App::getDb(); |
||
205 | |||
206 | $query = $dbc->select("nom")->from("_bataille_unite") |
||
207 | ->where("type", "=", $type, "AND") |
||
208 | ->where("nom", "=", $nom, "AND") |
||
209 | ->where("ID_base", "=", Bataille::getIdBase(), "AND") |
||
210 | ->where("(ID_groupe IS NULL OR ID_groupe = 0)", "", "", "AND", true) |
||
211 | ->where("(ID_mission IS NULL OR ID_mission = 0)", "", "", "", true) |
||
212 | ->orderBy("nom") |
||
213 | ->get(); |
||
214 | |||
215 | return count($query); |
||
216 | } |
||
217 | //-------------------------- END GETTER ----------------------------------------------------------------------------// |
||
218 | |||
219 | |||
220 | //-------------------------- SETTER ----------------------------------------------------------------------------// |
||
221 | /** |
||
222 | * @param $nom -> nom de l'unité à recruter |
||
223 | * @param $type -> type de l'unité à recruter |
||
224 | * @param $nombre -> nombre d'unité à recruter |
||
225 | * fonction qui permet d'initialiser le début du recrutement d'unités |
||
226 | */ |
||
227 | public function setCommencerRecruter($nom, $type, $nombre) { |
||
278 | |||
279 | /** |
||
280 | * @param $id_recrutement |
||
281 | * fonction appellée dans celle qui récupère les recrutement uniquement quand celui ci est finit |
||
282 | * fonction qui sert à terminer un rcrutement et ajouter les unités dans la base |
||
283 | */ |
||
284 | private function setTerminerRecrutement($id_recrutement) { |
||
307 | |||
308 | /** |
||
309 | * @param $nombre_unite |
||
310 | * @param $nom_unite |
||
311 | * @param $type_unite |
||
312 | * @param $id_mission |
||
313 | * @return bool |
||
314 | * permet de lancer des unites en expédition en ajoutant à chaque unité un id_mission |
||
315 | */ |
||
316 | public function setCommencerExpedition($nombre_unite, $nom_unite, $type_unite, $id_mission) { |
||
336 | |||
337 | /** |
||
338 | * @param $id_mission |
||
339 | * @param $pourcentage_perte |
||
340 | * fonction qui termine une expdedition au niveau des troupes, cette fonction s'occupe d'en |
||
341 | * supprimer de la bdd en fonction du nombre de troupe envoyé et du cpourcentage de perte |
||
342 | */ |
||
343 | public function setTerminerExpedition($id_mission, $pourcentage_perte) { |
||
373 | //-------------------------- END SETTER ----------------------------------------------------------------------------// |
||
374 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.