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 |
||
29 | class Container implements ContainerInterface |
||
30 | { |
||
31 | |||
32 | /** |
||
33 | * Holds all resolved or resolvable instances into the container. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | |||
38 | protected $collection; |
||
39 | |||
40 | /** |
||
41 | * Class specific defined dependencies. |
||
42 | * |
||
43 | * @var array |
||
44 | */ |
||
45 | |||
46 | protected $dependencies; |
||
47 | |||
48 | /** |
||
49 | * Cache of classes inspector and resolver. |
||
50 | * |
||
51 | * @var array |
||
52 | */ |
||
53 | |||
54 | protected $resolving; |
||
55 | |||
56 | /** |
||
57 | * Cache of classes dependencies in callbacks ready for resolution. |
||
58 | * |
||
59 | * @var array |
||
60 | */ |
||
61 | |||
62 | protected $resolved; |
||
63 | |||
64 | /** |
||
65 | * Call a user function injecting the dependencies. |
||
66 | * |
||
67 | * @param string|Closure $function The function or the user function name. |
||
68 | * @param array $parameters The predefined dependencies. |
||
69 | * |
||
70 | * @return mixed |
||
71 | */ |
||
72 | |||
73 | public function call($function, array $parameters = []) |
||
91 | |||
92 | /** |
||
93 | * Makes an element or class injecting automatically all the dependencies. |
||
94 | * |
||
95 | * @param string $abstract The class name or container element name to make. |
||
96 | * @param array $parameters Specific parameters definition. |
||
97 | * @param bool $force Specify if a new element must be given and the dependencies must have be recalculated. |
||
98 | 3 | * |
|
99 | * @throws \Psr\Container\Exception\ContainerException |
||
100 | 3 | * @return object|null |
|
101 | 3 | */ |
|
102 | 3 | ||
103 | public function make($abstract, array $parameters = [], bool $force = false) |
||
119 | |||
120 | /** |
||
121 | * Construct a class and all the dependencies using the reflection library of PHP. |
||
122 | * |
||
123 | * @param string $abstract The class name or container element name to make. |
||
124 | * @param bool $force Specify if a new element must be given and the dependencies must have be recalculated. |
||
125 | * |
||
126 | * @throws ReflectionException |
||
127 | * @return Closure |
||
128 | 19 | */ |
|
129 | |||
130 | 19 | protected function construct(string $abstract, bool $force) : Closure |
|
154 | 19 | ||
155 | /** |
||
156 | 18 | * Resolve all the given class reflected dependencies. |
|
157 | 8 | * |
|
158 | * @param string $abstract The class name or container element name to resolve dependencies. |
||
159 | * @param ReflectionParameter $dependency The class dependency to be resolved. |
||
160 | 8 | * @param bool $force Specify if the dependencies must be recalculated. |
|
161 | * |
||
162 | 8 | * @return Object |
|
163 | 8 | */ |
|
164 | |||
165 | 8 | protected function resolve(string $abstract, ReflectionParameter $dependency, bool $force) |
|
175 | |||
176 | /** |
||
177 | * Generate the dependencies callbacks to jump some conditions in every dependency creation. |
||
178 | * |
||
179 | * @param string $abstract The class name or container element name to resolve dependencies. |
||
180 | * @param ReflectionParameter $dependency The class dependency to be resolved. |
||
181 | * |
||
182 | * @return Closure |
||
183 | */ |
||
184 | |||
185 | protected function generate(string $abstract, ReflectionParameter $dependency) : Closure |
||
202 | |||
203 | /** |
||
204 | * Reset the container, removing all the elements, cache and options. |
||
205 | * |
||
206 | * @return void |
||
207 | 8 | */ |
|
208 | |||
209 | 8 | public function flush() |
|
216 | 5 | ||
217 | 5 | /** |
|
218 | * Finds an entry of the container by its identifier and returns it. |
||
219 | * |
||
220 | * @param string $abstract Identifier of the entry to look for. |
||
221 | * |
||
222 | * @throws \Psr\Container\Exception\NotFoundException No entry was found for this identifier. |
||
223 | * @throws \Psr\Container\Exception\ContainerException Error while retrieving the entry. |
||
224 | * |
||
225 | * @return mixed Entry. |
||
226 | */ |
||
227 | public function get($abstract) |
||
243 | |||
244 | 10 | /** |
|
245 | 8 | * Returns true if the container can return an entry for the given identifier. |
|
246 | * Returns false otherwise. |
||
247 | 8 | * |
|
248 | 2 | * `has($abstract)` returning true does not mean that `get($abstract)` will not throw an exception. |
|
249 | 6 | * It does however mean that `get($abstract)` will not throw a `NotFoundException`. |
|
250 | * |
||
251 | * @param string $abstract Identifier of the entry to look for. |
||
252 | 2 | * |
|
253 | * @return boolean |
||
254 | */ |
||
255 | 2 | ||
256 | public function has($abstract) |
||
260 | 2 | ||
261 | /** |
||
262 | 2 | * Verify if an element has a singleton instance. |
|
263 | * |
||
264 | 2 | * @param string The class name or container element name to resolve dependencies. |
|
265 | * @return bool |
||
266 | */ |
||
267 | 2 | ||
268 | public function isSingleton(string $abstract) : bool |
||
272 | 2 | ||
273 | /** |
||
274 | 2 | * Bind a new element to the container. |
|
275 | * |
||
276 | * @param string $abstract The alias name that will be used to call the element. |
||
277 | 1 | * @param string|closure $concrete The element class name, or an closure that makes the element. |
|
278 | * @param bool $shared Define if the element will be a singleton instance. |
||
279 | 1 | * |
|
280 | 1 | * @return \Codeburner\Container\Container |
|
281 | */ |
||
282 | 1 | ||
283 | public function set(string $abstract, $concrete, bool $shared = false) : self |
||
297 | |||
298 | /** |
||
299 | * Bind a new element to the container IF the element name not exists in the container. |
||
300 | * |
||
301 | * @param string $abstract The alias name that will be used to call the element. |
||
302 | * @param string|closure $concrete The element class name, or an closure that makes the element. |
||
303 | * @param bool $shared Define if the element will be a singleton instance. |
||
304 | * |
||
305 | * @return \Codeburner\Container\Container |
||
306 | */ |
||
307 | |||
308 | public function setIf(string $abstract, $concrete, bool $shared = false) : self |
||
316 | 2 | ||
317 | /** |
||
318 | 2 | * Bind an specific instance to a class dependency. |
|
319 | * |
||
320 | * @param string $class The class full name. |
||
321 | * @param string $dependencyName The dependency full name. |
||
322 | * @param string|closure $dependency The specific object class name or a classure that makes the element. |
||
323 | * |
||
324 | * @return \Codeburner\Container\Container |
||
325 | */ |
||
326 | |||
327 | 5 | public function setTo(string $class, string $dependencyName, $dependency) : self |
|
345 | |||
346 | 8 | /** |
|
347 | 11 | * Bind an element that will be construct only one time, and every call for the element, |
|
348 | 11 | * the same instance will be given. |
|
349 | * |
||
350 | 12 | * @param string $abstract The alias name that will be used to call the element. |
|
351 | 6 | * @param string|closure $concrete The element class name, or an closure that makes the element. |
|
352 | 12 | * |
|
353 | * @return \Codeburner\Container\Container |
||
354 | 12 | */ |
|
355 | |||
356 | public function singleton(string $abstract, $concrete) : self |
||
362 | |||
363 | /** |
||
364 | * Bind an object to the container. |
||
365 | * |
||
366 | * @param string $abstract The alias name that will be used to call the object. |
||
367 | 1 | * @param object $instance The object that will be inserted. |
|
368 | * |
||
369 | 1 | * @throws \Psr\Container\Exception\ContainerException When $instance is not an object. |
|
370 | 1 | * @return \Codeburner\Container\Container |
|
371 | 1 | */ |
|
372 | |||
373 | 1 | public function instance(string $abstract, $instance) : self |
|
383 | |||
384 | /** |
||
385 | * Modify an element with a given function that receive the old element as argument. |
||
386 | 3 | * |
|
387 | * @param string $abstract The alias name that will be used to call the element. |
||
388 | 3 | * @param closure $extension The function that receives the old element and return a new or modified one. |
|
389 | 2 | * |
|
390 | * @throws \Psr\Container\Exception\NotFoundException When no element was found with $abstract key. |
||
391 | 1 | * @return \Codeburner\Container\Container |
|
392 | 1 | */ |
|
393 | 1 | ||
394 | public function extend(string $abstract, closure $extension) : self |
||
412 | |||
413 | /** |
||
414 | * Makes an resolvable element an singleton. |
||
415 | 3 | * |
|
416 | * @param string $abstract The alias name that will be used to call the element. |
||
417 | 3 | * |
|
418 | * @throws \Psr\Container\Exception\NotFoundException When no element was found with $abstract key. |
||
419 | 3 | * @throws \Psr\Container\Exception\ContainerException When the element on $abstract key is not resolvable. |
|
420 | * |
||
421 | * @return \Codeburner\Container\Container |
||
422 | */ |
||
423 | |||
424 | public function share(string $abstract) : self |
||
438 | |||
439 | } |
||
440 |