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 ExtcalPersistableObjectHandler 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 ExtcalPersistableObjectHandler, and based on these observations, apply Extract Interface, too.
1 | <?php namespace XoopsModules\Extcal; |
||
28 | * @copyright copyright (c) 2000-2004 XOOPS.org |
||
29 | */ |
||
30 | class ExtcalPersistableObjectHandler extends \XoopsPersistableObjectHandler //XoopsObjectHandler |
||
31 | { |
||
32 | /**#@+ |
||
33 | * Information about the class, the handler is managing |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | // public $table; |
||
38 | // public $keyName; |
||
39 | // public $className; |
||
40 | // public $identifierName; |
||
41 | |||
42 | /**#@-*/ |
||
43 | |||
44 | /** |
||
45 | * Constructor - called from child classes. |
||
46 | * |
||
47 | * @param XoopsDatabase $db {@link XoopsDatabase} object |
||
|
|||
48 | * @param string $tablename Name of database table |
||
49 | * @param string $classname Name of Class, this handler is managing |
||
50 | * @param string $keyname Name of the property, holding the key |
||
51 | * @param bool $idenfierName |
||
52 | */ |
||
53 | public function __construct(\XoopsDatabase $db, $tablename, $classname, $keyname, $idenfierName = false) |
||
63 | |||
64 | /** |
||
65 | * Constructor. |
||
66 | */ |
||
67 | // public function ExtcalPersistableObjectHandler($db, $tablename, $classname, $keyname, $idenfierName = false) |
||
68 | // { |
||
69 | // $this->__construct($db, $tablename, $classname, $keyname, $idenfierName); |
||
70 | // } |
||
71 | |||
72 | /** |
||
73 | * create a new user. |
||
74 | * |
||
75 | * @param bool $isNew Flag the new objects as "new"? |
||
76 | * |
||
77 | * @return \XoopsObject |
||
78 | */ |
||
79 | public function create($isNew = true) |
||
88 | |||
89 | /** |
||
90 | * retrieve an object. |
||
91 | * |
||
92 | * @param mixed $id ID of the object - or array of ids for joint keys. Joint keys MUST be given in the same order as in the constructor |
||
93 | * @param null $fields |
||
94 | * @param bool $as_object |
||
95 | * |
||
96 | * @return mixed reference to the object, FALSE if failed |
||
97 | * |
||
98 | * @internal param bool $asObject whether to return an object or an array |
||
99 | */ |
||
100 | public function get($id = null, $fields = null, $as_object = true) //get($id, $as_object = true) |
||
118 | |||
119 | /** |
||
120 | * retrieve objects from the database. |
||
121 | * |
||
122 | * @param \CriteriaElement $criteria {@link CriteriaElement} conditions to be met |
||
123 | * @param bool $idAsKey use the ID as key for the array? |
||
124 | * @param bool $asObject return an array of objects? |
||
125 | * |
||
126 | * @return array |
||
127 | */ |
||
128 | public function &getObjects(\CriteriaElement $criteria = null, $idAsKey = false, $asObject = true) |
||
150 | |||
151 | /** |
||
152 | * Convert a database resultset to a returnable array. |
||
153 | * |
||
154 | * @param XoopsObject $result database resultset |
||
155 | * @param bool $idAsKey - should NOT be used with joint keys |
||
156 | * @param bool $asObject |
||
157 | * |
||
158 | * @return array |
||
159 | */ |
||
160 | public function convertResultSet($result, $idAsKey = false, $asObject = true) |
||
194 | |||
195 | /** |
||
196 | * Retrieve a list of objects as arrays - DON'T USE WITH JOINT KEYS. |
||
197 | * |
||
198 | * @param \CriteriaElement $criteria {@link CriteriaElement} conditions to be met |
||
199 | * @param int $limit Max number of objects to fetch |
||
200 | * @param int $start Which record to start at |
||
201 | * |
||
202 | * @return array |
||
203 | */ |
||
204 | public function getList(\CriteriaElement $criteria = null, $limit = 0, $start = 0) |
||
241 | |||
242 | /** |
||
243 | * count objects matching a condition. |
||
244 | * |
||
245 | * @param \CriteriaElement $criteria {@link CriteriaElement} to match |
||
246 | * |
||
247 | * @return int|array count of objects |
||
248 | */ |
||
249 | View Code Duplication | public function getCount(\CriteriaElement $criteria = null) |
|
283 | |||
284 | /** |
||
285 | * delete an object from the database by id. |
||
286 | * |
||
287 | * @param mixed $id id of the object to delete |
||
288 | * @param bool $force |
||
289 | * |
||
290 | * @return bool FALSE if failed. |
||
291 | */ |
||
292 | public function deleteById($id, $force = false) //delete(\XoopsObject $object, $force = false) |
||
315 | |||
316 | /** |
||
317 | * insert a new object in the database. |
||
318 | * |
||
319 | * @param XoopsObject $obj reference to the object |
||
320 | * @param bool $force whether to force the query execution despite security settings |
||
321 | * @param bool $checkObject check if the object is dirty and clean the attributes |
||
322 | * |
||
323 | * @return bool FALSE if failed, TRUE if already present and unchanged or successful |
||
324 | */ |
||
325 | public function insert(\XoopsObject $obj, $force = false, $checkObject = true) |
||
400 | |||
401 | /** |
||
402 | * Change a value for objects with a certain criteria. |
||
403 | * |
||
404 | * @param string $fieldname Name of the field |
||
405 | * @param string|array $fieldvalue Value to write |
||
406 | * @param CriteriaElement $criteria {@link CriteriaElement} |
||
407 | * @param bool $force |
||
408 | * |
||
409 | * @return bool |
||
410 | */ |
||
411 | public function updateAll($fieldname, $fieldvalue, \CriteriaElement $criteria = null, $force = false) |
||
436 | |||
437 | /** |
||
438 | * @param $fieldname |
||
439 | * @param $fieldvalue |
||
440 | * @param null $criteria |
||
441 | * @param bool $force |
||
442 | * |
||
443 | * @return bool |
||
444 | */ |
||
445 | public function updateFieldValue($fieldname, $fieldvalue, $criteria = null, $force = true) |
||
462 | |||
463 | /** |
||
464 | * delete all objects meeting the conditions. |
||
465 | * |
||
466 | * @param CriteriaElement $criteria {@link CriteriaElement} |
||
467 | * with conditions to meet |
||
468 | * @param bool $force |
||
469 | * @param bool $asObject |
||
470 | * |
||
471 | * @return bool |
||
472 | */ |
||
473 | public function deleteAll(\CriteriaElement $criteria = null, $force = true, $asObject = false) |
||
488 | |||
489 | /** |
||
490 | * @param $data |
||
491 | * |
||
492 | * @return array |
||
493 | */ |
||
494 | public function _toObject($data) |
||
512 | |||
513 | /** |
||
514 | * @param $objects |
||
515 | * @param array $externalKeys |
||
516 | * @param string $format |
||
517 | * |
||
518 | * @return array |
||
519 | */ |
||
520 | public function objectToArray($objects, $externalKeys = [], $format = 's') |
||
582 | |||
583 | /** |
||
584 | * @param $object |
||
585 | * @param string $format |
||
586 | * |
||
587 | * @return array |
||
588 | */ |
||
589 | public function objectToArrayWithoutExternalKey($object, $format = 's') |
||
601 | |||
602 | /** |
||
603 | * @param $fieldname |
||
604 | * @param $criteria |
||
605 | * @param string $op |
||
606 | * |
||
607 | * @return bool |
||
608 | */ |
||
609 | public function updateCounter($fieldname, $criteria, $op = '+') |
||
620 | |||
621 | /** |
||
622 | * @param null|CriteriaElement $criteria |
||
623 | * @param string $sum |
||
624 | * |
||
625 | * @return array|string |
||
626 | */ |
||
627 | View Code Duplication | public function getSum(\CriteriaElement $criteria = null, $sum = '*') |
|
661 | |||
662 | /** |
||
663 | * @param null|CriteriaElement $criteria |
||
664 | * @param string $max |
||
665 | * |
||
666 | * @return array|string |
||
667 | */ |
||
668 | View Code Duplication | public function getMax(\CriteriaElement $criteria = null, $max = '*') |
|
702 | |||
703 | /** |
||
704 | * @param null $criteria |
||
705 | * @param string $avg |
||
706 | * |
||
707 | * @return int |
||
708 | */ |
||
709 | public function getAvg($criteria = null, $avg = '*') |
||
725 | |||
726 | /** |
||
727 | * @return mixed |
||
728 | */ |
||
729 | public function getInsertId() |
||
730 | { |
||
731 | return $this->db->getInsertId(); |
||
732 | } |
||
734 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.