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 SQLAnywhereStatement 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 SQLAnywhereStatement, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
42 | class SQLAnywhereStatement implements IteratorAggregate, Statement |
||
43 | { |
||
44 | /** @var resource The connection resource. */ |
||
45 | private $conn; |
||
46 | |||
47 | /** @var string Name of the default class to instantiate when fetching class instances. */ |
||
48 | private $defaultFetchClass = '\stdClass'; |
||
49 | |||
50 | /** @var mixed[] Constructor arguments for the default class to instantiate when fetching class instances. */ |
||
51 | private $defaultFetchClassCtorArgs = []; |
||
52 | |||
53 | /** @var int Default fetch mode to use. */ |
||
54 | private $defaultFetchMode = FetchMode::MIXED; |
||
55 | |||
56 | /** @var resource The result set resource to fetch. */ |
||
57 | private $result; |
||
58 | |||
59 | /** @var resource The prepared SQL statement to execute. */ |
||
60 | private $stmt; |
||
61 | |||
62 | /** @var mixed[] The references to bound parameter values. */ |
||
63 | private $boundValues = []; |
||
64 | |||
65 | /** |
||
66 | * Prepares given statement for given connection. |
||
67 | * |
||
68 | * @param resource $conn The connection resource to use. |
||
69 | * @param string $sql The SQL statement to prepare. |
||
70 | * |
||
71 | * @throws SQLAnywhereException |
||
72 | */ |
||
73 | public function __construct($conn, $sql) |
||
86 | |||
87 | /** |
||
88 | * {@inheritdoc} |
||
89 | * |
||
90 | * @throws SQLAnywhereException |
||
91 | */ |
||
92 | public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) |
||
122 | |||
123 | /** |
||
124 | * {@inheritdoc} |
||
125 | */ |
||
126 | public function bindValue($param, $value, $type = ParameterType::STRING) |
||
130 | |||
131 | /** |
||
132 | * {@inheritdoc} |
||
133 | * |
||
134 | * @throws SQLAnywhereException |
||
135 | */ |
||
136 | public function closeCursor() |
||
144 | |||
145 | /** |
||
146 | * {@inheritdoc} |
||
147 | */ |
||
148 | public function columnCount() |
||
152 | |||
153 | /** |
||
154 | * {@inheritdoc} |
||
155 | */ |
||
156 | public function errorCode() |
||
160 | |||
161 | /** |
||
162 | * {@inheritdoc} |
||
163 | */ |
||
164 | public function errorInfo() |
||
168 | |||
169 | /** |
||
170 | * {@inheritdoc} |
||
171 | * |
||
172 | * @throws SQLAnywhereException |
||
173 | */ |
||
174 | public function execute($params = null) |
||
196 | |||
197 | /** |
||
198 | * {@inheritdoc} |
||
199 | * |
||
200 | * @throws SQLAnywhereException |
||
201 | */ |
||
202 | public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) |
||
248 | |||
249 | /** |
||
250 | * {@inheritdoc} |
||
251 | */ |
||
252 | public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) |
||
279 | |||
280 | /** |
||
281 | * {@inheritdoc} |
||
282 | */ |
||
283 | View Code Duplication | public function fetchColumn($columnIndex = 0) |
|
293 | |||
294 | /** |
||
295 | * {@inheritdoc} |
||
296 | */ |
||
297 | 2 | public function getIterator() |
|
301 | |||
302 | /** |
||
303 | * {@inheritdoc} |
||
304 | */ |
||
305 | public function rowCount() |
||
309 | |||
310 | /** |
||
311 | * {@inheritdoc} |
||
312 | */ |
||
313 | public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) |
||
321 | |||
322 | /** |
||
323 | * Casts a stdClass object to the given class name mapping its' properties. |
||
324 | * |
||
325 | * @param stdClass $sourceObject Object to cast from. |
||
326 | * @param string|object $destinationClass Name of the class or class instance to cast to. |
||
327 | * @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance. |
||
328 | * |
||
329 | * @return object |
||
330 | * |
||
331 | * @throws SQLAnywhereException |
||
332 | */ |
||
333 | private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) |
||
368 | } |
||
369 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.