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 DBStaticUser 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 DBStaticUser, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class DBStaticUser { |
||
13 | |||
14 | /** |
||
15 | * @param mixed $user |
||
16 | */ |
||
17 | // TODO - remove! |
||
18 | public static function validateUserRecord($user) { |
||
33 | |||
34 | /** |
||
35 | * @param array $playerArray |
||
36 | * |
||
37 | * @return string |
||
38 | */ |
||
39 | // TODO - remove or use something else |
||
40 | public static function renderNameAndCoordinates($playerArray) { |
||
43 | |||
44 | /** |
||
45 | * @return DbResultIterator |
||
46 | */ |
||
47 | protected static function playerSelectIterator($fields, $orderBy = '', $forUpdate = false, $groupHaving = '', $where = '', $limit = '') { |
||
73 | |||
74 | /** |
||
75 | * @return DbResultIterator |
||
76 | */ |
||
77 | public static function db_player_list_export_blitz_info() { |
||
80 | |||
81 | /** |
||
82 | * @return DbResultIterator |
||
83 | */ |
||
84 | public static function db_user_list_non_bots() { |
||
87 | |||
88 | /** |
||
89 | * @return DbResultIterator |
||
90 | */ |
||
91 | public static function db_user_list_admin_multiaccounts() { |
||
101 | |||
102 | // TODO - это вообще-то надо хранить в конфигурации |
||
103 | /** |
||
104 | * @return string |
||
105 | */ |
||
106 | public static function getLastRegisteredUserName() { |
||
111 | |||
112 | /** |
||
113 | * @param bool $online |
||
114 | * |
||
115 | * @return int |
||
116 | */ |
||
117 | public static function db_user_count($online = false) { |
||
122 | |||
123 | public static function db_user_list_admin_sorted($sort, $online = false) { |
||
138 | |||
139 | public static function db_user_list_to_celebrate($config_user_birthday_range) { |
||
159 | |||
160 | |||
161 | public static function lockAllRecords() { |
||
164 | |||
165 | public static function db_user_lock_with_target_owner_and_acs($user, $planet = array()) { |
||
175 | |||
176 | |||
177 | public static function db_player_list_blitz_delete_players() { |
||
186 | |||
187 | // TODO - NEVER change DM amount directly w/o logging! |
||
188 | public static function db_player_list_blitz_set_50k_dm() { |
||
198 | |||
199 | /** |
||
200 | * Выбирает записи игроков по списку их ID |
||
201 | * |
||
202 | * @param $user_id_list |
||
203 | * |
||
204 | * @return array |
||
205 | */ |
||
206 | public static function db_user_list_by_id($user_id_list) { |
||
217 | |||
218 | public static function db_user_by_username($username_unsafe, $for_update = false, $fields = '*', $player = null, $like = false) { |
||
254 | |||
255 | public static function db_user_list($user_filter = '', $for_update = false, $fields = '*') { |
||
258 | |||
259 | /** |
||
260 | * @param $user_id |
||
261 | * @param array $set |
||
262 | * |
||
263 | * @return array|bool|mysqli_result|null |
||
264 | */ |
||
265 | public static function db_user_set_by_id($user_id, $set) { |
||
268 | |||
269 | /** |
||
270 | * @param $user_id |
||
271 | * @param array $set |
||
272 | * @param array $adjust |
||
273 | * |
||
274 | * @return array|bool|mysqli_result|null |
||
275 | */ |
||
276 | public static function db_user_adjust_by_id($user_id, $adjust) { |
||
279 | |||
280 | /** |
||
281 | * Возвращает информацию о пользователе по его ID |
||
282 | * |
||
283 | * @param int|array $user_id_unsafe |
||
284 | * <p>int - ID пользователя</p> |
||
285 | * <p>array - запись пользователя с установленным полем ['id']</p> |
||
286 | * @param bool $for_update @deprecated |
||
287 | * @param string $fields @deprecated список полей или '*'/'' для всех полей |
||
288 | * @param null $player |
||
289 | * @param bool|null $player Признак выбора записи пользователь типа "игрок" |
||
290 | * <p>null - Можно выбрать запись любого типа</p> |
||
291 | * <p>true - Выбирается только запись типа "игрок"</p> |
||
292 | * <p>false - Выбирается только запись типа "альянс"</p> |
||
293 | * |
||
294 | * @return array|false |
||
295 | * <p>false - Нет записи с указанным ID и $player</p> |
||
296 | * <p>array - запись типа $user</p> |
||
297 | */ |
||
298 | public static function db_user_by_id($user_id_unsafe, $for_update = false, $fields = '*', $player = null) { |
||
310 | |||
311 | /** |
||
312 | * @param $ally_id |
||
313 | * @param $ally_rank_id |
||
314 | * @param array $set |
||
315 | * @param array $adjust |
||
316 | */ |
||
317 | public static function db_user_list_set_by_ally_and_rank($ally_id, $ally_rank_id, $set, $adjust) { |
||
331 | |||
332 | /** |
||
333 | * @param array $playerRowFieldChanges - array of $resourceId => $amount |
||
334 | * @param int $userId |
||
335 | * |
||
336 | * // TODO - DEDUPLICATE |
||
337 | * |
||
338 | * @see DBStaticPlanet::db_planet_update_resources |
||
339 | */ |
||
340 | View Code Duplication | public static function db_user_update_resources($playerRowFieldChanges, $userId) { |
|
356 | |||
357 | } |
||
358 |
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.