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 Localize 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 Localize, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
34 | class Localize extends \Tight\Modules\AbstractModule |
||
35 | { |
||
36 | |||
37 | /** |
||
38 | * @var string Resource file type |
||
39 | */ |
||
40 | private $resourceFileType; |
||
41 | |||
42 | /** |
||
43 | * @var string Current locale |
||
44 | */ |
||
45 | private $locale; |
||
46 | |||
47 | /** |
||
48 | * @var array Associative array for the current locale |
||
49 | */ |
||
50 | private $values; |
||
51 | |||
52 | /** |
||
53 | * Constructor |
||
54 | * |
||
55 | * @param array|\Tight\Modules\Localize\LocalizeConfig $config |
||
56 | * @throws \InvalidArgumentException If $config is not an array or an object |
||
57 | * of \Tight\Modules\Localize\LocalizeConfig class |
||
58 | */ |
||
59 | public function __construct($config = []) { |
||
71 | |||
72 | /** |
||
73 | * Sets the resource file type |
||
74 | * @param string $resourceFileType Resource file type |
||
75 | * @return \Tight\Modules\Localize\Localize Fluent setter |
||
76 | */ |
||
77 | public function setResourceFileType($resourceFileType) { |
||
82 | |||
83 | /** |
||
84 | * Gets the current resource file type |
||
85 | * @return string Resource file type |
||
86 | * @see \Tight\Modules\Localize\LocalizeConfig::FILETYPE_INI |
||
87 | * @see \Tight\Modules\Localize\LocalizeConfig::FILETYPE_JSON |
||
88 | * @see \Tight\Modules\Localize\LocalizeConfig::FILETYPE_XML |
||
89 | */ |
||
90 | public function getResourceFileType() { |
||
93 | |||
94 | /** |
||
95 | * Gets all the defined values for the current locale |
||
96 | * @return array Associative array of values |
||
97 | */ |
||
98 | public function getValues() { |
||
101 | |||
102 | /** |
||
103 | * Reloads the class with the new locale |
||
104 | */ |
||
105 | public function reloadConfig() { |
||
120 | |||
121 | /** |
||
122 | * Checks the dependences for the class |
||
123 | * @throws \Tight\Exception\ModuleException If resource directory cant be |
||
124 | * found |
||
125 | */ |
||
126 | private function checkDependences() { |
||
131 | |||
132 | /** |
||
133 | * Sets a new locale |
||
134 | * @param string $locale New defined locale |
||
135 | * @throws \Tight\Exception\ModuleException If resource default resource file |
||
136 | * cant be found |
||
137 | */ |
||
138 | public function setLocale($locale) { |
||
142 | |||
143 | /** |
||
144 | * Gets the available locales |
||
145 | * @return array Available locales |
||
146 | */ |
||
147 | public function getLocales() { |
||
161 | |||
162 | private function getLocalesFromJson() { |
||
189 | |||
190 | /** |
||
191 | * Gets the json values from the json file |
||
192 | * @return array String values |
||
193 | * @throws \Tight\Exception\ModuleException If json file cant be found |
||
194 | */ |
||
195 | private function getValuesFromJson() { |
||
213 | |||
214 | /** |
||
215 | * Gets the locales from the xml resource file |
||
216 | * @return array Array of locales |
||
217 | */ |
||
218 | private function getLocalesFromXml() { |
||
227 | |||
228 | /** |
||
229 | * Gets the xml resource read from the xml resource file |
||
230 | * @return \SimpleXMLElement XML values for the current locale |
||
1 ignored issue
–
show
|
|||
231 | * @throws \Tight\Exception\ModuleException If xml values resource file cant be found |
||
232 | */ |
||
233 | private function getXmlResources() { |
||
246 | |||
247 | /** |
||
248 | * Gets the values from xml resource file |
||
249 | * @return array Array of values |
||
250 | * @throws \Tight\Exception\ModuleException If the current locale cant be |
||
251 | * found in the xml resource file |
||
252 | */ |
||
253 | private function getValuesFromXml() { |
||
271 | |||
272 | /** |
||
273 | * Parses a \SimpleXmlElement object to get its values |
||
274 | * @param \SimpleXMLElement $xml XML object |
||
275 | * @return array Values |
||
276 | */ |
||
277 | private function parseXmlStringValues(\SimpleXMLElement $xml) { |
||
300 | |||
301 | /** |
||
302 | * Gets a value from a defined key |
||
303 | * @param string $key Key |
||
304 | * @return string Value defined for the key $key or an empty string if the |
||
305 | * key is not defined |
||
306 | */ |
||
307 | public function get($key) { |
||
314 | |||
315 | public function onConfigChange() { |
||
318 | |||
319 | public function onLoad() { |
||
322 | |||
323 | public function onRemove() { |
||
326 | |||
327 | } |
||
328 |
Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.
To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.
The function can be called with either null or an array for the parameter
$needle
but will only accept an array as$haystack
.