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 AdjectiveDeclension 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 AdjectiveDeclension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
19 | class AdjectiveDeclension extends BaseInflection implements Cases, Gender |
||
20 | { |
||
21 | use RussianLanguage, CasesHelper; |
||
22 | |||
23 | const HARD_BASE = 1; |
||
24 | const SOFT_BASE = 2; |
||
25 | const MIXED_BASE = 3; |
||
26 | |||
27 | /** |
||
28 | * @param string $adjective |
||
29 | * @return bool|void |
||
30 | */ |
||
31 | public static function isMutable($adjective) |
||
35 | |||
36 | /** |
||
37 | * @param string $adjective |
||
38 | * @param string $case |
||
39 | * @param bool $animateness |
||
40 | * @param null $gender |
||
41 | * |
||
42 | * @return string |
||
43 | * @throws \Exception |
||
44 | */ |
||
45 | public static function getCase($adjective, $case, $animateness = false, $gender = null) |
||
55 | |||
56 | /** |
||
57 | * @param string $adjective |
||
58 | * |
||
59 | * @param bool $isEmphasized |
||
60 | * |
||
61 | * @return string |
||
62 | */ |
||
63 | 24 | public static function detectGender($adjective, &$isEmphasized = false) |
|
84 | |||
85 | /** |
||
86 | * @param string $adjective |
||
87 | * @param bool $animateness |
||
88 | * @param null|string $gender |
||
89 | * |
||
90 | * @return string[] |
||
91 | * @phpstan-return array<string, string> |
||
92 | */ |
||
93 | 18 | public static function getCases($adjective, $animateness = false, $gender = null) |
|
119 | |||
120 | /** |
||
121 | * @param string $adjective |
||
122 | * |
||
123 | * @return int |
||
124 | */ |
||
125 | 25 | public static function getAdjectiveBaseType($adjective) |
|
149 | |||
150 | /** |
||
151 | * @param string $adjective |
||
152 | * @param bool $animateness |
||
153 | * @param string $gender |
||
154 | * @param string $afterConsonantVowel |
||
155 | * |
||
156 | * @return string[] |
||
157 | * @phpstan-return array<string, string> |
||
158 | */ |
||
159 | 6 | View Code Duplication | protected static function declinateHardAdjective($adjective, $animateness, $gender, |
195 | |||
196 | /** |
||
197 | * @param string $adjective |
||
198 | * @param bool $animateness |
||
199 | * @param string $gender |
||
200 | * @param string $afterConsonantVowel |
||
201 | * |
||
202 | * @return string[] |
||
203 | * @phpstan-return array<string, string> |
||
204 | */ |
||
205 | 3 | View Code Duplication | protected static function declinateSoftAdjective($adjective, $animateness, $gender, $afterConsonantVowel) |
240 | |||
241 | /** |
||
242 | * @param string $adjective |
||
243 | * @param bool $animateness |
||
244 | * @param string $gender |
||
245 | * @param string $afterConsonantVowel |
||
246 | * |
||
247 | * @return string[] |
||
248 | * @phpstan-return array<string, string> |
||
249 | */ |
||
250 | 9 | protected static function declinateMixedAdjective($adjective, $animateness, $gender, $afterConsonantVowel) |
|
287 | } |
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.