Complex classes like RecordSchema 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 RecordSchema, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 24 | class RecordSchema implements SchemaInterface  | 
            ||
| 25 | { | 
            ||
| 26 | /**  | 
            ||
| 27 | * @var ReflectionEntity  | 
            ||
| 28 | */  | 
            ||
| 29 | private $reflection;  | 
            ||
| 30 | |||
| 31 | /**  | 
            ||
| 32 | * @invisible  | 
            ||
| 33 | * @var MutatorsConfig  | 
            ||
| 34 | */  | 
            ||
| 35 | private $mutatorsConfig;  | 
            ||
| 36 | |||
| 37 | /**  | 
            ||
| 38 | * @invisible  | 
            ||
| 39 | * @var ColumnRenderer  | 
            ||
| 40 | */  | 
            ||
| 41 | private $renderer;  | 
            ||
| 42 | |||
| 43 | /**  | 
            ||
| 44 | * @param ReflectionEntity $reflection  | 
            ||
| 45 | * @param MutatorsConfig $mutators  | 
            ||
| 46 | * @param ColumnRenderer|null $rendered  | 
            ||
| 47 | */  | 
            ||
| 48 | public function __construct(  | 
            ||
| 57 | |||
| 58 | /**  | 
            ||
| 59 |      * {@inheritdoc} | 
            ||
| 60 | */  | 
            ||
| 61 | public function getClass(): string  | 
            ||
| 65 | |||
| 66 | /**  | 
            ||
| 67 |      * {@inheritdoc} | 
            ||
| 68 | */  | 
            ||
| 69 | public function getRole(): string  | 
            ||
| 76 | |||
| 77 | /**  | 
            ||
| 78 | * @return ReflectionEntity  | 
            ||
| 79 | */  | 
            ||
| 80 | public function getReflection(): ReflectionEntity  | 
            ||
| 84 | |||
| 85 | /**  | 
            ||
| 86 |      * {@inheritdoc} | 
            ||
| 87 | */  | 
            ||
| 88 | public function getInstantiator(): string  | 
            ||
| 92 | |||
| 93 | /**  | 
            ||
| 94 |      * {@inheritdoc} | 
            ||
| 95 | */  | 
            ||
| 96 | public function getDatabase()  | 
            ||
| 106 | |||
| 107 | /**  | 
            ||
| 108 |      * {@inheritdoc} | 
            ||
| 109 | */  | 
            ||
| 110 | public function getTable(): string  | 
            ||
| 121 | |||
| 122 | /**  | 
            ||
| 123 | * Fields and their types declared in Record model.  | 
            ||
| 124 | *  | 
            ||
| 125 | * @return array  | 
            ||
| 126 | */  | 
            ||
| 127 | public function getFields(): array  | 
            ||
| 139 | |||
| 140 | /**  | 
            ||
| 141 | * Returns set of declared indexes.  | 
            ||
| 142 | *  | 
            ||
| 143 | * Example:  | 
            ||
| 144 | * const INDEXES = [  | 
            ||
| 145 | * [self::UNIQUE, 'email'],  | 
            ||
| 146 | * [self::INDEX, 'status', 'balance'],  | 
            ||
| 147 | * [self::INDEX, 'public_id']  | 
            ||
| 148 | * ];  | 
            ||
| 149 | *  | 
            ||
| 150 | * @do generator  | 
            ||
| 151 | *  | 
            ||
| 152 | * @return \Generator|IndexDefinition[]  | 
            ||
| 153 | *  | 
            ||
| 154 | * @throws DefinitionException  | 
            ||
| 155 | */  | 
            ||
| 156 | public function getIndexes(): \Generator  | 
            ||
| 164 | |||
| 165 | /**  | 
            ||
| 166 |      * {@inheritdoc} | 
            ||
| 167 | */  | 
            ||
| 168 | public function declareTable(AbstractTable $table): AbstractTable  | 
            ||
| 176 | |||
| 177 | /**  | 
            ||
| 178 |      * {@inheritdoc} | 
            ||
| 179 | */  | 
            ||
| 180 | public function getRelations(): \Generator  | 
            ||
| 208 | |||
| 209 | /**  | 
            ||
| 210 |      * {@inheritdoc} | 
            ||
| 211 | */  | 
            ||
| 212 | public function packSchema(  | 
            ||
| 240 | |||
| 241 | /**  | 
            ||
| 242 | * Generate set of default values to be used by record.  | 
            ||
| 243 | *  | 
            ||
| 244 | * @param AbstractTable $table  | 
            ||
| 245 | *  | 
            ||
| 246 | * @return array  | 
            ||
| 247 | */  | 
            ||
| 248 | protected function packDefaults(AbstractTable $table): array  | 
            ||
| 269 | |||
| 270 | /**  | 
            ||
| 271 | * Generate set of mutators associated with entity fields using user defined and automatic  | 
            ||
| 272 | * mutators.  | 
            ||
| 273 | *  | 
            ||
| 274 | * @see MutatorsConfig  | 
            ||
| 275 | *  | 
            ||
| 276 | * @param AbstractTable $table  | 
            ||
| 277 | *  | 
            ||
| 278 | * @return array  | 
            ||
| 279 | */  | 
            ||
| 280 | protected function buildMutators(AbstractTable $table): array  | 
            ||
| 307 | |||
| 308 | /**  | 
            ||
| 309 | * Check if field schema/type defines relation.  | 
            ||
| 310 | *  | 
            ||
| 311 | * @param mixed $type  | 
            ||
| 312 | *  | 
            ||
| 313 | * @return bool  | 
            ||
| 314 | */  | 
            ||
| 315 | protected function isRelation($type): bool  | 
            ||
| 323 | |||
| 324 | /**  | 
            ||
| 325 | * @param array $definition  | 
            ||
| 326 | *  | 
            ||
| 327 | * @return IndexDefinition  | 
            ||
| 328 | *  | 
            ||
| 329 | * @throws DefinitionException  | 
            ||
| 330 | */  | 
            ||
| 331 | protected function castIndex(array $definition)  | 
            ||
| 359 | |||
| 360 | /**  | 
            ||
| 361 | * Default defined values.  | 
            ||
| 362 | *  | 
            ||
| 363 | * @return array  | 
            ||
| 364 | */  | 
            ||
| 365 | protected function getDefaults(): array  | 
            ||
| 370 | |||
| 371 | /**  | 
            ||
| 372 | * Process value thought associated mutator if any.  | 
            ||
| 373 | *  | 
            ||
| 374 | * @param array $mutators  | 
            ||
| 375 | * @param string $field  | 
            ||
| 376 | * @param mixed $default  | 
            ||
| 377 | *  | 
            ||
| 378 | * @return mixed  | 
            ||
| 379 | */  | 
            ||
| 380 | protected function mutateValue(array $mutators, string $field, $default)  | 
            ||
| 405 | |||
| 406 | /**  | 
            ||
| 407 | * Pass value thought accessor to ensure it's default.  | 
            ||
| 408 | *  | 
            ||
| 409 | * @param mixed $default  | 
            ||
| 410 | * @param string $accessor  | 
            ||
| 411 | *  | 
            ||
| 412 | * @return mixed  | 
            ||
| 413 | *  | 
            ||
| 414 | * @throws AccessorExceptionInterface  | 
            ||
| 415 | */  | 
            ||
| 416 | protected function accessorDefault($default, string $accessor)  | 
            ||
| 431 | }  |