Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Image_Transform_Driver_IM 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 Image_Transform_Driver_IM, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
45 | class Image_Transform_Driver_IM extends Image_Transform |
||
46 | { |
||
47 | /** |
||
48 | * associative array commands to be executed |
||
49 | * @var array |
||
50 | * @access private |
||
51 | */ |
||
52 | var $command; |
||
53 | |||
54 | /** |
||
55 | * Class constructor |
||
56 | */ |
||
57 | function Image_Transform_Driver_IM() |
||
61 | |||
62 | /** |
||
63 | * Class constructor |
||
64 | */ |
||
65 | View Code Duplication | function __construct() |
|
80 | |||
81 | /** |
||
82 | * Initialize the state of the object |
||
83 | **/ |
||
84 | function _init() |
||
88 | |||
89 | /** |
||
90 | * Load an image. |
||
91 | * |
||
92 | * This method doesn't support remote files. |
||
93 | * |
||
94 | * @param string filename |
||
95 | * |
||
96 | * @return mixed TRUE or a PEAR error object on error |
||
97 | * @see PEAR::isError() |
||
98 | */ |
||
99 | function load($image) |
||
114 | |||
115 | /** |
||
116 | * Image_Transform_Driver_IM::_get_image_details() |
||
117 | * |
||
118 | * @param string $image the path and name of the image file |
||
119 | * @return none |
||
120 | */ |
||
121 | function _get_image_details($image) |
||
149 | |||
150 | /** |
||
151 | * Resize the image. |
||
152 | * |
||
153 | * @access private |
||
154 | * |
||
155 | * @param int $new_x New width |
||
156 | * @param int $new_y New height |
||
157 | * @param mixed $options Optional parameters |
||
158 | * |
||
159 | * @return true on success or PEAR Error object on error |
||
160 | * @see PEAR::isError() |
||
161 | */ |
||
162 | function _resize($new_x, $new_y, $options = null) |
||
175 | |||
176 | /** |
||
177 | * rotate |
||
178 | * |
||
179 | * @param int angle rotation angle |
||
180 | * @param array options no option allowed |
||
181 | * @return mixed TRUE or a PEAR error object on error |
||
182 | */ |
||
183 | function rotate($angle, $options = null) |
||
192 | |||
193 | /** |
||
194 | * Crop image |
||
195 | * |
||
196 | * @author Ian Eure <[email protected]> |
||
197 | * @since 0.8 |
||
198 | * |
||
199 | * @param int width Cropped image width |
||
200 | * @param int height Cropped image height |
||
201 | * @param int x X-coordinate to crop at |
||
202 | * @param int y Y-coordinate to crop at |
||
203 | * |
||
204 | * @return mixed TRUE or a PEAR error object on error |
||
205 | */ |
||
206 | function crop($width, $height, $x = 0, $y = 0) { |
||
220 | |||
221 | /** |
||
222 | * addText |
||
223 | * |
||
224 | * @param array options Array contains options |
||
225 | * array( |
||
226 | * 'text' The string to draw |
||
227 | * 'x' Horizontal position |
||
228 | * 'y' Vertical Position |
||
229 | * 'Color' Font color |
||
230 | * 'font' Font to be used |
||
231 | * 'size' Size of the fonts in pixel |
||
232 | * 'resize_first' Tell if the image has to be resized |
||
233 | * before drawing the text |
||
234 | * ) |
||
235 | * |
||
236 | * @return mixed TRUE or a PEAR error object on error |
||
237 | * @see PEAR::isError() |
||
238 | */ |
||
239 | function addText($params) |
||
259 | |||
260 | /** |
||
261 | * Adjust the image gamma |
||
262 | * |
||
263 | * @access public |
||
264 | * @param float $outputgamma |
||
265 | * @return mixed TRUE or a PEAR error object on error |
||
266 | */ |
||
267 | function gamma($outputgamma = 1.0) { |
||
273 | |||
274 | /** |
||
275 | * Convert the image to greyscale |
||
276 | * |
||
277 | * @access public |
||
278 | * @return mixed TRUE or a PEAR error object on error |
||
279 | */ |
||
280 | function greyscale() { |
||
284 | |||
285 | /** |
||
286 | * Horizontal mirroring |
||
287 | * |
||
288 | * @access public |
||
289 | * @return TRUE or PEAR Error object on error |
||
290 | */ |
||
291 | View Code Duplication | function mirror() { |
|
300 | |||
301 | /** |
||
302 | * Vertical mirroring |
||
303 | * |
||
304 | * @access public |
||
305 | * @return TRUE or PEAR Error object on error |
||
306 | */ |
||
307 | View Code Duplication | function flip() { |
|
316 | |||
317 | /** |
||
318 | * Save the image file |
||
319 | * |
||
320 | * @access public |
||
321 | * |
||
322 | * @param $filename string the name of the file to write to |
||
323 | * @param $quality quality image dpi, default=75 |
||
324 | * @param $type string (JPEG, PNG...) |
||
325 | * |
||
326 | * @return mixed TRUE or a PEAR error object on error |
||
327 | */ |
||
328 | function save($filename, $type = '', $quality = null) |
||
358 | |||
359 | /** |
||
360 | * Display image without saving and lose changes |
||
361 | * |
||
362 | * This method adds the Content-type HTTP header |
||
363 | * |
||
364 | * @access public |
||
365 | * |
||
366 | * @param string type (JPEG,PNG...); |
||
367 | * @param int quality 75 |
||
368 | * |
||
369 | * @return mixed TRUE or a PEAR error object on error |
||
370 | */ |
||
371 | function display($type = '', $quality = null) |
||
399 | |||
400 | /** |
||
401 | * Destroy image handle |
||
402 | * |
||
403 | * @return void |
||
404 | */ |
||
405 | function free() |
||
411 | |||
412 | } // End class ImageIM |
||
413 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.