Complex classes like AbstractWorkflow 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 AbstractWorkflow, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
45 | abstract class AbstractWorkflow implements WorkflowInterface |
||
46 | { |
||
47 | /** |
||
48 | * @var string |
||
49 | */ |
||
50 | const CURRENT_STEPS = 'currentSteps'; |
||
51 | |||
52 | /** |
||
53 | * @var string |
||
54 | */ |
||
55 | const HISTORY_STEPS = 'historySteps'; |
||
56 | |||
57 | /** |
||
58 | * @var WorkflowContextInterface |
||
59 | */ |
||
60 | protected $context; |
||
61 | |||
62 | /** |
||
63 | * @var ConfigurationInterface |
||
64 | */ |
||
65 | protected $configuration; |
||
66 | |||
67 | |||
68 | /** |
||
69 | * @var TypeResolverInterface |
||
70 | */ |
||
71 | protected $typeResolver; |
||
72 | |||
73 | /** |
||
74 | * Логер |
||
75 | * |
||
76 | * @var LoggerInterface |
||
77 | */ |
||
78 | protected $log; |
||
79 | |||
80 | /** |
||
81 | * Резолвер для создания провайдеров отвечающих за исполнение функций, проверку условий, выполнение валидаторов и т.д. |
||
82 | * |
||
83 | * @var string |
||
84 | */ |
||
85 | protected $defaultTypeResolverClass = TypeResolver::class; |
||
86 | |||
87 | /** |
||
88 | * Карта переходов состояния процесса workflow |
||
89 | * |
||
90 | * @var null|array |
||
91 | */ |
||
92 | protected $mapEntryState; |
||
93 | |||
94 | /** |
||
95 | * Менеджер движков |
||
96 | * |
||
97 | * @var EngineManagerInterface |
||
98 | */ |
||
99 | protected $engineManager; |
||
100 | |||
101 | /** |
||
102 | * AbstractWorkflow constructor. |
||
103 | * |
||
104 | * @throws InternalWorkflowException |
||
105 | */ |
||
106 | 19 | public function __construct() |
|
111 | |||
112 | /** |
||
113 | * Устанавливает менеджер движков |
||
114 | * |
||
115 | * @return EngineManagerInterface |
||
116 | */ |
||
117 | 19 | public function getEngineManager() |
|
126 | |||
127 | /** |
||
128 | * Возвращает менеджер движков |
||
129 | * |
||
130 | * @param EngineManagerInterface $engineManager |
||
131 | * |
||
132 | * @return $this |
||
133 | */ |
||
134 | public function setEngineManager(EngineManagerInterface $engineManager) |
||
140 | |||
141 | /** |
||
142 | * Инициация карты переходов состояния процесса workflow |
||
143 | */ |
||
144 | 19 | protected function initMapEntryState() |
|
166 | |||
167 | /** |
||
168 | * Инициализация системы логирования |
||
169 | * |
||
170 | * @throws InternalWorkflowException |
||
171 | */ |
||
172 | 19 | protected function initLoger() |
|
180 | |||
181 | /** |
||
182 | * Инициализация workflow. Workflow нужно иницаилизровать прежде, чем выполнять какие либо действия. |
||
183 | * Workflow может быть инициализированно только один раз |
||
184 | * |
||
185 | * @param string $workflowName Имя workflow |
||
186 | * @param integer $initialAction Имя первого шага, с которого начинается workflow |
||
187 | * @param TransientVarsInterface $inputs Данные введеные пользователем |
||
188 | * |
||
189 | * @return integer |
||
190 | * |
||
191 | * @throws InternalWorkflowException |
||
192 | * @throws InvalidActionException |
||
193 | * @throws InvalidRoleException |
||
194 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
195 | * @throws InvalidArgumentException |
||
196 | * @throws WorkflowException |
||
197 | */ |
||
198 | 19 | public function initialize($workflowName, $initialAction, TransientVarsInterface $inputs = null) |
|
248 | |||
249 | /** |
||
250 | * @param $id |
||
251 | * @param $inputs |
||
252 | * |
||
253 | * @return array |
||
254 | * |
||
255 | */ |
||
256 | 2 | public function getAvailableActions($id, TransientVarsInterface $inputs = null) |
|
324 | |||
325 | /** |
||
326 | * Создает хранилище переменных |
||
327 | * |
||
328 | * @param $class |
||
329 | * |
||
330 | * @return TransientVarsInterface |
||
331 | */ |
||
332 | protected function transientVarsFactory($class = BaseTransientVars::class) |
||
337 | |||
338 | /** |
||
339 | * |
||
340 | * |
||
341 | * Осуществляет переходл в новое состояние, для заданного процесса workflow |
||
342 | * |
||
343 | * @param integer $entryId id запущенного процесса workflow |
||
344 | * @param integer $actionId id действия, доступного та текущем шаеге процессса workflow |
||
345 | * @param TransientVarsInterface $inputs Входные данные для перехода |
||
346 | * |
||
347 | * @return void |
||
348 | * |
||
349 | * @throws WorkflowException |
||
350 | * @throws InvalidActionException |
||
351 | * @throws InvalidArgumentException |
||
352 | * @throws InternalWorkflowException |
||
353 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
354 | */ |
||
355 | 8 | public function doAction($entryId, $actionId, TransientVarsInterface $inputs = null) |
|
415 | |||
416 | /** |
||
417 | * @param WorkflowDescriptor $wf |
||
418 | * @param $actionId |
||
419 | * @param TransientVarsInterface $transientVars |
||
420 | * @param PropertySetInterface $ps |
||
421 | * |
||
422 | * @return ActionDescriptor|null |
||
423 | */ |
||
424 | 8 | protected function getValidGlobalActions(WorkflowDescriptor $wf, $actionId, TransientVarsInterface $transientVars, PropertySetInterface $ps) |
|
436 | |||
437 | |||
438 | /** |
||
439 | * |
||
440 | * @param SplObjectStorage $currentSteps |
||
441 | * @param WorkflowDescriptor $wf |
||
442 | * @param $actionId |
||
443 | * @param TransientVarsInterface $transientVars |
||
444 | * @param PropertySetInterface $ps |
||
445 | * |
||
446 | * @return ActionDescriptor|null |
||
447 | * |
||
448 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
449 | * @throws InternalWorkflowException |
||
450 | */ |
||
451 | 8 | protected function getValidActionsFromCurrentSteps(SplObjectStorage $currentSteps, WorkflowDescriptor $wf, $actionId, TransientVarsInterface $transientVars, PropertySetInterface $ps) |
|
476 | |||
477 | /** |
||
478 | * @param ActionDescriptor $action |
||
479 | * @param $id |
||
480 | * |
||
481 | * @return void |
||
482 | * |
||
483 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
484 | * @throws InvalidArgumentException |
||
485 | * @throws InternalWorkflowException |
||
486 | */ |
||
487 | 8 | protected function checkImplicitFinish(ActionDescriptor $action, $id) |
|
515 | |||
516 | |||
517 | |||
518 | /** |
||
519 | * |
||
520 | * Check if the state of the specified workflow instance can be changed to the new specified one. |
||
521 | * |
||
522 | * @param integer $id The workflow instance id. |
||
523 | * @param integer $newState The new state id. |
||
524 | * |
||
525 | * @return boolean true if the state of the workflow can be modified, false otherwise. |
||
526 | * |
||
527 | * @throws InternalWorkflowException |
||
528 | */ |
||
529 | 16 | public function canModifyEntryState($id, $newState) |
|
538 | |||
539 | |||
540 | /** |
||
541 | * |
||
542 | * Возвращает коллекцию объектов описывающие состояние для текущего экземпляра workflow |
||
543 | * |
||
544 | * @param integer $entryId id экземпляра workflow |
||
545 | * |
||
546 | * @return SplObjectStorage|StepInterface[] |
||
547 | * |
||
548 | * @throws InternalWorkflowException |
||
549 | */ |
||
550 | public function getCurrentSteps($entryId) |
||
554 | |||
555 | /** |
||
556 | * Возвращает информацию о том в какие шаги, были осуществленны переходы, для процесса workflow с заданным id |
||
557 | * |
||
558 | * @param integer $entryId уникальный идентификатор процесса workflow |
||
559 | * |
||
560 | * @return StepInterface[]|SplObjectStorage список шагов |
||
561 | * |
||
562 | * @throws InternalWorkflowException |
||
563 | */ |
||
564 | public function getHistorySteps($entryId) |
||
568 | |||
569 | /** |
||
570 | * Получение шагов информации о шагах процесса workflow |
||
571 | * |
||
572 | * @param $entryId |
||
573 | * @param $type |
||
574 | * |
||
575 | * @return Spi\StepInterface[]|SplObjectStorage |
||
576 | * |
||
577 | * @throws InternalWorkflowException |
||
578 | */ |
||
579 | 19 | protected function getStepFromStorage($entryId, $type) |
|
599 | |||
600 | |||
601 | |||
602 | /** |
||
603 | * |
||
604 | * |
||
605 | * Modify the state of the specified workflow instance. |
||
606 | * @param integer $id The workflow instance id. |
||
607 | * @param integer $newState the new state to change the workflow instance to. |
||
608 | * |
||
609 | * @throws InvalidArgumentException |
||
610 | * @throws InvalidEntryStateException |
||
611 | * @throws InternalWorkflowException |
||
612 | */ |
||
613 | 16 | public function changeEntryState($id, $newState) |
|
651 | |||
652 | |||
653 | |||
654 | |||
655 | |||
656 | /** |
||
657 | * Проверяет имеет ли пользователь достаточно прав, что бы иниициировать вызываемый процесс |
||
658 | * |
||
659 | * @param string $workflowName имя workflow |
||
660 | * @param integer $initialAction id начального состояния |
||
661 | * @param TransientVarsInterface $inputs |
||
662 | * |
||
663 | * @return bool |
||
664 | * |
||
665 | * @throws InvalidArgumentException |
||
666 | * @throws WorkflowException |
||
667 | * @throws InternalWorkflowException |
||
668 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
669 | */ |
||
670 | public function canInitialize($workflowName, $initialAction, TransientVarsInterface $inputs = null) |
||
713 | |||
714 | |||
715 | /** |
||
716 | * Проверяет имеет ли пользователь достаточно прав, что бы иниициировать вызываемый процесс |
||
717 | * |
||
718 | * @param string $workflowName имя workflow |
||
719 | * @param integer $initialAction id начального состояния |
||
720 | * @param TransientVarsInterface $transientVars |
||
721 | * |
||
722 | * @param PropertySetInterface $ps |
||
723 | * |
||
724 | * @return bool |
||
725 | * |
||
726 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
727 | * @throws InvalidActionException |
||
728 | * @throws InternalWorkflowException |
||
729 | * @throws WorkflowException |
||
730 | */ |
||
731 | 19 | protected function canInitializeInternal($workflowName, $initialAction, TransientVarsInterface $transientVars, PropertySetInterface $ps) |
|
758 | |||
759 | /** |
||
760 | * Возвращает резолвер |
||
761 | * |
||
762 | * @return TypeResolverInterface |
||
763 | */ |
||
764 | 19 | public function getResolver() |
|
777 | |||
778 | /** |
||
779 | * Возвращает хранилище состояния workflow |
||
780 | * |
||
781 | * @return WorkflowStoreInterface |
||
782 | * |
||
783 | * @throws InternalWorkflowException |
||
784 | */ |
||
785 | 19 | protected function getPersistence() |
|
789 | |||
790 | /** |
||
791 | * Получить конфигурацию workflow. Метод также проверяет была ли иницилазированн конфигурация, если нет, то |
||
792 | * инициализирует ее. |
||
793 | * |
||
794 | * Если конфигурация не была установленна, то возвращает конфигурацию по умолчанию |
||
795 | * |
||
796 | * @return ConfigurationInterface|DefaultConfiguration Конфигурация которая была установленна |
||
797 | * |
||
798 | * @throws InternalWorkflowException |
||
799 | */ |
||
800 | 19 | public function getConfiguration() |
|
816 | |||
817 | /** |
||
818 | * @return LoggerInterface |
||
819 | */ |
||
820 | 17 | public function getLog() |
|
824 | |||
825 | /** |
||
826 | * @param LoggerInterface $log |
||
827 | * |
||
828 | * @return $this |
||
829 | * |
||
830 | * @throws InternalWorkflowException |
||
831 | */ |
||
832 | public function setLog($log) |
||
846 | |||
847 | |||
848 | /** |
||
849 | * Get the workflow descriptor for the specified workflow name. |
||
850 | * |
||
851 | * @param string $workflowName The workflow name. |
||
852 | * @return WorkflowDescriptor |
||
853 | * |
||
854 | * @throws InternalWorkflowException |
||
855 | */ |
||
856 | public function getWorkflowDescriptor($workflowName) |
||
866 | |||
867 | |||
868 | /** |
||
869 | * Executes a special trigger-function using the context of the given workflow instance id. |
||
870 | * Note that this method is exposed for Quartz trigger jobs, user code should never call it. |
||
871 | * |
||
872 | * @param integer $id The workflow instance id |
||
873 | * @param integer $triggerId The id of the special trigger-function |
||
874 | * |
||
875 | * @throws InvalidArgumentException |
||
876 | * @throws WorkflowException |
||
877 | * @throws InternalWorkflowException |
||
878 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
879 | */ |
||
880 | public function executeTriggerFunction($id, $triggerId) |
||
905 | |||
906 | |||
907 | /** |
||
908 | * @param WorkflowDescriptor $wf |
||
909 | * @param StepInterface $step |
||
910 | * @param TransientVarsInterface $transientVars |
||
911 | * @param PropertySetInterface $ps |
||
912 | * |
||
913 | * @return array |
||
914 | * |
||
915 | * @throws InternalWorkflowException |
||
916 | * @throws WorkflowException |
||
917 | * @throws \OldTown\Workflow\Exception\ArgumentNotNumericException |
||
918 | */ |
||
919 | protected function getAvailableActionsForStep(WorkflowDescriptor $wf, StepInterface $step, TransientVarsInterface $transientVars, PropertySetInterface $ps) |
||
962 | |||
963 | /** |
||
964 | * @param ConfigurationInterface $configuration |
||
965 | * |
||
966 | * @return $this |
||
967 | */ |
||
968 | 19 | public function setConfiguration(ConfigurationInterface $configuration) |
|
974 | |||
975 | /** |
||
976 | * Возвращает состояние для текущего экземпляра workflow |
||
977 | * |
||
978 | * @param integer $id id экземпляра workflow |
||
979 | * @return integer id текущего состояния |
||
980 | * |
||
981 | * @throws InternalWorkflowException |
||
982 | */ |
||
983 | public function getEntryState($id) |
||
999 | |||
1000 | |||
1001 | /** |
||
1002 | * Настройки хранилища |
||
1003 | * |
||
1004 | * @return array |
||
1005 | * |
||
1006 | * @throws InternalWorkflowException |
||
1007 | */ |
||
1008 | public function getPersistenceProperties() |
||
1012 | |||
1013 | |||
1014 | /** |
||
1015 | * Get the PropertySet for the specified workflow instance id. |
||
1016 | * @param integer $id The workflow instance id. |
||
1017 | * |
||
1018 | * @return PropertySetInterface |
||
1019 | * @throws InternalWorkflowException |
||
1020 | */ |
||
1021 | public function getPropertySet($id) |
||
1037 | |||
1038 | /** |
||
1039 | * @return string[] |
||
1040 | * |
||
1041 | * @throws InternalWorkflowException |
||
1042 | */ |
||
1043 | public function getWorkflowNames() |
||
1054 | |||
1055 | /** |
||
1056 | * @param TypeResolverInterface $typeResolver |
||
1057 | * |
||
1058 | * @return $this |
||
1059 | */ |
||
1060 | public function setTypeResolver(TypeResolverInterface $typeResolver) |
||
1066 | |||
1067 | |||
1068 | /** |
||
1069 | * Get a collection (Strings) of currently defined permissions for the specified workflow instance. |
||
1070 | * @param integer $id id the workflow instance id. |
||
1071 | * @param TransientVarsInterface $inputs inputs The inputs to the workflow instance. |
||
1072 | * |
||
1073 | * @return array A List of permissions specified currently (a permission is a string name). |
||
1074 | * |
||
1075 | */ |
||
1076 | public function getSecurityPermissions($id, TransientVarsInterface $inputs = null) |
||
1137 | |||
1138 | |||
1139 | /** |
||
1140 | * Get the name of the specified workflow instance. |
||
1141 | * |
||
1142 | * @param integer $id the workflow instance id. |
||
1143 | * |
||
1144 | * @return string |
||
1145 | * |
||
1146 | * @throws InternalWorkflowException |
||
1147 | */ |
||
1148 | public function getWorkflowName($id) |
||
1167 | |||
1168 | /** |
||
1169 | * Удаляет workflow |
||
1170 | * |
||
1171 | * @param string $workflowName |
||
1172 | * |
||
1173 | * @return bool |
||
1174 | * |
||
1175 | * @throws InternalWorkflowException |
||
1176 | */ |
||
1177 | public function removeWorkflowDescriptor($workflowName) |
||
1181 | |||
1182 | /** |
||
1183 | * @param $workflowName |
||
1184 | * @param WorkflowDescriptor $descriptor |
||
1185 | * @param $replace |
||
1186 | * |
||
1187 | * @return bool |
||
1188 | * |
||
1189 | * @throws InternalWorkflowException |
||
1190 | */ |
||
1191 | public function saveWorkflowDescriptor($workflowName, WorkflowDescriptor $descriptor, $replace) |
||
1197 | |||
1198 | |||
1199 | /** |
||
1200 | * Query the workflow store for matching instances |
||
1201 | * |
||
1202 | * @param WorkflowExpressionQuery $query |
||
1203 | * |
||
1204 | * @return array |
||
1205 | * |
||
1206 | * @throws InternalWorkflowException |
||
1207 | */ |
||
1208 | public function query(WorkflowExpressionQuery $query) |
||
1212 | |||
1213 | /** |
||
1214 | * @return string |
||
1215 | */ |
||
1216 | 19 | public function getDefaultTypeResolverClass() |
|
1220 | |||
1221 | /** |
||
1222 | * @param string $defaultTypeResolverClass |
||
1223 | * |
||
1224 | * @return $this |
||
1225 | */ |
||
1226 | public function setDefaultTypeResolverClass($defaultTypeResolverClass) |
||
1232 | |||
1233 | |||
1234 | /** |
||
1235 | * @return WorkflowContextInterface |
||
1236 | */ |
||
1237 | 19 | public function getContext() |
|
1241 | } |
||
1242 |