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 BaseEventEmitterTrait 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 BaseEventEmitterTrait, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
5 | trait BaseEventEmitterTrait |
||
6 | { |
||
7 | /** |
||
8 | * @var int |
||
9 | */ |
||
10 | protected $emitterBlocked = EventEmitter::EVENTS_FORWARD; |
||
11 | |||
12 | /** |
||
13 | * @var int[] |
||
14 | */ |
||
15 | protected $eventPointers = []; |
||
16 | |||
17 | /** |
||
18 | * @var EventListener[][] |
||
19 | */ |
||
20 | protected $eventListeners = []; |
||
21 | |||
22 | /** |
||
23 | * @var EventEmitterInterface[] |
||
24 | */ |
||
25 | protected $forwardListeners = []; |
||
26 | |||
27 | /** |
||
28 | * |
||
29 | */ |
||
30 | 39 | public function __construct() |
|
32 | |||
33 | /** |
||
34 | * |
||
35 | */ |
||
36 | 5 | public function __destruct() |
|
43 | |||
44 | /** |
||
45 | * @see EventEmitterInterface::setMode |
||
46 | */ |
||
47 | 20 | public function setMode($emitterMode) |
|
51 | |||
52 | /** |
||
53 | * @see EventEmitterInterface::getMode |
||
54 | */ |
||
55 | 4 | public function getMode() |
|
59 | |||
60 | /** |
||
61 | * @see EventEmitterInterface::on |
||
62 | */ |
||
63 | 66 | View Code Duplication | public function on($event, callable $listener) |
78 | |||
79 | /** |
||
80 | * @see EventEmitterInterface::once |
||
81 | */ |
||
82 | 12 | View Code Duplication | public function once($event, callable $listener) |
97 | |||
98 | /** |
||
99 | * @see EventEmitterInterface::times |
||
100 | */ |
||
101 | 28 | public function times($event, $limit, callable $listener) |
|
127 | |||
128 | /** |
||
129 | * @see EventEmitterInterface::delay |
||
130 | */ |
||
131 | 8 | public function delay($event, $ticks, callable $listener) |
|
141 | |||
142 | /** |
||
143 | * @see EventEmitterInterface::delayOnce |
||
144 | */ |
||
145 | 8 | View Code Duplication | public function delayOnce($event, $ticks, callable $listener) |
155 | |||
156 | /** |
||
157 | * @see EventEmitterInterface::delayTimes |
||
158 | */ |
||
159 | 8 | View Code Duplication | public function delayTimes($event, $ticks, $limit, callable $listener) |
169 | |||
170 | /** |
||
171 | * @see EventEmitterInterface::removeListener |
||
172 | */ |
||
173 | 16 | public function removeListener($event, callable $listener) |
|
183 | |||
184 | /** |
||
185 | * @see EventEmitterInterface::removeListeners |
||
186 | */ |
||
187 | 8 | public function removeListeners($event) |
|
192 | |||
193 | /** |
||
194 | * @see EventEmitterInterface::flushListeners |
||
195 | */ |
||
196 | 4 | public function flushListeners() |
|
204 | |||
205 | /** |
||
206 | * @see EventEmitterInterface::findListener |
||
207 | */ |
||
208 | 16 | public function findListener($event, callable $listener) |
|
222 | |||
223 | /** |
||
224 | * @see EventEmitterInterface::emit |
||
225 | */ |
||
226 | 106 | public function emit($event, $arguments = []) |
|
247 | |||
248 | /** |
||
249 | * @see EventEmitterInterface::copyEvent |
||
250 | */ |
||
251 | 8 | public function copyEvent(EventEmitterInterface $emitter, $event) |
|
257 | |||
258 | /** |
||
259 | * @see EventEmitterInterface::copyEvents |
||
260 | */ |
||
261 | 4 | public function copyEvents(EventEmitterInterface $emitter, $events) |
|
273 | |||
274 | /** |
||
275 | * @see EventEmitterInterface::forwardEvents |
||
276 | */ |
||
277 | 24 | public function forwardEvents(EventEmitterInterface $emitter) |
|
283 | |||
284 | /** |
||
285 | * @see EventEmitterInterface::discardEvents |
||
286 | */ |
||
287 | 8 | public function discardEvents(EventEmitterInterface $emitter) |
|
299 | |||
300 | /** |
||
301 | * @param int $pointer |
||
302 | * @param string $event |
||
303 | * @param callable $listener |
||
304 | * @return callable |
||
305 | */ |
||
306 | 50 | protected function attachOnListener($pointer, $event, callable $listener) |
|
310 | |||
311 | /** |
||
312 | * @param int $pointer |
||
313 | * @param string $event |
||
314 | * @param callable $listener |
||
315 | * @return callable |
||
316 | */ |
||
317 | 6 | protected function attachOnceListener($pointer, $event, callable $listener) |
|
326 | |||
327 | /** |
||
328 | * @param int $pointer |
||
329 | * @param string $event |
||
330 | * @param int $limit |
||
331 | * @param callable $listener |
||
332 | * @return callable |
||
333 | */ |
||
334 | 14 | protected function attachTimesListener($pointer, $event, $limit, callable $listener) |
|
346 | |||
347 | /** |
||
348 | * Destruct method. |
||
349 | */ |
||
350 | private function destructEventEmitterTrait() |
||
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.