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_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.