Complex classes like Base 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 Base, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | abstract class Base |
||
9 | { |
||
10 | /** |
||
11 | * @var array |
||
12 | */ |
||
13 | protected $args; |
||
14 | |||
15 | /** |
||
16 | * @var array |
||
17 | */ |
||
18 | protected $dependencies = []; |
||
19 | |||
20 | /** |
||
21 | * Whether the field has multiple values |
||
22 | * |
||
23 | * @var bool |
||
24 | */ |
||
25 | protected $multi = false; |
||
26 | |||
27 | /** |
||
28 | * Whether the field is rendered outside of the form table |
||
29 | * |
||
30 | * @var bool |
||
31 | */ |
||
32 | protected $outside = false; |
||
33 | |||
34 | /** |
||
35 | * The field element tag (i.e. "input") |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | protected $element; |
||
40 | |||
41 | public function __construct( array $args = [] ) |
||
45 | |||
46 | /** |
||
47 | * @param string $property |
||
48 | * |
||
49 | * @return mixed |
||
50 | * @throws Exception |
||
51 | */ |
||
52 | public function __get( $property ) |
||
65 | |||
66 | /** |
||
67 | * Generate the field description |
||
68 | * |
||
69 | * @param bool $paragraph |
||
70 | * |
||
71 | * @return null|string |
||
72 | */ |
||
73 | public function generateDescription( $paragraph = true ) |
||
81 | |||
82 | /** |
||
83 | * Generate the field label |
||
84 | * |
||
85 | * @return null|string |
||
86 | */ |
||
87 | public function generateLabel() |
||
97 | |||
98 | /** |
||
99 | * Render this field type |
||
100 | * |
||
101 | * @return string |
||
102 | */ |
||
103 | abstract public function render(); |
||
104 | |||
105 | /** |
||
106 | * Convert a value to camel case. |
||
107 | * |
||
108 | * @param string $value |
||
109 | * |
||
110 | * @return string |
||
111 | */ |
||
112 | protected function camelCase( $value ) |
||
118 | |||
119 | /** |
||
120 | * Implode the field attributes |
||
121 | * |
||
122 | * @return array |
||
123 | */ |
||
124 | protected function implodeAttributes( $defaults = [] ) |
||
128 | |||
129 | /** |
||
130 | * Implode multi-field items |
||
131 | * |
||
132 | * @return null|string |
||
133 | */ |
||
134 | protected function implodeOptions( $method = 'select_option', $default = null ) |
||
163 | |||
164 | /** |
||
165 | * Normalize attributes for this specific field type |
||
166 | * |
||
167 | * @param bool|string $implode |
||
168 | * |
||
169 | * @return array |
||
170 | */ |
||
171 | protected function normalize( array $defaults = [], $implode = false ) |
||
181 | |||
182 | /** |
||
183 | * Merge and overwrite empty $this->args values with $defaults |
||
184 | * |
||
185 | * @return array |
||
186 | */ |
||
187 | protected function mergeAttributesWith( array $defaults ) |
||
200 | |||
201 | /** |
||
202 | * Generate checkboxes and radios |
||
203 | * |
||
204 | * @param string $optionKey |
||
205 | * @param string $number |
||
206 | * @param string $type |
||
207 | * |
||
208 | * @return null|string |
||
209 | */ |
||
210 | protected function multiInput( $optionKey, $number, $type = 'radio' ) |
||
229 | |||
230 | /** |
||
231 | * Build the checkbox/radio args |
||
232 | * |
||
233 | * @param string $type |
||
234 | * @param string $optionName |
||
235 | * @param string $number |
||
236 | * |
||
237 | * @return array|null |
||
238 | */ |
||
239 | protected function multiInputArgs( $type, $optionName, $number ) |
||
292 | |||
293 | /** |
||
294 | * Generate checkboxes |
||
295 | * |
||
296 | * @param string $optionKey |
||
297 | * @param string $number |
||
298 | * |
||
299 | * @return null|string |
||
300 | */ |
||
301 | protected function multiInputCheckbox( $optionKey, $number ) |
||
305 | |||
306 | /** |
||
307 | * Generate select options |
||
308 | * |
||
309 | * @param string $optionKey |
||
310 | * |
||
311 | * @return string |
||
312 | */ |
||
313 | protected function selectOption( $optionKey ) |
||
321 | |||
322 | /** |
||
323 | * Generate a single checkbox |
||
324 | * |
||
325 | * @param string $type |
||
326 | * |
||
327 | * @return null|string |
||
328 | */ |
||
329 | protected function singleInput( $type = 'checkbox' ) |
||
353 | } |
||
354 |
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next
break
.There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.