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 EntryIdResolver 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 EntryIdResolver, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class EntryIdResolver extends AbstractListenerAggregate |
||
24 | { |
||
25 | /** |
||
26 | * Имя параметра в конфиги модуля, по которому можно получить имя менеджера wf |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | const WORKFLOW_MANAGER_NAME = 'workflowManagerName'; |
||
31 | |||
32 | /** |
||
33 | * Имя параметра в конфиги модуля, по которому можно получить имя псевдонима менеджера wf |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | const WORKFLOW_MANAGER_ALIAS = 'workflowManagerAlias'; |
||
38 | |||
39 | /** |
||
40 | * Имя параметра в конфиге модуля, по которому можно получить имя wf |
||
41 | * |
||
42 | * @var string |
||
43 | */ |
||
44 | const WORKFLOW_NAME = 'workflowName'; |
||
45 | |||
46 | /** |
||
47 | * Имя параметра в конфиге модуля, по которому можно получить значение имени роутера |
||
48 | * |
||
49 | * @var string |
||
50 | */ |
||
51 | const ROUTER_NAME = 'routeName'; |
||
52 | |||
53 | /** |
||
54 | * Имя параметра в конфиге модуля, по которому можно конфиг описывающий какие классы и какие имена параметров |
||
55 | * роуетера используется, для получения entryId |
||
56 | * |
||
57 | * @var string |
||
58 | */ |
||
59 | const MAP = 'map'; |
||
60 | |||
61 | /** |
||
62 | * Имя параметра в карте(@see const MAP), по которому можно получить класс сущности |
||
63 | * |
||
64 | * @var string |
||
65 | */ |
||
66 | const ENTITY_CLASS_NAME = 'entityClassName'; |
||
67 | |||
68 | /** |
||
69 | * Имя параметра в карте(@see const MAP), по которому можно получить конфиг описывающий как для заданного свойства |
||
70 | * сущности(свойство является либо первичным ключем, либо составной частью первичного ключа) получиить из |
||
71 | * урл значение. |
||
72 | * |
||
73 | * |
||
74 | * @var string |
||
75 | */ |
||
76 | const IDENTIFIERS_MAP = 'identifiersMap'; |
||
77 | |||
78 | /** |
||
79 | * Имя параметра в карте(@see const IDENTIFIERS_MAP), по которому можно получить имя свойства сущности, которое |
||
80 | * является первичным ключем (или частью первичного ключа) |
||
81 | * |
||
82 | * |
||
83 | * @var string |
||
84 | */ |
||
85 | const PROPERTY_NAME = 'propertyName'; |
||
86 | |||
87 | /** |
||
88 | * Имя параметра в карте(@see const IDENTIFIERS_MAP), по которому можно определить как получить значение свойства, |
||
89 | * из параметра роутера, или из query |
||
90 | * |
||
91 | * @var string |
||
92 | */ |
||
93 | const MODE = 'mode'; |
||
94 | |||
95 | /** |
||
96 | * Значение для параметра mode (@see const MODE), определяет что значение берется из параметров роутера |
||
97 | * |
||
98 | * @var string |
||
99 | */ |
||
100 | const MODE_ROUTER_PARAM = 'param'; |
||
101 | |||
102 | /** |
||
103 | * Значение для параметра mode (@see const MODE), определяет что значение берется из query части url |
||
104 | * |
||
105 | * @var string |
||
106 | */ |
||
107 | const MODE_QUERY = 'query'; |
||
108 | |||
109 | /** |
||
110 | * Имя параметра в карте(@see const IDENTIFIERS_MAP), определяет имя параметра роутера или query параметра |
||
111 | * содержащие значение для propertyName (@see const PROPERTY_NAME) |
||
112 | * |
||
113 | * @var string |
||
114 | */ |
||
115 | const PARAM_NAME = 'paramName'; |
||
116 | |||
117 | /** |
||
118 | * Набор допустимых значений для mode (@see const MODE) |
||
119 | * |
||
120 | * @var array |
||
121 | */ |
||
122 | protected $accessMode = [ |
||
123 | self::MODE_ROUTER_PARAM => self::MODE_ROUTER_PARAM, |
||
124 | self::MODE_ROUTER_PARAM => self::MODE_ROUTER_PARAM, |
||
125 | ]; |
||
126 | |||
127 | /** |
||
128 | * Сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
||
129 | * |
||
130 | * @var EntryToObjectsService |
||
131 | */ |
||
132 | protected $entryToObjectsService; |
||
133 | |||
134 | /** |
||
135 | * Настройки модуля |
||
136 | * |
||
137 | * @var ModuleOptions |
||
138 | */ |
||
139 | protected $moduleOptions; |
||
140 | |||
141 | /** |
||
142 | * Индекс для маппинга |
||
143 | * |
||
144 | * @var null|array |
||
145 | */ |
||
146 | protected $indexMetadata; |
||
147 | |||
148 | /** |
||
149 | * @var MvcEvent |
||
150 | */ |
||
151 | protected $mvcEvent; |
||
152 | |||
153 | /** |
||
154 | * Логер |
||
155 | * |
||
156 | * @var LoggerInterface |
||
157 | */ |
||
158 | protected $log; |
||
159 | |||
160 | /** |
||
161 | * EntryIdResolver constructor. |
||
162 | * |
||
163 | * @param array $options |
||
164 | */ |
||
165 | public function __construct(array $options = []) |
||
175 | |||
176 | /** |
||
177 | * @param EntryToObjectsService $entryToObjectsService |
||
178 | * @param ModuleOptions $moduleOptions |
||
179 | * @param MvcEvent $mvcEvent |
||
180 | * @param LoggerInterface $log |
||
181 | */ |
||
182 | protected function init( |
||
193 | |||
194 | /** |
||
195 | * @param EventManagerInterface $events |
||
196 | */ |
||
197 | public function attach(EventManagerInterface $events) |
||
201 | |||
202 | /** |
||
203 | * Обработчик содержащий логику получения entryId |
||
204 | * |
||
205 | * @param ResolveEntryIdEventInterface $resolveEntryIdEvent |
||
206 | * |
||
207 | * |
||
208 | * @return null|string |
||
209 | * |
||
210 | * @throws \OldTown\Workflow\ZF2\Toolkit\EntryToObjects\Exception\InvalidGetEntryByObjectsInfoException |
||
211 | * @throws \OldTown\Workflow\ZF2\Toolkit\WorkflowRunParams\Exception\InvalidWorkflowEntryToObjectMetadataException |
||
212 | * @throws \Zend\Serializer\Exception\ExceptionInterface |
||
213 | */ |
||
214 | public function onResolveEntryId(ResolveEntryIdEventInterface $resolveEntryIdEvent) |
||
282 | |||
283 | /** |
||
284 | * Подготавливает набор ключей для поиска в индексе |
||
285 | * |
||
286 | * @param string $routerName |
||
287 | * @param string $workflowName |
||
288 | * @param null $managerName |
||
289 | * @param null $managerAlias |
||
290 | * |
||
291 | * @return array |
||
292 | */ |
||
293 | public function buildIndexKeys($routerName, $workflowName, $managerName = null, $managerAlias = null) |
||
321 | |||
322 | /** |
||
323 | * @return array|null |
||
324 | * |
||
325 | * @throws Exception\InvalidWorkflowEntryToObjectMetadataException |
||
326 | */ |
||
327 | public function getIndexMetadata() |
||
455 | |||
456 | /** |
||
457 | * @param array|null $indexMetadata |
||
458 | * |
||
459 | * @return $this |
||
460 | */ |
||
461 | public function setIndexMetadata(array $indexMetadata = null) |
||
467 | |||
468 | |||
469 | /** |
||
470 | * Сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
||
471 | * |
||
472 | * @return EntryToObjectsService |
||
473 | */ |
||
474 | public function getEntryToObjectsService() |
||
478 | |||
479 | /** |
||
480 | * Устанавливает сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
||
481 | * |
||
482 | * @param EntryToObjectsService $entryToObjectsService |
||
483 | * |
||
484 | * @return $this |
||
485 | */ |
||
486 | public function setEntryToObjectsService(EntryToObjectsService $entryToObjectsService) |
||
492 | |||
493 | /** |
||
494 | * Настройки модуля |
||
495 | * |
||
496 | * @return ModuleOptions |
||
497 | */ |
||
498 | public function getModuleOptions() |
||
502 | |||
503 | /** |
||
504 | * Устанавливает настройки модуля |
||
505 | * |
||
506 | * @param ModuleOptions $moduleOptions |
||
507 | * |
||
508 | * @return $this |
||
509 | */ |
||
510 | public function setModuleOptions(ModuleOptions $moduleOptions) |
||
516 | |||
517 | /** |
||
518 | * @return MvcEvent |
||
519 | */ |
||
520 | public function getMvcEvent() |
||
524 | |||
525 | /** |
||
526 | * @param MvcEvent $mvcEvent |
||
527 | * |
||
528 | * @return $this |
||
529 | */ |
||
530 | public function setMvcEvent(MvcEvent $mvcEvent) |
||
536 | |||
537 | |||
538 | /** |
||
539 | * Устанавливает логер |
||
540 | * |
||
541 | * @return LoggerInterface |
||
542 | */ |
||
543 | public function getLog() |
||
547 | |||
548 | /** |
||
549 | * Возвращает логер |
||
550 | * |
||
551 | * @param LoggerInterface $log |
||
552 | * |
||
553 | * @return $this |
||
554 | */ |
||
555 | public function setLog(LoggerInterface $log) |
||
561 | } |
||
562 |
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.