Total Complexity | 41 |
Total Lines | 269 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 2 | Features | 0 |
Complex classes like Configurator 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.
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 Configurator, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | final class Configurator |
||
23 | { |
||
24 | /** @var ReaderInterface */ |
||
25 | private $reader; |
||
26 | |||
27 | /** @var Inflector */ |
||
28 | private $inflector; |
||
29 | |||
30 | /** |
||
31 | * @param object<ReaderInterface|DoctrineReader> $reader |
||
32 | */ |
||
33 | public function __construct(object $reader) |
||
34 | { |
||
35 | $this->reader = ReaderFactory::create($reader); |
||
36 | $this->inflector = (new InflectorFactory())->build(); |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * @param Entity $ann |
||
41 | * @param \ReflectionClass $class |
||
42 | * @return EntitySchema |
||
43 | */ |
||
44 | public function initEntity(Entity $ann, \ReflectionClass $class): EntitySchema |
||
45 | { |
||
46 | $e = new EntitySchema(); |
||
47 | $e->setClass($class->getName()); |
||
48 | |||
49 | $e->setRole($ann->getRole() ?? $this->inflector->camelize($class->getShortName())); |
||
50 | |||
51 | // representing classes |
||
52 | $e->setMapper($this->resolveName($ann->getMapper(), $class)); |
||
53 | $e->setRepository($this->resolveName($ann->getRepository(), $class)); |
||
54 | $e->setSource($this->resolveName($ann->getSource(), $class)); |
||
55 | $e->setConstrain($this->resolveName($ann->getConstrain(), $class)); |
||
56 | |||
57 | if ($ann->isReadonlySchema()) { |
||
58 | $e->getOptions()->set(SyncTables::READONLY_SCHEMA, true); |
||
59 | } |
||
60 | |||
61 | return $e; |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * @param Embeddable $emb |
||
66 | * @param \ReflectionClass $class |
||
67 | * @return EntitySchema |
||
68 | */ |
||
69 | public function initEmbedding(Embeddable $emb, \ReflectionClass $class): EntitySchema |
||
70 | { |
||
71 | $e = new EntitySchema(); |
||
72 | $e->setClass($class->getName()); |
||
73 | |||
74 | $e->setRole($emb->getRole() ?? $this->inflector->camelize($class->getShortName())); |
||
75 | |||
76 | // representing classes |
||
77 | $e->setMapper($this->resolveName($emb->getMapper(), $class)); |
||
78 | |||
79 | return $e; |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * @param EntitySchema $entity |
||
84 | * @param \ReflectionClass $class |
||
85 | * @param string $columnPrefix |
||
86 | */ |
||
87 | public function initFields(EntitySchema $entity, \ReflectionClass $class, string $columnPrefix = ''): void |
||
104 | ); |
||
105 | } |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * @param EntitySchema $entity |
||
110 | * @param \ReflectionClass $class |
||
111 | */ |
||
112 | public function initRelations(EntitySchema $entity, \ReflectionClass $class): void |
||
158 | } |
||
159 | } |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * @param EntitySchema $entity |
||
164 | * @param Column[] $columns |
||
165 | * @param \ReflectionClass $class |
||
166 | */ |
||
167 | public function initColumns(EntitySchema $entity, array $columns, \ReflectionClass $class): void |
||
199 | ); |
||
200 | } |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * @param string $name |
||
205 | * @param Column $column |
||
206 | * @param \ReflectionClass $class |
||
207 | * @param string $columnPrefix |
||
208 | * @return Field |
||
209 | */ |
||
210 | public function initField(string $name, Column $column, \ReflectionClass $class, string $columnPrefix): Field |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Resolve class or role name relative to the current class. |
||
244 | * |
||
245 | * @param string $name |
||
246 | * @param \ReflectionClass $class |
||
247 | * @return string |
||
248 | */ |
||
249 | public function resolveName(?string $name, \ReflectionClass $class): ?string |
||
250 | { |
||
251 | if ($name === null || class_exists($name, true) || interface_exists($name, true)) { |
||
252 | return $name; |
||
253 | } |
||
254 | |||
255 | $resolved = sprintf( |
||
256 | '%s\\%s', |
||
257 | $class->getNamespaceName(), |
||
258 | ltrim(str_replace('/', '\\', $name), '\\') |
||
259 | ); |
||
260 | |||
261 | if (class_exists($resolved, true) || interface_exists($resolved, true)) { |
||
262 | return ltrim($resolved, '\\'); |
||
263 | } |
||
264 | |||
265 | return $name; |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * @param mixed $typecast |
||
270 | * @param \ReflectionClass $class |
||
271 | * @return mixed |
||
272 | */ |
||
273 | protected function resolveTypecast($typecast, \ReflectionClass $class) |
||
291 | } |
||
292 | } |
||
293 |