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 |
||
| 21 | trait BlogObject |
||
| 22 | { |
||
| 23 | /** |
||
| 24 | * @return ManyManyList|BlogPost[] |
||
| 25 | */ |
||
| 26 | public function BlogPosts() |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Get blog this tag was queried from |
||
| 37 | * |
||
| 38 | * @return Blog|null |
||
| 39 | */ |
||
| 40 | public function Blog() |
||
| 50 | |||
| 51 | /** |
||
| 52 | * {@inheritdoc} |
||
| 53 | */ |
||
| 54 | public function getCMSFields() |
||
| 69 | |||
| 70 | /** |
||
| 71 | * Number of times this object has blog posts in the current blog |
||
| 72 | * |
||
| 73 | * @return int |
||
| 74 | */ |
||
| 75 | public function getBlogCount() |
||
| 87 | |||
| 88 | /** |
||
| 89 | * {@inheritdoc} |
||
| 90 | * @return ValidationResult |
||
| 91 | */ |
||
| 92 | public function validate() |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Returns a relative link to this category or tag |
||
| 109 | * |
||
| 110 | * @return string |
||
| 111 | */ |
||
| 112 | public function getLink() |
||
| 124 | |||
| 125 | /** |
||
| 126 | * Inherits from the parent blog or can be overwritten using a DataExtension. |
||
| 127 | * |
||
| 128 | * @param null|Member $member |
||
| 129 | * |
||
| 130 | * @return bool |
||
| 131 | */ |
||
| 132 | View Code Duplication | public function canView($member = null) |
|
| 143 | |||
| 144 | /** |
||
| 145 | * {@inheritdoc} |
||
| 146 | */ |
||
| 147 | public function canCreate($member = null, $context = []) |
||
| 159 | |||
| 160 | /** |
||
| 161 | * Inherits from the parent blog or can be overwritten using a DataExtension. |
||
| 162 | * |
||
| 163 | * @param null|Member $member |
||
| 164 | * |
||
| 165 | * @return bool |
||
| 166 | */ |
||
| 167 | View Code Duplication | public function canDelete($member = null) |
|
| 178 | |||
| 179 | /** |
||
| 180 | * Inherits from the parent blog or can be overwritten using a DataExtension. |
||
| 181 | * |
||
| 182 | * @param null|Member $member |
||
| 183 | * |
||
| 184 | * @return bool |
||
| 185 | */ |
||
| 186 | View Code Duplication | public function canEdit($member = null) |
|
| 197 | |||
| 198 | /** |
||
| 199 | * @return mixed |
||
| 200 | */ |
||
| 201 | public function getBlogID() |
||
| 205 | |||
| 206 | /** |
||
| 207 | * Set a blog ID for this record |
||
| 208 | * |
||
| 209 | * @param int $id |
||
| 210 | * @return $this |
||
| 211 | */ |
||
| 212 | public function setBlogID($id) |
||
| 217 | |||
| 218 | protected function onBeforeWrite() |
||
| 226 | |||
| 227 | /** |
||
| 228 | * Generates a unique URLSegment from the title. |
||
| 229 | * |
||
| 230 | * @param int $increment |
||
| 231 | * |
||
| 232 | * @return string |
||
| 233 | */ |
||
| 234 | public function generateURLSegment($increment = 0) |
||
| 257 | |||
| 258 | /** |
||
| 259 | * Looks for objects o the same type and the same value by the given Field |
||
| 260 | * |
||
| 261 | * @param string $field E.g. URLSegment or Title |
||
| 262 | * @return DataList |
||
| 263 | */ |
||
| 264 | protected function getDuplicatesByField($field) |
||
| 275 | |||
| 276 | /** |
||
| 277 | * This returns the url segment for the listing page. |
||
| 278 | * eg. 'categories' in /my-blog/categories/category-url |
||
| 279 | * |
||
| 280 | * This is not editable at the moment, but a method is being used incase we want |
||
| 281 | * to make it editable in the future. We can use this method to provide logic |
||
| 282 | * without replacing multiple areas of the code base. We're also not being opinionated |
||
| 283 | * about how the segment should be obtained at the moment and allowing for the |
||
| 284 | * implementation to decide. |
||
| 285 | * |
||
| 286 | * @return string |
||
| 287 | */ |
||
| 288 | abstract protected function getListUrlSegment(); |
||
| 289 | |||
| 290 | /** |
||
| 291 | * Returns an error message for this object when it tries to write a duplicate. |
||
| 292 | * |
||
| 293 | * @return string |
||
| 294 | */ |
||
| 295 | abstract protected function getDuplicateError(); |
||
| 296 | } |
||
| 297 |
This check looks for methods that are used by a trait but not required by it.
To illustrate, let’s look at the following code example
The trait
Idableprovides a methodequalsIdthat in turn relies on the methodgetId(). If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()as an abstract method to the trait will make sure it is available.