Complex classes like Container 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 Container, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 13 | class Container implements ContainerInterface |
||
| 14 | { |
||
| 15 | /** |
||
| 16 | * Array of singletons |
||
| 17 | * @var array |
||
| 18 | */ |
||
| 19 | protected $shares = []; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * Array pf definitions, support instance,callable,Definition, class |
||
| 23 | * @var array |
||
| 24 | */ |
||
| 25 | protected $definitions = []; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Array of interface bindings |
||
| 29 | * @var array |
||
| 30 | */ |
||
| 31 | protected $contextBindings = []; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Array of parameters |
||
| 35 | * @var ParameterStore |
||
| 36 | */ |
||
| 37 | protected $parameters; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @var ClassDefinitionResolver |
||
| 41 | */ |
||
| 42 | protected $classDefinitionResolver; |
||
| 43 | |||
| 44 | public function __construct() |
||
| 48 | |||
| 49 | /** |
||
| 50 | * Add a Definition class |
||
| 51 | * @param string $name |
||
| 52 | * @param string $class |
||
| 53 | * @return ClassDefinition |
||
| 54 | */ |
||
| 55 | public function define($name, $class) |
||
| 61 | |||
| 62 | /** |
||
| 63 | * Bind an callable to the container with its name |
||
| 64 | * @param string $name |
||
| 65 | * @param mixed $creation A invalid callable |
||
| 66 | * @throws ConfigException |
||
| 67 | * @return $this |
||
| 68 | */ |
||
| 69 | public function call($name, $creation) |
||
| 77 | |||
| 78 | /** |
||
| 79 | * Bind an instance to the container with its name |
||
| 80 | * ``` |
||
| 81 | * $container->instance('user', new User()); |
||
| 82 | * //Or just give instance |
||
| 83 | * $container->instance(new User()); |
||
| 84 | * |
||
| 85 | * ``` |
||
| 86 | * @param string $name |
||
| 87 | * @param object $instance |
||
| 88 | * @throws ConfigException |
||
| 89 | * @return $this |
||
| 90 | */ |
||
| 91 | public function instance($name, $instance = null) |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Binds an interface or abstract class to its implementation; |
||
| 107 | * It's also be used to bind a service name to an existing class |
||
| 108 | * @param string $name |
||
| 109 | * @param string $implementation |
||
| 110 | * @param string|array $context the specified context to bind |
||
| 111 | * @throws ConfigException |
||
| 112 | * @return $this |
||
| 113 | */ |
||
| 114 | public function bind($name, $implementation, $context = null) |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Add a definition to the container |
||
| 136 | * ``` |
||
| 137 | * //Add an instance like "instance" method |
||
| 138 | * $container->set('student', new Student()); |
||
| 139 | * |
||
| 140 | * //Add a callable definition |
||
| 141 | * $container->set('student', 'StudentFactory::create'); |
||
| 142 | * $container->set('student', function(){ |
||
| 143 | * return new Student(); |
||
| 144 | * }); |
||
| 145 | * |
||
| 146 | * //Add an instance of "Slince\Di\Definition" |
||
| 147 | * $container->set('student', new Definition('Foo\Bar\StudentClass', [ |
||
| 148 | * 'gender' => 'boy', |
||
| 149 | * 'school' => new Reference('school') |
||
| 150 | * ], [ |
||
| 151 | * 'setAge' => [18] |
||
| 152 | * ], [ |
||
| 153 | * 'father' => 'James', |
||
| 154 | * 'mather' => 'Sophie' |
||
| 155 | * ])); |
||
| 156 | * |
||
| 157 | * //Add a class definition |
||
| 158 | * $container->set('student', Foo\Bar\StudentClass); |
||
| 159 | * ``` |
||
| 160 | * @param string $name |
||
| 161 | * @param mixed $definition |
||
| 162 | * @throws ConfigException |
||
| 163 | * @return $this |
||
| 164 | */ |
||
| 165 | public function set($name, $definition) |
||
| 178 | |||
| 179 | /** |
||
| 180 | * Share the service by given name |
||
| 181 | * @param string $name |
||
| 182 | * @return $this |
||
| 183 | */ |
||
| 184 | public function share($name) |
||
| 189 | |||
| 190 | /** |
||
| 191 | * Get a service instance by specified name |
||
| 192 | * @param string $name |
||
| 193 | * @param array $arguments |
||
| 194 | * @return object |
||
| 195 | */ |
||
| 196 | public function get($name, $arguments = []) |
||
| 217 | |||
| 218 | /** |
||
| 219 | * {@inheritdoc} |
||
| 220 | */ |
||
| 221 | public function has($name) |
||
| 231 | |||
| 232 | /** |
||
| 233 | * Gets all global parameters |
||
| 234 | * @return array |
||
| 235 | */ |
||
| 236 | public function getParameters() |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Sets array of parameters |
||
| 243 | * @param array $parameterStore |
||
| 244 | */ |
||
| 245 | public function setParameters(array $parameterStore) |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Add some parameters |
||
| 252 | * @param array $parameters |
||
| 253 | */ |
||
| 254 | public function addParameters(array $parameters) |
||
| 258 | |||
| 259 | /** |
||
| 260 | * Sets a parameter with its name and value |
||
| 261 | * @param $name |
||
| 262 | * @param mixed $value |
||
| 263 | */ |
||
| 264 | public function setParameter($name, $value) |
||
| 268 | |||
| 269 | /** |
||
| 270 | * Gets a parameter by given name |
||
| 271 | * @param $name |
||
| 272 | * @param mixed $default |
||
| 273 | * @return mixed |
||
| 274 | */ |
||
| 275 | public function getParameter($name, $default = null) |
||
| 279 | |||
| 280 | /** |
||
| 281 | * Resolves all arguments for the function or method. |
||
| 282 | * @param \ReflectionFunctionAbstract $method |
||
| 283 | * @param array $arguments |
||
| 284 | * @param array $contextBindings The context bindings for the function |
||
| 285 | * @throws DependencyInjectionException |
||
| 286 | * @return array |
||
| 287 | */ |
||
| 288 | public function resolveFunctionArguments(\ReflectionFunctionAbstract $method, array $arguments, array $contextBindings = []) |
||
| 324 | |||
| 325 | /** |
||
| 326 | * Gets all context bindings for the class and method |
||
| 327 | * [ |
||
| 328 | * 'User' => [ |
||
| 329 | * 'original' => 'SchoolInterface' |
||
| 330 | * 'bind' => 'MagicSchool', |
||
| 331 | * ] |
||
| 332 | * ] |
||
| 333 | * @param string $contextClass |
||
| 334 | * @param string $contextMethod |
||
| 335 | * @return array |
||
| 336 | */ |
||
| 337 | public function getContextBindings($contextClass, $contextMethod) |
||
| 349 | |||
| 350 | protected function createInstanceFromDefinition($definition, array $arguments) |
||
| 371 | |||
| 372 | protected function getClassDefinitionResolver() |
||
| 379 | |||
| 380 | /** |
||
| 381 | * Resolves array of parameters |
||
| 382 | * @param array $parameters |
||
| 383 | * @return array |
||
| 384 | */ |
||
| 385 | protected function resolveParameters($parameters) |
||
| 398 | |||
| 399 | /** |
||
| 400 | * Formats parameter value |
||
| 401 | * @param $value |
||
| 402 | * @return mixed |
||
| 403 | * @throws DependencyInjectionException |
||
| 404 | */ |
||
| 405 | protected function formatParameter($value) |
||
| 424 | } |
||
| 425 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.