Complex classes like QueryProcessor 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 QueryProcessor, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class QueryProcessor |
||
24 | { |
||
25 | /** |
||
26 | * Holds details of the request that client has submitted. |
||
27 | * |
||
28 | * @var RequestDescription |
||
29 | */ |
||
30 | private $request; |
||
31 | |||
32 | /** |
||
33 | * Holds reference to the underlying data service specific |
||
34 | * instance. |
||
35 | * |
||
36 | * @var IService |
||
37 | */ |
||
38 | private $service; |
||
39 | |||
40 | /** |
||
41 | * If $orderby, $skip, $top and $count options can be applied to the request. |
||
42 | * |
||
43 | * @var bool |
||
44 | */ |
||
45 | private $setQueryApplicable; |
||
46 | |||
47 | /** |
||
48 | * Whether the top level request is a candidate for paging. |
||
49 | * |
||
50 | * @var bool |
||
51 | */ |
||
52 | private $pagingApplicable; |
||
53 | |||
54 | /** |
||
55 | * Whether $expand, $select can be applied to the request. |
||
56 | * |
||
57 | * @var bool |
||
58 | */ |
||
59 | private $expandSelectApplicable; |
||
60 | |||
61 | /** |
||
62 | * Creates new instance of QueryProcessor. |
||
63 | * |
||
64 | * @param RequestDescription $request Description of the request submitted by client |
||
65 | * @param IService $service Reference to the service implementation |
||
66 | */ |
||
67 | private function __construct(RequestDescription $request, IService $service) |
||
96 | |||
97 | /** |
||
98 | * Process the OData query options and update RequestDescription accordingly. |
||
99 | * |
||
100 | * @param RequestDescription $request Description of the request submitted by client |
||
101 | * @param IService $service Reference to the data service |
||
102 | * |
||
103 | * @throws ODataException |
||
104 | */ |
||
105 | public static function process(RequestDescription $request, IService $service) |
||
117 | |||
118 | /** |
||
119 | * Processes the odata query options in the request uri and update the request description |
||
120 | * instance with processed details. |
||
121 | * |
||
122 | * @throws ODataException If any error occured while processing the query options |
||
123 | */ |
||
124 | private function processQuery() |
||
133 | |||
134 | /** |
||
135 | * Process $skip and $top options. |
||
136 | * |
||
137 | * |
||
138 | * @throws ODataException Throws syntax error if the $skip or $top option |
||
139 | * is specified with non-integer value, throws |
||
140 | * bad request error if the $skip or $top option |
||
141 | * is not applicable for the requested resource |
||
142 | */ |
||
143 | private function processSkipAndTop() |
||
180 | |||
181 | /** |
||
182 | * Process $orderby option, This function requires _processSkipAndTopOption |
||
183 | * function to be already called as this function need to know whether |
||
184 | * client has requested for skip, top or paging is enabled for the |
||
185 | * requested resource in these cases function generates additional orderby |
||
186 | * expression using keys. |
||
187 | * |
||
188 | * |
||
189 | * @throws ODataException If any error occurs while parsing orderby option |
||
190 | */ |
||
191 | private function processOrderBy() |
||
240 | |||
241 | /** |
||
242 | * Process the $filter option in the request and update request decription. |
||
243 | * |
||
244 | * |
||
245 | * @throws ODataException Throws error in the following cases: |
||
246 | * (1) If $filter cannot be applied to the |
||
247 | * resource targeted by the request uri |
||
248 | * (2) If any error occured while parsing and |
||
249 | * translating the odata $filter expression |
||
250 | * to expression tree |
||
251 | * (3) If any error occured while generating |
||
252 | * php expression from expression tree |
||
253 | */ |
||
254 | private function processFilter() |
||
275 | |||
276 | /** |
||
277 | * Process the $inlinecount option and update the request description. |
||
278 | * |
||
279 | * |
||
280 | * @throws ODataException Throws bad request error in the following cases |
||
281 | * (1) If $inlinecount is disabled by the developer |
||
282 | * (2) If both $count and $inlinecount specified |
||
283 | * (3) If $inlinecount value is unknown |
||
284 | * (4) If capability negotiation over version fails |
||
285 | */ |
||
286 | private function processCount() |
||
330 | |||
331 | /** |
||
332 | * Process the $skiptoken option in the request and update the request |
||
333 | * description, this function requires _processOrderBy method to be |
||
334 | * already invoked. |
||
335 | * |
||
336 | * |
||
337 | * @throws ODataException Throws bad request error in the following cases |
||
338 | * (1) If $skiptoken cannot be applied to the |
||
339 | * resource targeted by the request uri |
||
340 | * (2) If paging is not enabled for the resource |
||
341 | * targeted by the request uri |
||
342 | * (3) If parsing of $skiptoken fails |
||
343 | * (4) If capability negotiation over version fails |
||
344 | */ |
||
345 | private function processSkipToken() |
||
380 | |||
381 | /** |
||
382 | * Process the $expand and $select option and update the request description. |
||
383 | * |
||
384 | * |
||
385 | * @throws ODataException Throws bad request error in the following cases |
||
386 | * (1) If $expand or select cannot be applied to the |
||
387 | * requested resource. |
||
388 | * (2) If projection is disabled by the developer |
||
389 | * (3) If some error occurs while parsing the options |
||
390 | */ |
||
391 | private function processExpandAndSelect() |
||
433 | |||
434 | /** |
||
435 | * Is server side paging is configured, this function return true |
||
436 | * if the resource targeted by the resource path is applicable |
||
437 | * for paging and paging is enabled for the targeted resource set |
||
438 | * else false. |
||
439 | * |
||
440 | * @return bool |
||
441 | */ |
||
442 | private function isSSPagingRequired() |
||
452 | |||
453 | /** |
||
454 | * Read skip or top query option value which is expected to be positive |
||
455 | * integer. |
||
456 | * |
||
457 | * @param string $queryItem The name of the query item to read from request |
||
458 | * uri ($skip or $top) |
||
459 | * @param int &$value On return, If the requested query item is |
||
460 | * present with a valid integer value then this |
||
461 | * argument will holds that integer value |
||
462 | * otherwise holds zero |
||
463 | * |
||
464 | * @throws ODataException Throws syntax error if the requested argument |
||
465 | * is present and it is not an integer |
||
466 | * |
||
467 | * @return bool True If the requested query item with valid integer |
||
468 | * value is present in the request, false query |
||
469 | * item is absent in the request uri |
||
470 | */ |
||
471 | private function readSkipOrTopOption($queryItem, &$value) |
||
502 | |||
503 | /** |
||
504 | * Checks whether client request contains any odata query options. |
||
505 | * |
||
506 | * |
||
507 | * @throws ODataException Throws bad request error if client request |
||
508 | * includes any odata query option |
||
509 | */ |
||
510 | private function checkForEmptyQueryArguments() |
||
527 | |||
528 | /** |
||
529 | * To check whether the the query options $orderby, $inlinecount, $skip |
||
530 | * or $top is applicable for the current requested resource. |
||
531 | * |
||
532 | * |
||
533 | * @throws ODataException Throws bad request error if any of the query options $orderby, $inlinecount, |
||
534 | * $skip or $top cannot be applied to the requested resource |
||
535 | */ |
||
536 | private function checkSetQueryApplicable() |
||
544 | |||
545 | /** |
||
546 | * To check whether the the query options $select, $expand |
||
547 | * is applicable for the current requested resource. |
||
548 | * |
||
549 | * @param string $queryItem The query option to check |
||
550 | * |
||
551 | * @throws ODataException Throws bad request error if the query |
||
552 | * options $select, $expand cannot be |
||
553 | * applied to the requested resource |
||
554 | */ |
||
555 | private function checkExpandOrSelectApplicable($queryItem) |
||
563 | } |
||
564 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.