Complex classes like Manager 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 Manager, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 36 | class Manager implements IManager { |
||
| 37 | /** @var EventDispatcherInterface */ |
||
| 38 | protected $dispatcher; |
||
| 39 | |||
| 40 | /** @var IApp[] */ |
||
| 41 | protected $apps; |
||
| 42 | |||
| 43 | /** @var INotifier */ |
||
| 44 | protected $notifiers; |
||
| 45 | |||
| 46 | /** @var array[] */ |
||
| 47 | protected $notifiersInfo; |
||
| 48 | |||
| 49 | /** @var \Closure[] */ |
||
| 50 | protected $appsClosures; |
||
| 51 | |||
| 52 | /** @var \Closure[] */ |
||
| 53 | protected $notifiersClosures; |
||
| 54 | |||
| 55 | /** @var \Closure[] */ |
||
| 56 | protected $notifiersInfoClosures; |
||
| 57 | |||
| 58 | /** @var IApp[] */ |
||
| 59 | protected $builtAppsHolder; |
||
| 60 | |||
| 61 | /** @var INotifier[] */ |
||
| 62 | protected $builtNotifiersHolder; |
||
| 63 | |||
| 64 | public function __construct(EventDispatcherInterface $dispatcher) { |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @param \Closure $service The service must implement IApp, otherwise a |
||
| 79 | * \InvalidArgumentException is thrown later |
||
| 80 | * @return null |
||
| 81 | * @since 8.2.0 |
||
| 82 | */ |
||
| 83 | public function registerApp(\Closure $service) { |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @param \Closure $service The service must implement INotifier, otherwise a |
||
| 90 | * \InvalidArgumentException is thrown later |
||
| 91 | * @param \Closure $info An array with the keys 'id' and 'name' containing |
||
| 92 | * the app id and the app name |
||
| 93 | * @return null |
||
| 94 | * @since 8.2.0 - Parameter $info was added in 9.0.0 |
||
| 95 | */ |
||
| 96 | public function registerNotifier(\Closure $service, \Closure $info) { |
||
| 102 | |||
| 103 | /** |
||
| 104 | * INTERNAL USE ONLY!! This method isn't part of the IManager interface |
||
| 105 | * @internal This should only be used by the RegisterConsumerEventImpl (the real implementation). |
||
| 106 | * Do NOT use this method outside as it might not work as expected. |
||
| 107 | */ |
||
| 108 | public function registerBuiltApp(IApp $app) { |
||
| 111 | |||
| 112 | /** |
||
| 113 | * INTERNAL USE ONLY!! This method isn't part of the IManager interface |
||
| 114 | * @internal This should only be used by the RegisterNotifierEventImpl (the real implementation). |
||
| 115 | * Do NOT use this method outside as it might not work as expected. |
||
| 116 | */ |
||
| 117 | public function registerBuiltNotifier(INotifier $notifier, $id, $name) { |
||
| 127 | |||
| 128 | /** |
||
| 129 | * @return IApp[] |
||
| 130 | */ |
||
| 131 | protected function getApps() { |
||
| 152 | |||
| 153 | /** |
||
| 154 | * @return INotifier[] |
||
| 155 | */ |
||
| 156 | protected function getNotifiers() { |
||
| 179 | |||
| 180 | /** |
||
| 181 | * @return array[] |
||
| 182 | */ |
||
| 183 | public function listNotifiers() { |
||
| 209 | |||
| 210 | /** |
||
| 211 | * @return INotification |
||
| 212 | * @since 8.2.0 |
||
| 213 | */ |
||
| 214 | public function createNotification() { |
||
| 217 | |||
| 218 | /** |
||
| 219 | * @return bool |
||
| 220 | * @since 8.2.0 |
||
| 221 | */ |
||
| 222 | public function hasNotifiers() { |
||
| 225 | |||
| 226 | /** |
||
| 227 | * @param INotification $notification |
||
| 228 | * @return null |
||
| 229 | * @throws \InvalidArgumentException When the notification is not valid |
||
| 230 | * @since 8.2.0 |
||
| 231 | */ |
||
| 232 | public function notify(INotification $notification) { |
||
| 246 | |||
| 247 | /** |
||
| 248 | * @param INotification $notification |
||
| 249 | * @param string $languageCode The code of the language that should be used to prepare the notification |
||
| 250 | * @return INotification |
||
| 251 | * @throws \InvalidArgumentException When the notification was not prepared by a notifier |
||
| 252 | * @since 8.2.0 |
||
| 253 | */ |
||
| 254 | public function prepare(INotification $notification, $languageCode) { |
||
| 275 | |||
| 276 | /** |
||
| 277 | * @param INotification $notification |
||
| 278 | * @return null |
||
| 279 | */ |
||
| 280 | public function markProcessed(INotification $notification) { |
||
| 287 | |||
| 288 | /** |
||
| 289 | * @param INotification $notification |
||
| 290 | * @return int |
||
| 291 | */ |
||
| 292 | public function getCount(INotification $notification) { |
||
| 302 | } |
||
| 303 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..