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 GroupsBackendService 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 GroupsBackendService, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
48 | class GroupsBackendService { |
||
49 | |||
50 | /** @var string */ |
||
51 | protected $userId; |
||
52 | |||
53 | /** @var Circle */ |
||
54 | protected $circle; |
||
55 | |||
56 | /** @var Member */ |
||
57 | protected $member; |
||
58 | |||
59 | /** @var IGroup */ |
||
60 | protected $group; |
||
61 | |||
62 | /** @var IUser */ |
||
63 | protected $user; |
||
64 | |||
65 | /** @var ConfigService */ |
||
66 | protected $configService; |
||
67 | |||
68 | /** @var MiscService */ |
||
69 | protected $miscService; |
||
70 | |||
71 | /** @var CirclesRequest */ |
||
72 | protected $circlesRequest; |
||
73 | |||
74 | /** @var MembersRequest */ |
||
75 | protected $membersRequest; |
||
76 | |||
77 | /** @var IGroupManager */ |
||
78 | protected $groupManager; |
||
79 | |||
80 | /** @var IUserManager */ |
||
81 | protected $userManager; |
||
82 | |||
83 | /** |
||
84 | * GroupsBackendService constructor. |
||
85 | * |
||
86 | * @param string $userId |
||
87 | * @param CirclesRequest $circlesRequest |
||
88 | * @param MembersRequest $membersRequest |
||
89 | * @param IGroupManager $groupManager |
||
90 | * @param IUserManager $userManager |
||
91 | * @param ConfigService $configService |
||
92 | * @param MiscService $miscService |
||
93 | */ |
||
94 | public function __construct( |
||
111 | |||
112 | /** |
||
113 | * @param ManagerEvent $event |
||
114 | */ |
||
115 | public function onAppEnabled(ManagerEvent $event) { |
||
120 | |||
121 | /** |
||
122 | * @param GenericEvent $event |
||
123 | */ |
||
124 | public function onCircleCreation(GenericEvent $event) { |
||
162 | |||
163 | /** |
||
164 | * @param GenericEvent $event |
||
165 | */ |
||
166 | public function onCircleDestruction(GenericEvent $event) { |
||
177 | |||
178 | /** |
||
179 | * @param GenericEvent $event |
||
180 | */ |
||
181 | View Code Duplication | public function onMemberNew(GenericEvent $event) { |
|
197 | |||
198 | /** |
||
199 | * @param GenericEvent $event |
||
200 | */ |
||
201 | public function onMemberInvited(GenericEvent $event) { |
||
204 | |||
205 | /** |
||
206 | * @param GenericEvent $event |
||
207 | */ |
||
208 | public function onMemberRequesting(GenericEvent $event) { |
||
211 | |||
212 | /** |
||
213 | * @param GenericEvent $event |
||
214 | */ |
||
215 | View Code Duplication | public function onMemberLeaving(GenericEvent $event) { |
|
231 | |||
232 | /** |
||
233 | * @param GenericEvent $event |
||
234 | */ |
||
235 | public function onMemberLevel(GenericEvent $event) { |
||
238 | |||
239 | /** |
||
240 | * @param GenericEvent $event |
||
241 | */ |
||
242 | public function onMemberOwner(GenericEvent $event) { |
||
245 | |||
246 | /** |
||
247 | * @param GenericEvent $event |
||
248 | */ |
||
249 | public function onGroupLink(GenericEvent $event) { |
||
252 | |||
253 | /** |
||
254 | * @param GenericEvent $event |
||
255 | */ |
||
256 | public function onGroupUnlink(GenericEvent $event) { |
||
259 | |||
260 | /** |
||
261 | * @param GenericEvent $event |
||
262 | */ |
||
263 | public function onGroupLevel(GenericEvent $event) { |
||
266 | |||
267 | /** |
||
268 | * @param GenericEvent $event |
||
269 | */ |
||
270 | public function onLinkRequestSent(GenericEvent $event) { |
||
273 | |||
274 | /** |
||
275 | * @param GenericEvent $event |
||
276 | */ |
||
277 | public function onLinkRequestReceived(GenericEvent $event) { |
||
280 | |||
281 | /** |
||
282 | * @param GenericEvent $event |
||
283 | */ |
||
284 | public function onLinkRequestRejected(GenericEvent $event) { |
||
287 | |||
288 | /** |
||
289 | * @param GenericEvent $event |
||
290 | */ |
||
291 | public function onLinkRequestCanceled(GenericEvent $event) { |
||
294 | |||
295 | /** |
||
296 | * @param GenericEvent $event |
||
297 | */ |
||
298 | public function onLinkRequestAccepted(GenericEvent $event) { |
||
301 | |||
302 | /** |
||
303 | * @param GenericEvent $event |
||
304 | */ |
||
305 | public function onLinkRequestAccepting(GenericEvent $event) { |
||
308 | |||
309 | /** |
||
310 | * @param GenericEvent $event |
||
311 | */ |
||
312 | public function onLinkUp(GenericEvent $event) { |
||
315 | |||
316 | /** |
||
317 | * @param GenericEvent $event |
||
318 | */ |
||
319 | public function onLinkDown(GenericEvent $event) { |
||
322 | |||
323 | /** |
||
324 | * @param GenericEvent $event |
||
325 | */ |
||
326 | public function onLinkRemove(GenericEvent $event) { |
||
329 | |||
330 | /** |
||
331 | * @param GenericEvent $event |
||
332 | */ |
||
333 | public function onSettingsChange(GenericEvent $event) { |
||
345 | |||
346 | /** |
||
347 | * When a group add a user, add it as a member of the associate Circle |
||
348 | * |
||
349 | * @param SymfonyGenericEvent $event |
||
350 | */ |
||
351 | public function onGroupPostAddUser(SymfonyGenericEvent $event) { |
||
367 | |||
368 | /** |
||
369 | * When a group remove a user, remove it as a member of the associate Circle |
||
370 | * |
||
371 | * @param SymfonyGenericEvent $event |
||
372 | */ |
||
373 | public function onGroupPostRemoveUser(SymfonyGenericEvent $event) { |
||
398 | |||
399 | /** |
||
400 | * When a group is removed, remove its associated Circle, if any |
||
401 | * |
||
402 | * @param SymfonyGenericEvent $event |
||
403 | */ |
||
404 | public function onGroupPostDelete(SymfonyGenericEvent $event) { |
||
414 | |||
415 | /** |
||
416 | * @return string|null |
||
417 | */ |
||
418 | protected function getCircleGroupName() |
||
428 | |||
429 | /** |
||
430 | * @param string $displayName |
||
431 | * @return bool |
||
432 | */ |
||
433 | protected function setCircleGroupName($displayName) |
||
442 | } |
||
443 |
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.