Complex classes like ContainerFactory 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 ContainerFactory, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class ContainerFactory |
||
| 17 | { |
||
| 18 | |||
| 19 | private $configs; |
||
| 20 | |||
| 21 | /** @var Container[] */ |
||
| 22 | private $containersToMerge; |
||
| 23 | |||
| 24 | private $workingDirectory; |
||
| 25 | |||
| 26 | |||
| 27 | 18 | public function addConfig($file) |
|
| 31 | |||
| 32 | |||
| 33 | 1 | public function getConfigs() |
|
| 37 | |||
| 38 | |||
| 39 | 13 | public function addContainerToMerge(Container $container) |
|
| 43 | |||
| 44 | |||
| 45 | 1 | public function getContainersToMerge() |
|
| 49 | |||
| 50 | |||
| 51 | 1 | public function getWorkingDirectory() |
|
| 55 | |||
| 56 | |||
| 57 | 19 | public function setWorkingDirectory($workingDirectory) |
|
| 61 | |||
| 62 | |||
| 63 | 18 | public function create() |
|
| 131 | |||
| 132 | |||
| 133 | 17 | private function resolveFiles(array $files) |
|
| 134 | { |
||
| 135 | 17 | $return = []; |
|
| 136 | 17 | foreach ($files as $file) { |
|
| 137 | 17 | $array = $this->readFile($file); |
|
| 138 | 15 | if ($array !== NULL) { |
|
| 139 | 15 | if (isset($array['includes'])) { |
|
| 140 | 2 | foreach ($array['includes'] as $include) { |
|
| 141 | 2 | $return[] = dirname($file) . DIRECTORY_SEPARATOR . $include; |
|
| 142 | 2 | } |
|
| 143 | 2 | } |
|
| 144 | 15 | $return[] = $file; |
|
| 145 | 15 | } |
|
| 146 | 15 | } |
|
| 147 | 15 | return $return; |
|
| 148 | } |
||
| 149 | |||
| 150 | |||
| 151 | 15 | private function readConfigs($files, $config) |
|
| 161 | |||
| 162 | |||
| 163 | 17 | private function readFile($file) |
|
| 174 | |||
| 175 | |||
| 176 | 15 | private function parseValues($config, & $allConfig = [], $keysPath = []) |
|
| 177 | { |
||
| 178 | 15 | $config = $this->resolveUnmergables($config); |
|
| 179 | 15 | foreach ($config as $key => $value) { |
|
| 180 | 15 | if($value instanceof \Nette\Neon\Entity){ |
|
| 181 | 13 | $value->value = $this->parseValue($value->value, $allConfig); |
|
| 182 | 13 | foreach($value->attributes as $k => $v){ |
|
| 183 | 13 | if(is_array($v)){ |
|
| 184 | 9 | $value->attributes[$k] = $this->parseValues($v, $allConfig, array_merge($keysPath, [$key])); |
|
| 185 | 9 | } else{ |
|
| 186 | 4 | $value->attributes[$k] = $this->parseValue($v, $allConfig); |
|
| 187 | } |
||
| 188 | 13 | } |
|
| 189 | 15 | } elseif (is_array($value)) { |
|
| 190 | 15 | $value = $this->parseValues($value, $allConfig, array_merge($keysPath, [$key])); |
|
| 191 | 15 | } elseif(!is_object($value)) { |
|
| 192 | 15 | $value = $this->parseValue($value, $allConfig); |
|
| 193 | 15 | } |
|
| 194 | |||
| 195 | // get new key name, and replace it |
||
| 196 | 15 | $newKey = $this->parseValue($key, $allConfig); |
|
| 197 | 15 | unset($config[$key]); |
|
| 198 | 15 | $config[$newKey] = $value; |
|
| 199 | |||
| 200 | // write to global config |
||
| 201 | 15 | $v = & $allConfig; |
|
| 202 | 15 | foreach ($keysPath as $kp) { |
|
| 203 | 15 | $v = & $v[$kp]; |
|
| 204 | 15 | } |
|
| 205 | 15 | if (!($value instanceof \Nette\Neon\Entity)) { |
|
| 206 | 15 | $v[$newKey] = $value; |
|
| 207 | 15 | } |
|
| 208 | 15 | } |
|
| 209 | 15 | return $config; |
|
| 210 | } |
||
| 211 | |||
| 212 | |||
| 213 | 15 | private function parseValue($value, $config) |
|
| 235 | |||
| 236 | |||
| 237 | 15 | private function resolveUnmergables($config) |
|
| 248 | |||
| 249 | } |