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:
1 | <?php |
||
53 | class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver { |
||
54 | |||
55 | /** |
||
56 | * Sub-driver |
||
57 | * |
||
58 | * @var string |
||
59 | */ |
||
60 | public $subdriver = 'oci'; |
||
61 | |||
62 | // -------------------------------------------------------------------- |
||
63 | |||
64 | /** |
||
65 | * List of reserved identifiers |
||
66 | * |
||
67 | * Identifiers that must NOT be escaped. |
||
68 | * |
||
69 | * @var string[] |
||
70 | */ |
||
71 | protected $_reserved_identifiers = array('*', 'rownum'); |
||
72 | |||
73 | /** |
||
74 | * ORDER BY random keyword |
||
75 | * |
||
76 | * @var array |
||
77 | */ |
||
78 | protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported |
||
79 | |||
80 | /** |
||
81 | * COUNT string |
||
82 | * |
||
83 | * @used-by CI_DB_driver::count_all() |
||
84 | * @used-by CI_DB_query_builder::count_all_results() |
||
85 | * |
||
86 | * @var string |
||
87 | */ |
||
88 | protected $_count_string = 'SELECT COUNT(1) AS '; |
||
89 | |||
90 | // -------------------------------------------------------------------- |
||
91 | |||
92 | /** |
||
93 | * Class constructor |
||
94 | * |
||
95 | * Builds the DSN if not already set. |
||
96 | * |
||
97 | * @param array $params |
||
98 | * @return void |
||
99 | */ |
||
100 | public function __construct($params) |
||
129 | |||
130 | // -------------------------------------------------------------------- |
||
131 | |||
132 | /** |
||
133 | * Database version number |
||
134 | * |
||
135 | * @return string |
||
136 | */ |
||
137 | public function version() |
||
152 | |||
153 | // -------------------------------------------------------------------- |
||
154 | |||
155 | /** |
||
156 | * Show table query |
||
157 | * |
||
158 | * Generates a platform-specific query string so that the table names can be fetched |
||
159 | * |
||
160 | * @param bool $prefix_limit |
||
161 | * @return string |
||
162 | */ |
||
163 | View Code Duplication | protected function _list_tables($prefix_limit = FALSE) |
|
175 | |||
176 | // -------------------------------------------------------------------- |
||
177 | |||
178 | /** |
||
179 | * Show column query |
||
180 | * |
||
181 | * Generates a platform-specific query string so that the column names can be fetched |
||
182 | * |
||
183 | * @param string $table |
||
184 | * @return string |
||
185 | */ |
||
186 | View Code Duplication | protected function _list_columns($table = '') |
|
201 | |||
202 | // -------------------------------------------------------------------- |
||
203 | |||
204 | /** |
||
205 | * Returns an object with field data |
||
206 | * |
||
207 | * @param string $table |
||
208 | * @return array |
||
209 | */ |
||
210 | View Code Duplication | public function field_data($table) |
|
257 | |||
258 | // -------------------------------------------------------------------- |
||
259 | |||
260 | /** |
||
261 | * Insert batch statement |
||
262 | * |
||
263 | * @param string $table Table name |
||
264 | * @param array $keys INSERT keys |
||
265 | * @param array $values INSERT values |
||
266 | * @return string |
||
267 | */ |
||
268 | View Code Duplication | protected function _insert_batch($table, $keys, $values) |
|
280 | |||
281 | // -------------------------------------------------------------------- |
||
282 | |||
283 | /** |
||
284 | * Delete statement |
||
285 | * |
||
286 | * Generates a platform-specific delete string from the supplied data |
||
287 | * |
||
288 | * @param string $table |
||
289 | * @return string |
||
290 | */ |
||
291 | View Code Duplication | protected function _delete($table) |
|
301 | |||
302 | // -------------------------------------------------------------------- |
||
303 | |||
304 | /** |
||
305 | * LIMIT |
||
306 | * |
||
307 | * Generates a platform-specific LIMIT clause |
||
308 | * |
||
309 | * @param string $sql SQL Query |
||
310 | * @return string |
||
311 | */ |
||
312 | protected function _limit($sql) |
||
317 | |||
318 | } |
||
319 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.