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 EntrustUserTrait 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 EntrustUserTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | trait EntrustUserTrait |
||
19 | { |
||
20 | //Big block of caching functionality. |
||
21 | View Code Duplication | public function cachedRoles() |
|
34 | |||
35 | public function save(array $options = []) |
||
42 | |||
43 | public function delete(array $options = []) |
||
50 | |||
51 | public function restore() |
||
58 | |||
59 | /** |
||
60 | * Many-to-Many relations with Role. |
||
61 | * |
||
62 | * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany |
||
63 | */ |
||
64 | public function roles() |
||
71 | |||
72 | /** |
||
73 | * Boot the user model |
||
74 | * Attach event listener to remove the many-to-many records when trying to |
||
75 | * delete Will NOT delete any records if the user model uses soft deletes. |
||
76 | * |
||
77 | * @return void|bool |
||
78 | */ |
||
79 | View Code Duplication | public static function boot() |
|
93 | |||
94 | /** |
||
95 | * Checks if the user has a role by its name. |
||
96 | * |
||
97 | * @param string|array $name Role name or array of role names. |
||
98 | * @param bool $requireAll All roles in the array are required. |
||
99 | * |
||
100 | * @return bool |
||
101 | */ |
||
102 | View Code Duplication | public function hasRole($name, $requireAll = false) |
|
129 | |||
130 | /** |
||
131 | * Check if user has a permission by its name. |
||
132 | * |
||
133 | * @param string|array $permission Permission string or array of |
||
134 | * permissions. |
||
135 | * @param bool $requireAll All permissions in the array are |
||
136 | * required. |
||
137 | * |
||
138 | * @return bool |
||
139 | */ |
||
140 | View Code Duplication | public function can($permission, $requireAll = false) |
|
170 | |||
171 | /** |
||
172 | * Checks role(s) and permission(s). |
||
173 | * |
||
174 | * @param string|array $roles Array of roles or comma separated |
||
175 | * string |
||
176 | * @param string|array $permissions Array of permissions or comma separated |
||
177 | * string. |
||
178 | * @param array $options validate_all (true|false) or |
||
179 | * return_type (boolean|array|both) |
||
180 | * |
||
181 | * @throws \InvalidArgumentException |
||
182 | * @return array|bool |
||
183 | */ |
||
184 | public function ability($roles, $permissions, $options = []) |
||
252 | |||
253 | /** |
||
254 | * Alias to eloquent many-to-many relation's attach() method. |
||
255 | * |
||
256 | * @param mixed $role |
||
257 | */ |
||
258 | View Code Duplication | public function attachRole($role) |
|
270 | |||
271 | /** |
||
272 | * Alias to eloquent many-to-many relation's detach() method. |
||
273 | * |
||
274 | * @param mixed $role |
||
275 | */ |
||
276 | View Code Duplication | public function detachRole($role) |
|
288 | |||
289 | /** |
||
290 | * Attach multiple roles to a user |
||
291 | * |
||
292 | * @param mixed $roles |
||
293 | */ |
||
294 | public function attachRoles($roles) |
||
300 | |||
301 | /** |
||
302 | * Detach multiple roles from a user |
||
303 | * |
||
304 | * @param mixed $roles |
||
305 | */ |
||
306 | public function detachRoles($roles = null) |
||
316 | |||
317 | } |
||
318 |
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.