Complex classes like MenuItem 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 MenuItem, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Arcanedev\Menus\Entities; |
||
12 | class MenuItem implements MenuItemInterface |
||
13 | { |
||
14 | /* ------------------------------------------------------------------------------------------------ |
||
15 | | Properties |
||
16 | | ------------------------------------------------------------------------------------------------ |
||
17 | */ |
||
18 | /** |
||
19 | * Menu item type. |
||
20 | * |
||
21 | * @var string |
||
22 | */ |
||
23 | protected $type; |
||
24 | |||
25 | /** |
||
26 | * Menu item root status. |
||
27 | * |
||
28 | * @var bool |
||
29 | */ |
||
30 | protected $root = false; |
||
31 | |||
32 | /** |
||
33 | * Menu item properties. |
||
34 | * |
||
35 | * @var array |
||
36 | */ |
||
37 | protected $properties; |
||
38 | |||
39 | /** |
||
40 | * Menu item attributes. |
||
41 | * |
||
42 | * @var MenuItemAttributes |
||
43 | */ |
||
44 | protected $attributes; |
||
45 | |||
46 | /** |
||
47 | * Menu item children. |
||
48 | * |
||
49 | * @var MenuItemCollection |
||
50 | */ |
||
51 | protected $children; |
||
52 | |||
53 | /* ------------------------------------------------------------------------------------------------ |
||
54 | | Constructor |
||
55 | | ------------------------------------------------------------------------------------------------ |
||
56 | */ |
||
57 | /** |
||
58 | * Make menu item instance. |
||
59 | * |
||
60 | * @param array $properties |
||
61 | */ |
||
62 | 115 | public function __construct(array $properties) |
|
67 | |||
68 | /* ------------------------------------------------------------------------------------------------ |
||
69 | | Getters & Setters |
||
70 | | ------------------------------------------------------------------------------------------------ |
||
71 | */ |
||
72 | /** |
||
73 | * Set the menu item type. |
||
74 | * |
||
75 | * @param array $properties |
||
76 | * |
||
77 | * @return self |
||
78 | */ |
||
79 | 115 | private function setType(array &$properties) |
|
89 | |||
90 | /** |
||
91 | * Set the menu item root status. |
||
92 | * |
||
93 | * @param array $properties |
||
94 | * |
||
95 | * @return self |
||
96 | */ |
||
97 | 115 | private function setRoot(array &$properties) |
|
103 | |||
104 | /** |
||
105 | * Get the menu item property. |
||
106 | * |
||
107 | * @param string $name |
||
108 | * @param mixed|null $default |
||
109 | * |
||
110 | * @return mixed |
||
111 | */ |
||
112 | 75 | public function getProperty($name, $default = null) |
|
116 | |||
117 | /** |
||
118 | * Set the item properties. |
||
119 | * |
||
120 | * @param array $properties |
||
121 | * |
||
122 | * @return self |
||
123 | */ |
||
124 | 115 | private function setProperties(array $properties) |
|
137 | |||
138 | /** |
||
139 | * Get the menu item attributes. |
||
140 | * |
||
141 | * @return \Arcanedev\Menus\Entities\MenuItemAttributes |
||
142 | */ |
||
143 | 65 | public function attributes() |
|
147 | |||
148 | /** |
||
149 | * Get all sub-items. |
||
150 | * |
||
151 | * @return \Arcanedev\Menus\Entities\MenuItemCollection |
||
152 | */ |
||
153 | 95 | public function children() |
|
157 | |||
158 | /** |
||
159 | * Get the menu item url. |
||
160 | */ |
||
161 | 60 | public function getUrl() |
|
165 | |||
166 | /** |
||
167 | * Get the menu item icon. |
||
168 | * |
||
169 | * @param string $tag |
||
170 | * |
||
171 | * @return string |
||
172 | */ |
||
173 | 40 | public function getIcon($tag = 'i') |
|
181 | |||
182 | /** |
||
183 | * Get the menu item content. |
||
184 | * |
||
185 | * @return string |
||
186 | */ |
||
187 | 45 | public function getContent() |
|
191 | |||
192 | /* ------------------------------------------------------------------------------------------------ |
||
193 | | Main Functions |
||
194 | | ------------------------------------------------------------------------------------------------ |
||
195 | */ |
||
196 | /** |
||
197 | * Make MenuItem instance. |
||
198 | * |
||
199 | * @param array $properties |
||
200 | * @param \Closure $callback |
||
201 | * |
||
202 | * @return \Arcanedev\Menus\Entities\MenuItem |
||
203 | */ |
||
204 | 110 | public static function make($properties, Closure $callback = null) |
|
214 | |||
215 | /** |
||
216 | * Fill the menu item properties. |
||
217 | * |
||
218 | * @param array $properties |
||
219 | * |
||
220 | * @return \Arcanedev\Menus\Entities\MenuItem |
||
221 | */ |
||
222 | 5 | public function fill(array $properties) |
|
228 | |||
229 | /** |
||
230 | * Add an url sub-item to the parent. |
||
231 | * |
||
232 | * @param string $url |
||
233 | * @param string $content |
||
234 | * @param array $attributes |
||
235 | */ |
||
236 | 20 | public function url($url, $content, array $attributes = []) |
|
240 | |||
241 | /** |
||
242 | * Add a route sub-item to the parent. |
||
243 | * |
||
244 | * @param string $route |
||
245 | * @param string $content |
||
246 | * @param array $parameters |
||
247 | * @param array $attributes |
||
248 | */ |
||
249 | 40 | public function route($route, $content, array $parameters = [], array $attributes = []) |
|
255 | |||
256 | /** |
||
257 | * Add an action sub-item to parent. |
||
258 | * |
||
259 | * @param string $action |
||
260 | * @param string $content |
||
261 | * @param array $parameters |
||
262 | * @param array $attributes |
||
263 | */ |
||
264 | 20 | public function action($action, $content, array $parameters = [], array $attributes = []) |
|
270 | |||
271 | /** |
||
272 | * Add a dropdown sub-item to the parent. |
||
273 | * |
||
274 | * @param string $content |
||
275 | * @param \Closure $callback |
||
276 | * @param array $attributes |
||
277 | */ |
||
278 | 20 | public function dropdown($content, Closure $callback, array $attributes = []) |
|
282 | |||
283 | /** |
||
284 | * Add a divider sub-item to the parent. |
||
285 | */ |
||
286 | 20 | public function divider() |
|
290 | |||
291 | /** |
||
292 | * Add a header item to the parent. |
||
293 | * |
||
294 | * @param string $content |
||
295 | */ |
||
296 | 20 | public function header($content) |
|
300 | |||
301 | /** |
||
302 | * Add an item to the parent. |
||
303 | * |
||
304 | * @param array $properties |
||
305 | * @param \Closure $callback |
||
306 | */ |
||
307 | 20 | public function add(array $properties, Closure $callback = null) |
|
311 | |||
312 | /* ------------------------------------------------------------------------------------------------ |
||
313 | | Check Functions |
||
314 | | ------------------------------------------------------------------------------------------------ |
||
315 | */ |
||
316 | /** |
||
317 | * Check if the menu item is root. |
||
318 | * |
||
319 | * @return bool |
||
320 | */ |
||
321 | 35 | public function isRoot() |
|
325 | |||
326 | /** |
||
327 | * Check if the menu item is a dropdown item. |
||
328 | * |
||
329 | * @return bool |
||
330 | */ |
||
331 | 5 | public function isDropdown() |
|
335 | |||
336 | /** |
||
337 | * Check if the menu item is a header. |
||
338 | * |
||
339 | * @return bool |
||
340 | */ |
||
341 | 5 | public function isHeader() |
|
345 | |||
346 | /** |
||
347 | * Check if menu item is a divider. |
||
348 | * |
||
349 | * @return bool |
||
350 | */ |
||
351 | 85 | public function isDivider() |
|
355 | |||
356 | /** |
||
357 | * Check if menu item is active. |
||
358 | * |
||
359 | * @return bool |
||
360 | */ |
||
361 | 75 | public function isActive() |
|
365 | |||
366 | /** |
||
367 | * Check if the menu item has sub-items. |
||
368 | * |
||
369 | * @return bool |
||
370 | */ |
||
371 | 90 | public function hasChildren() |
|
375 | |||
376 | /** |
||
377 | * Check the menu item type. |
||
378 | * |
||
379 | * @param string $type |
||
380 | * |
||
381 | * @return bool |
||
382 | */ |
||
383 | 90 | private function isType($type) |
|
387 | |||
388 | /* ------------------------------------------------------------------------------------------------ |
||
389 | | Other Functions |
||
390 | | ------------------------------------------------------------------------------------------------ |
||
391 | */ |
||
392 | /** |
||
393 | * Make an child item and add it to the parent item. |
||
394 | * |
||
395 | * @param string $type |
||
396 | * @param array $properties |
||
397 | * @param \Closure|null $callback |
||
398 | * |
||
399 | * @return self |
||
400 | */ |
||
401 | 55 | private function makeSubItem($type, array $properties = [], Closure $callback = null) |
|
409 | |||
410 | /** |
||
411 | * Add a child item to collection. |
||
412 | * |
||
413 | * @param self $item |
||
414 | * |
||
415 | * @return \Arcanedev\Menus\Entities\MenuItem |
||
416 | */ |
||
417 | 55 | private function addChild(MenuItem $item) |
|
423 | |||
424 | /** |
||
425 | * Dispatch menu item url. |
||
426 | * |
||
427 | * @param string $default |
||
428 | * |
||
429 | * @return string |
||
430 | */ |
||
431 | 45 | private function dispatchUrl($default = '#') |
|
451 | |||
452 | /** |
||
453 | * Guess the menu item type. |
||
454 | * |
||
455 | * @param array $properties |
||
456 | * |
||
457 | * @return string|null |
||
458 | */ |
||
459 | 100 | private function guessType(array $properties) |
|
469 | } |
||
470 |