Complex classes like Kohana_Jam_Array_Model 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 Kohana_Jam_Array_Model, and based on these observations, apply Extract Interface, too.
1 | <?php defined('SYSPATH') OR die('No direct script access.'); |
||
12 | abstract class Kohana_Jam_Array_Model extends Jam_Array { |
||
13 | |||
14 | public static function factory() |
||
18 | |||
19 | /** |
||
20 | * Convert a collection to an array, keep an array or make a Jam_Model to an array(Jam_Model) |
||
21 | * @param mixed $collection |
||
22 | * @return array |
||
23 | */ |
||
24 | 20 | public static function convert_collection_to_array($collection) |
|
40 | |||
41 | /** |
||
42 | * A collection used to load the content |
||
43 | * @var Jam_Query_Builder_Collection |
||
44 | */ |
||
45 | protected $_collection; |
||
46 | |||
47 | /** |
||
48 | * The name of the models in this iterator |
||
49 | * @var string |
||
50 | */ |
||
51 | protected $_model; |
||
52 | |||
53 | /** |
||
54 | * The original content, loaded from the database |
||
55 | * @var array |
||
56 | */ |
||
57 | protected $_original; |
||
58 | |||
59 | /** |
||
60 | * This is set if the whole collection has been replaced. |
||
61 | * @var boolean |
||
62 | */ |
||
63 | protected $_replace = FALSE; |
||
64 | |||
65 | /** |
||
66 | * Getter / Setter of the model name |
||
67 | * @param string $model |
||
68 | * @return string |
||
69 | */ |
||
70 | 754 | public function model($model = NULL) |
|
79 | |||
80 | /** |
||
81 | * Getter of the meta object for this iterator (based on $_model) |
||
82 | * @return Jam_Model |
||
83 | * @throws Kohana_Exception If $_model not present |
||
84 | */ |
||
85 | 18 | public function meta() |
|
92 | |||
93 | /** |
||
94 | * Getter / Setter of the collection, used to lazy load the data for this iterator |
||
95 | * @param Jam_Query_Builder_Collection $collection |
||
96 | * @return Jam_Query_Builder_Collection |
||
97 | */ |
||
98 | 18 | public function collection(Jam_Query_Builder_Collection $collection = NULL) |
|
108 | |||
109 | /** |
||
110 | * Load the content from the database, using $_collection. |
||
111 | * If some items have been added to the iterator before it has been loaded, merge the results |
||
112 | * @throws Kohana_Exception If the $_collection has not been loaded |
||
113 | */ |
||
114 | 27 | protected function _load_content() |
|
138 | |||
139 | public function reload() |
||
145 | |||
146 | /** |
||
147 | * Load an item from the database, based on a unique key |
||
148 | * @param string $key |
||
149 | * @return Jam_Model |
||
150 | */ |
||
151 | protected function _find_item($key) |
||
152 | { |
||
153 | return Jam::find($this->model(), $key); |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Convert an item from the $_content to a Jam_Model |
||
158 | * @param mixed $value |
||
159 | * @param boolean $is_changed |
||
160 | * @param int $offset |
||
161 | * @return Jam_Model |
||
162 | */ |
||
163 | 19 | protected function _load_item($value, $is_changed, $offset) |
|
164 | { |
||
165 | 19 | if ($value instanceof Jam_Model OR ! $value) |
|
166 | { |
||
167 | 12 | $item = $value; |
|
168 | } |
||
169 | 12 | elseif ( ! is_array($value)) |
|
170 | { |
||
171 | $item = $this->_find_item($value); |
||
172 | } |
||
173 | 12 | elseif (is_array($value) AND $is_changed) |
|
174 | { |
||
175 | $key = $this->meta()->primary_key(); |
||
176 | if (isset($value[$key]) AND $value[$key]) |
||
177 | { |
||
178 | $item_key = is_array($value[$key]) ? reset($value[$key]) : $value[$key]; |
||
179 | |||
180 | $model = $this->_find_item($item_key); |
||
181 | if ( ! $model) |
||
182 | { |
||
183 | $model = clone Jam::build_template($this->model(), $value); |
||
184 | } |
||
185 | else |
||
186 | { |
||
187 | unset($value[$key]); |
||
188 | } |
||
189 | } |
||
190 | else |
||
191 | { |
||
192 | $model = clone Jam::build_template($this->model(), $value); |
||
193 | } |
||
194 | |||
195 | $item = $model->set($value); |
||
196 | } |
||
197 | else |
||
198 | { |
||
199 | 12 | $item = clone Jam::build_template($this->model(), $value); |
|
200 | 12 | $item = $item->load_fields($value); |
|
201 | } |
||
202 | |||
203 | 19 | $this->_content[$offset] = $item; |
|
204 | |||
205 | 19 | return $item; |
|
206 | } |
||
207 | |||
208 | /** |
||
209 | * Find out the primary_key of an item of the $_content |
||
210 | * @param mixed $value |
||
211 | * @return int |
||
212 | */ |
||
213 | 21 | protected function _id($value) |
|
227 | |||
228 | 15 | public function search($item) |
|
250 | |||
251 | 12 | public function as_array($key = NULL, $value = NULL) |
|
264 | |||
265 | 6 | public function ids() |
|
271 | |||
272 | 7 | public function load_fields(array $data) |
|
277 | |||
278 | public function original() |
||
282 | |||
283 | 1 | public function original_ids() |
|
289 | |||
290 | 3 | public function has($item) |
|
294 | |||
295 | 8 | public function set($items) |
|
304 | |||
305 | 8 | public function add($items) |
|
316 | |||
317 | 6 | public function remove($items) |
|
331 | |||
332 | /** |
||
333 | * Build a new Jam Model, add it to the collection and return the newly built model |
||
334 | * @param array $values set values on the new model |
||
335 | * @return Jam_Model |
||
336 | */ |
||
337 | 1 | public function build(array $values = NULL) |
|
348 | |||
349 | /** |
||
350 | * The same as build but saves the model in the database |
||
351 | * @param array $values |
||
352 | * @return Jam_Model |
||
353 | */ |
||
354 | public function create(array $values = NULL) |
||
358 | |||
359 | 1 | public function check_changed() |
|
374 | |||
375 | 1 | public function save_changed() |
|
388 | |||
389 | 1 | public function clear() |
|
397 | |||
398 | public function clear_changed() |
||
399 | { |
||
400 | $this->_changed = array(); |
||
401 | $this->_original = $this->_content; |
||
402 | |||
403 | return $this; |
||
404 | } |
||
405 | |||
406 | 16 | public function __toString() |
|
413 | |||
414 | 2 | public function __call($method, $args) |
|
421 | |||
422 | /** |
||
423 | * Getter for the changed array - check if any or a particular item has been changed |
||
424 | * @param int $offset |
||
425 | * @return bool |
||
426 | */ |
||
427 | 6 | public function changed($offset = NULL) |
|
442 | |||
443 | 754 | public function serialize() |
|
458 | |||
459 | 754 | public function unserialize($data) |
|
471 | } |
||
472 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.