Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ObjectAccessor 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 ObjectAccessor, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
25 | abstract class ObjectAccessor extends Component |
||
26 | { |
||
27 | |||
28 | use ObjectRecordBehavior; |
||
29 | |||
30 | /** |
||
31 | * @var Object[] |
||
32 | */ |
||
33 | protected $_cacheAll; |
||
34 | |||
35 | /** |
||
36 | * @var Object[] |
||
37 | */ |
||
38 | protected $_cacheById = []; |
||
39 | |||
40 | /******************************************* |
||
41 | * OBJECT CLASSES |
||
42 | *******************************************/ |
||
43 | |||
44 | /** |
||
45 | * @return string |
||
46 | */ |
||
47 | public abstract static function objectClass(): string; |
||
48 | |||
49 | /** |
||
50 | * @return string |
||
51 | */ |
||
52 | public static function objectClassInstance(): string |
||
56 | |||
57 | /******************************************* |
||
58 | * CREATE |
||
59 | *******************************************/ |
||
60 | |||
61 | /** |
||
62 | * @param array $config |
||
63 | * @throws InvalidConfigException |
||
64 | * @return Object |
||
65 | */ |
||
66 | View Code Duplication | public function create($config = []): Object |
|
90 | |||
91 | /** |
||
92 | * @param Record $record |
||
93 | * @param string|null $toScenario |
||
94 | * @throws InvalidConfigException |
||
95 | * @return Object |
||
96 | */ |
||
97 | protected function createFromRecord(Record $record, string $toScenario = null): Object |
||
117 | |||
118 | |||
119 | /******************************************* |
||
120 | * FIND/GET ALL |
||
121 | *******************************************/ |
||
122 | |||
123 | /** |
||
124 | * @param string $toScenario |
||
125 | * @return Object[] |
||
126 | */ |
||
127 | View Code Duplication | public function findAll(string $toScenario = null) |
|
151 | |||
152 | /** |
||
153 | * @param string $toScenario |
||
154 | * @return Object[] |
||
155 | * @throws ObjectNotFoundException |
||
156 | */ |
||
157 | public function getAll(string $toScenario = null): array |
||
169 | |||
170 | /******************************************* |
||
171 | * FIND/GET |
||
172 | *******************************************/ |
||
173 | |||
174 | /** |
||
175 | * @param $identifier |
||
176 | * @param string $toScenario |
||
177 | * @return Object|null |
||
178 | */ |
||
179 | View Code Duplication | public function find($identifier, string $toScenario = null) |
|
201 | |||
202 | /** |
||
203 | * @param $identifier |
||
204 | * @param string $toScenario |
||
205 | * @return Object |
||
206 | * @throws ObjectNotFoundException |
||
207 | */ |
||
208 | public function get($identifier, string $toScenario = null): Object |
||
221 | |||
222 | /******************************************* |
||
223 | * FIND/GET BY ID |
||
224 | *******************************************/ |
||
225 | |||
226 | /** |
||
227 | * @param int $id |
||
228 | * @param string|null $toScenario |
||
229 | * @return Object|null |
||
230 | */ |
||
231 | View Code Duplication | public function findById(int $id, string $toScenario = null) |
|
256 | |||
257 | /** |
||
258 | * @param int $id |
||
259 | * @param string|null $toScenario |
||
260 | * @return Object |
||
261 | * @throws ObjectNotFoundException |
||
262 | */ |
||
263 | View Code Duplication | public function getById(int $id, string $toScenario = null): Object |
|
276 | |||
277 | /** |
||
278 | * @param int $id |
||
279 | * @param string|null $toScenario |
||
280 | * @return Object|null |
||
281 | */ |
||
282 | View Code Duplication | public function freshFindById(int $id, string $toScenario = null) |
|
296 | |||
297 | /** |
||
298 | * @param int $id |
||
299 | * @param string|null $toScenario |
||
300 | * @return Object |
||
301 | * @throws ObjectNotFoundException |
||
302 | */ |
||
303 | View Code Duplication | public function freshGetById(int $id, string $toScenario = null): Object |
|
315 | |||
316 | /******************************************* |
||
317 | * FIND/GET BY QUERY |
||
318 | *******************************************/ |
||
319 | |||
320 | /** |
||
321 | * @param QueryInterface $query |
||
322 | * @param string $toScenario |
||
323 | * @return Object[] |
||
324 | */ |
||
325 | View Code Duplication | public function findAllByQuery(QueryInterface $query, string $toScenario = null): array |
|
337 | |||
338 | /** |
||
339 | * @param QueryInterface $query |
||
340 | * @param string $toScenario |
||
341 | * @return Object|null |
||
342 | */ |
||
343 | View Code Duplication | public function findByQuery(QueryInterface $query, string $toScenario = null) |
|
354 | |||
355 | /******************************************* |
||
356 | * FIND/GET BY CONDITION |
||
357 | *******************************************/ |
||
358 | |||
359 | /** |
||
360 | * @param $condition |
||
361 | * @param string $toScenario |
||
362 | * @return Object[] |
||
363 | */ |
||
364 | View Code Duplication | public function findAllByCondition($condition, string $toScenario = null): array |
|
381 | |||
382 | /** |
||
383 | * @param $condition |
||
384 | * @param string $toScenario |
||
385 | * @return Object[] |
||
386 | * @throws ObjectNotFoundException |
||
387 | */ |
||
388 | public function getAllByCondition($condition, string $toScenario = null): array |
||
400 | |||
401 | /** |
||
402 | * @param $condition |
||
403 | * @param string $toScenario |
||
404 | * @return Object|null |
||
405 | */ |
||
406 | View Code Duplication | public function findByCondition($condition, string $toScenario = null) |
|
417 | |||
418 | /** |
||
419 | * @param $condition |
||
420 | * @param string $toScenario |
||
421 | * @return Object |
||
422 | * @throws ObjectNotFoundException |
||
423 | */ |
||
424 | public function getByCondition($condition, string $toScenario = null): Object |
||
436 | |||
437 | /******************************************* |
||
438 | * FIND/GET BY CRITERIA |
||
439 | *******************************************/ |
||
440 | |||
441 | /** |
||
442 | * @param $criteria |
||
443 | * @param string $toScenario |
||
444 | * @return Object[] |
||
445 | */ |
||
446 | View Code Duplication | public function findAllByCriteria($criteria, string $toScenario = null): array |
|
464 | |||
465 | /** |
||
466 | * @param $criteria |
||
467 | * @param string $toScenario |
||
468 | * @return Object[] |
||
469 | * @throws ObjectNotFoundException |
||
470 | */ |
||
471 | public function getAllByCriteria($criteria, string $toScenario = null): array |
||
483 | |||
484 | /** |
||
485 | * @param $criteria |
||
486 | * @param string $toScenario |
||
487 | * @return Object|null |
||
488 | */ |
||
489 | View Code Duplication | public function findByCriteria($criteria, string $toScenario = null) |
|
500 | |||
501 | /** |
||
502 | * @param $criteria |
||
503 | * @param string $toScenario |
||
504 | * @return Object |
||
505 | * @throws ObjectNotFoundException |
||
506 | */ |
||
507 | public function getByCriteria($criteria, string $toScenario = null): Object |
||
519 | |||
520 | |||
521 | /******************************************* |
||
522 | * FIND/GET BY RECORD |
||
523 | *******************************************/ |
||
524 | |||
525 | /** |
||
526 | * @param Record $record |
||
527 | * @param string $toScenario |
||
528 | * @return Object |
||
529 | */ |
||
530 | View Code Duplication | public function findByRecord(Record $record, string $toScenario = null): Object |
|
547 | |||
548 | /** |
||
549 | * @param Record $record |
||
550 | * @param string $toScenario |
||
551 | * @return Object |
||
552 | */ |
||
553 | public function getByRecord(Record $record, string $toScenario = null): Object |
||
557 | |||
558 | |||
559 | /******************************************* |
||
560 | * CACHE |
||
561 | *******************************************/ |
||
562 | |||
563 | /** |
||
564 | * @param $identifier |
||
565 | * @return Object|null |
||
566 | */ |
||
567 | View Code Duplication | public function findCache($identifier) |
|
583 | |||
584 | /** |
||
585 | * Find an existing cache by ID |
||
586 | * |
||
587 | * @param $id |
||
588 | * @return Object|null |
||
589 | */ |
||
590 | public function findCacheById(int $id) |
||
603 | |||
604 | /** |
||
605 | * Identify whether in cache by ID |
||
606 | * |
||
607 | * @param $id |
||
608 | * @return bool |
||
609 | */ |
||
610 | protected function isCachedById(int $id) |
||
614 | |||
615 | /** |
||
616 | * @param Object $object |
||
617 | * @return $this |
||
618 | */ |
||
619 | protected function cacheById(Object $object) |
||
633 | |||
634 | /** |
||
635 | * @param Record $record |
||
636 | * @return Object|null |
||
637 | */ |
||
638 | public function findCacheByRecord(Record $record) |
||
650 | |||
651 | /** |
||
652 | * @param Object $object |
||
653 | * @return static |
||
654 | */ |
||
655 | public function addToCache(Object $object) |
||
662 | |||
663 | |||
664 | /******************************************* |
||
665 | * EXCEPTIONS |
||
666 | *******************************************/ |
||
667 | |||
668 | /** |
||
669 | * @throws ObjectNotFoundException |
||
670 | */ |
||
671 | protected function notFoundException() |
||
681 | |||
682 | /** |
||
683 | * @param int|null $id |
||
684 | * @throws ObjectNotFoundException |
||
685 | */ |
||
686 | protected function notFoundByIdException(int $id = null) |
||
697 | |||
698 | /** |
||
699 | * @param null $criteria |
||
700 | * @throws ObjectNotFoundException |
||
701 | */ |
||
702 | protected function notFoundByCriteriaException($criteria = null) |
||
713 | |||
714 | /** |
||
715 | * @param null $condition |
||
716 | * @throws ObjectNotFoundException |
||
717 | */ |
||
718 | protected function notFoundByConditionException($condition = null) |
||
729 | |||
730 | } |
||
731 |