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
Idable
provides a methodequalsId
that 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.