Complex classes like AbstractRecord 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 AbstractRecord, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | abstract class AbstractRecord extends SchematicEntity |
||
21 | { |
||
22 | use SolidableTrait; |
||
23 | |||
24 | /** |
||
25 | * Set of schema sections needed to describe entity behaviour. |
||
26 | */ |
||
27 | const SH_PRIMARY_KEY = 0; |
||
28 | const SH_DEFAULTS = 1; |
||
29 | const SH_RELATIONS = 6; |
||
30 | |||
31 | /** |
||
32 | * Record behaviour definition. |
||
33 | * |
||
34 | * @var array |
||
35 | */ |
||
36 | private $recordSchema = []; |
||
37 | |||
38 | /** |
||
39 | * Record field updates (changed values). This array contain set of initial property values if |
||
40 | * any of them changed. |
||
41 | * |
||
42 | * @var array |
||
43 | */ |
||
44 | private $changes = []; |
||
45 | |||
46 | /** |
||
47 | * AssociatedRelation bucket. Manages declared record relations. |
||
48 | * |
||
49 | * @var RelationMap |
||
50 | */ |
||
51 | protected $relations; |
||
52 | |||
53 | /** |
||
54 | * Parent ORM instance, responsible for relation initialization and lazy loading operations. |
||
55 | * |
||
56 | * @invisible |
||
57 | * @var ORMInterface |
||
58 | */ |
||
59 | protected $orm; |
||
60 | |||
61 | /** |
||
62 | * @param ORMInterface $orm |
||
63 | * @param array $data |
||
64 | * @param RelationMap $relations |
||
65 | */ |
||
66 | public function __construct( |
||
80 | |||
81 | /** |
||
82 | * Get value of primary of model. Make sure to call isLoaded first! |
||
83 | * |
||
84 | * @return int|string|null |
||
85 | */ |
||
86 | public function primaryKey() |
||
90 | |||
91 | /** |
||
92 | * {@inheritdoc} |
||
93 | * |
||
94 | * @throws RelationException |
||
95 | */ |
||
96 | public function getField(string $name, $default = null, bool $filter = true) |
||
106 | |||
107 | /** |
||
108 | * {@inheritdoc} |
||
109 | * |
||
110 | * @param bool $registerChanges Track field changes. |
||
111 | * |
||
112 | * @throws RelationException |
||
113 | */ |
||
114 | public function setField( |
||
134 | |||
135 | /** |
||
136 | * {@inheritdoc} |
||
137 | */ |
||
138 | public function hasField(string $name): bool |
||
146 | |||
147 | /** |
||
148 | * {@inheritdoc} |
||
149 | * |
||
150 | * @throws AccessException |
||
151 | * @throws RelationException |
||
152 | */ |
||
153 | public function __unset($offset) |
||
168 | |||
169 | /** |
||
170 | * {@inheritdoc} |
||
171 | * |
||
172 | * Method does not check updates in nested relation, but only in primary record. |
||
173 | * |
||
174 | * @param string $field Check once specific field changes. |
||
175 | */ |
||
176 | public function hasChanges(string $field = null): bool |
||
207 | |||
208 | /** |
||
209 | * @return array |
||
210 | */ |
||
211 | public function __debugInfo() |
||
221 | |||
222 | /** |
||
223 | * @return string |
||
224 | */ |
||
225 | public function __toString() |
||
229 | |||
230 | /** |
||
231 | * {@inheritdoc} |
||
232 | */ |
||
233 | protected function isNullable(string $field): bool |
||
243 | |||
244 | /** |
||
245 | * {@inheritdoc} |
||
246 | * |
||
247 | * DocumentEntity will pass ODM instance as part of accessor context. |
||
248 | * |
||
249 | * @see CompositionDefinition |
||
250 | */ |
||
251 | protected function createAccessor( |
||
260 | |||
261 | /** |
||
262 | * {@inheritdoc} |
||
263 | */ |
||
264 | protected function iocContainer() |
||
273 | |||
274 | /** |
||
275 | * Name of column used as primary key. |
||
276 | * |
||
277 | * @return string |
||
278 | */ |
||
279 | protected function primaryColumn(): string |
||
283 | |||
284 | /** |
||
285 | * Create set of fields to be sent to UPDATE statement. |
||
286 | * |
||
287 | * @param bool $skipPrimary Skip primary key |
||
288 | * |
||
289 | * @return array |
||
290 | */ |
||
291 | protected function packChanges(bool $skipPrimary = false): array |
||
327 | |||
328 | /** |
||
329 | * Indicate that all updates done, reset dirty state. |
||
330 | */ |
||
331 | protected function flushChanges() |
||
341 | |||
342 | /** |
||
343 | * @param string $name |
||
344 | */ |
||
345 | private function registerChange(string $name) |
||
356 | |||
357 | /** |
||
358 | * @param string $name |
||
359 | * |
||
360 | * @throws AccessException |
||
361 | */ |
||
362 | private function assertField(string $name) |
||
372 | } |