Complex classes like DataProvider 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 DataProvider, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
47 | class DataProvider implements DataProviderInterface |
||
48 | { |
||
49 | |||
50 | /** |
||
51 | * Instance of model |
||
52 | * @var Document |
||
53 | * @since v1.0 |
||
54 | */ |
||
55 | public $model; |
||
56 | |||
57 | /** |
||
58 | * Finder instance |
||
59 | * @var FinderInterface |
||
60 | */ |
||
61 | private $finder = null; |
||
62 | |||
63 | /** |
||
64 | * @var CriteriaInterface |
||
65 | */ |
||
66 | private $criteria; |
||
67 | |||
68 | /** |
||
69 | * @var SortInterface |
||
70 | */ |
||
71 | private $sort; |
||
72 | private $data = null; |
||
73 | private $totalItemCount = null; |
||
74 | |||
75 | /** |
||
76 | * Pagination instance |
||
77 | * @var PaginationInterface |
||
78 | */ |
||
79 | private $pagination = null; |
||
80 | |||
81 | /** |
||
82 | * Constructor. |
||
83 | * @param mixed $modelClass the model class (e.g. 'Post') or the model finder instance |
||
84 | * (e.g. <code>Post::model()</code>, <code>Post::model()->published()</code>). |
||
85 | * @param array $config configuration (name=>value) to be applied as the initial property values of this class. |
||
86 | * @since v1.0 |
||
87 | */ |
||
88 | 1 | public function __construct($modelClass, $config = []) |
|
154 | |||
155 | /** |
||
156 | * Get model used by this data provider |
||
157 | * @return AnnotatedInterface |
||
158 | */ |
||
159 | public function getModel() |
||
163 | |||
164 | /** |
||
165 | * Set model |
||
166 | * @param AnnotatedInterface $model |
||
167 | */ |
||
168 | public function setModel(AnnotatedInterface $model) |
||
172 | |||
173 | /** |
||
174 | * Returns the criteria. |
||
175 | * @return Criteria the query criteria |
||
176 | * @since v1.0 |
||
177 | */ |
||
178 | public function getCriteria() |
||
187 | |||
188 | /** |
||
189 | * Sets the query criteria. |
||
190 | * @param CriteriaInterface|array $criteria the query criteria. Array representing the MongoDB query criteria. |
||
191 | * @since v1.0 |
||
192 | */ |
||
193 | public function setCriteria($criteria) |
||
208 | |||
209 | /** |
||
210 | * Returns the sort object. |
||
211 | * @return Sort the sorting object. If this is false, it means the sorting is disabled. |
||
212 | */ |
||
213 | 1 | public function getSort() |
|
222 | |||
223 | /** |
||
224 | * Set sort |
||
225 | * @param SortInterface $sort |
||
226 | * @return DataProvider |
||
227 | */ |
||
228 | public function setSort(SortInterface $sort) |
||
234 | |||
235 | /** |
||
236 | * Returns the pagination object. |
||
237 | * @param string $className the pagination object class name, use this param to override default pagination class. |
||
238 | * @return PaginationInterface|Pagination|false the pagination object. If this is false, it means the pagination is disabled. |
||
239 | */ |
||
240 | 1 | public function getPagination($className = Pagination::class) |
|
263 | |||
264 | /** |
||
265 | * Set pagination |
||
266 | * @param type $pagination |
||
267 | */ |
||
268 | public function setPagination($pagination) |
||
297 | |||
298 | /** |
||
299 | * Returns the number of data items in the current page. |
||
300 | * This is equivalent to <code>count($provider->getData())</code>. |
||
301 | * When {@link pagination} is set false, this returns the same value as {@link totalItemCount}. |
||
302 | * @param boolean $refresh whether the number of data items should be re-calculated. |
||
303 | * @return integer the number of data items in the current page. |
||
304 | */ |
||
305 | public function getItemCount($refresh = false) |
||
309 | |||
310 | /** |
||
311 | * Returns the total number of data items. |
||
312 | * When {@link pagination} is set false, this returns the same value as {@link itemCount}. |
||
313 | * @return integer total number of possible data items. |
||
314 | */ |
||
315 | 1 | public function getTotalItemCount() |
|
323 | |||
324 | /** |
||
325 | * Fetches the data from the persistent data storage. |
||
326 | * @return Document[]|Cursor list of data items |
||
327 | * @since v1.0 |
||
328 | */ |
||
329 | 1 | protected function fetchData() |
|
346 | |||
347 | /** |
||
348 | * Returns the data items currently available, ensures that result is at leas empty array |
||
349 | * @param boolean $refresh whether the data should be re-fetched from persistent storage. |
||
350 | * @return array the list of data items currently available in this data provider. |
||
351 | */ |
||
352 | 1 | public function getData($refresh = false) |
|
364 | |||
365 | } |
||
366 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.