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 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, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class Image |
||
27 | { |
||
28 | |||
29 | /** |
||
30 | * 已生成的图片 |
||
31 | * @var resource |
||
32 | */ |
||
33 | protected $image; |
||
34 | |||
35 | /** |
||
36 | * 验证码 |
||
37 | * @var string |
||
38 | */ |
||
39 | protected $code; |
||
40 | |||
41 | /** |
||
42 | * 验证码设置 |
||
43 | * @var array |
||
44 | */ |
||
45 | protected $config = array( |
||
46 | /** |
||
47 | * 默认验证码宽度 |
||
48 | * @var int |
||
49 | */ |
||
50 | 'width' => 150, |
||
51 | /** |
||
52 | * 默认验证码高度 |
||
53 | * @var int |
||
54 | */ |
||
55 | 'height' => 40, |
||
56 | /** |
||
57 | * 指定文字颜色 |
||
58 | * @var string |
||
59 | */ |
||
60 | 'textColor' => null, |
||
61 | /** |
||
62 | * 文字字体文件 |
||
63 | * @var string |
||
64 | */ |
||
65 | 'textFont' => null, |
||
66 | /** |
||
67 | * 指定图片背景色 |
||
68 | * @var string |
||
69 | */ |
||
70 | 'backgroundColor' => null, |
||
71 | /** |
||
72 | * 开启失真模式 |
||
73 | * @var bool |
||
74 | */ |
||
75 | 'distortion' => true, |
||
76 | /** |
||
77 | * 最大前景线条数 |
||
78 | * @var int |
||
79 | */ |
||
80 | 'maxFrontLines' => null, |
||
81 | /** |
||
82 | * 最大背景线条数 |
||
83 | * @val int |
||
84 | */ |
||
85 | 'maxBehindLines' => null, |
||
86 | /** |
||
87 | * 文字最大角度 |
||
88 | * @var int |
||
89 | */ |
||
90 | 'maxAngle' => 8, |
||
91 | /** |
||
92 | * 文字最大偏移量 |
||
93 | * @var int |
||
94 | */ |
||
95 | 'maxOffset' => 5, |
||
96 | /** |
||
97 | * 图片质量 |
||
98 | * @var int |
||
99 | */ |
||
100 | 'quality' => 90 |
||
101 | ); |
||
102 | |||
103 | |||
104 | public function __construct($code, array $config = array()) |
||
110 | |||
111 | /** |
||
112 | * 设置验证码配置 |
||
113 | * @param $config |
||
114 | * @param null $value |
||
115 | * @return $this |
||
116 | */ |
||
117 | public function setConfig($config, $value = null) |
||
130 | |||
131 | /** |
||
132 | * 获取配置 |
||
133 | * @param $key |
||
134 | * @return array|string|number |
||
135 | */ |
||
136 | public function getConfig($key) |
||
143 | |||
144 | /** |
||
145 | * 获取图片 |
||
146 | * @return resource |
||
147 | */ |
||
148 | public function getImage() |
||
157 | |||
158 | /** |
||
159 | * 重置图片 |
||
160 | * @return $this |
||
161 | */ |
||
162 | public function reset() |
||
169 | |||
170 | /** |
||
171 | * 获取 base64的数据,用做image标签的src |
||
172 | * @return string |
||
173 | */ |
||
174 | public function getDataUrl() |
||
178 | |||
179 | /** |
||
180 | * 输出为html |
||
181 | * @param int $width |
||
182 | * @param int $height |
||
183 | * @return string |
||
184 | */ |
||
185 | public function html($width = null, $height = null) |
||
197 | |||
198 | /** |
||
199 | * 返回Response响应 |
||
200 | * @return Response |
||
201 | */ |
||
202 | public function response() |
||
208 | |||
209 | |||
210 | /** |
||
211 | * 获取图片资源 |
||
212 | * @return mixed |
||
213 | */ |
||
214 | public function getContext() |
||
218 | |||
219 | /** |
||
220 | * 保存为图片 |
||
221 | * @param $filename |
||
222 | * @return $this |
||
223 | */ |
||
224 | public function save($filename) |
||
230 | |||
231 | /** |
||
232 | * 直接输出 |
||
233 | * @param null $filename |
||
234 | * @return $this |
||
235 | */ |
||
236 | public function output($filename = null) |
||
242 | |||
243 | /** |
||
244 | * 获取输出内容 |
||
245 | * @return string |
||
246 | */ |
||
247 | public function getContent() |
||
253 | |||
254 | /** |
||
255 | * 创建验证码图片 |
||
256 | * @param $code |
||
257 | * @return resource |
||
258 | */ |
||
259 | protected function build($code) |
||
320 | |||
321 | /** |
||
322 | * 获取一个字体 |
||
323 | * @return string |
||
324 | */ |
||
325 | protected function getTextFont() |
||
334 | |||
335 | /** |
||
336 | * 写入验证码到图片中 |
||
337 | * @param $image |
||
338 | * @param $phrase |
||
339 | * @param $font |
||
340 | * @return int |
||
341 | */ |
||
342 | protected function renderText($image, $phrase, $font) |
||
376 | |||
377 | /** |
||
378 | * 画线 |
||
379 | * @param $image |
||
380 | * @param $width |
||
381 | * @param $height |
||
382 | * @param null $color |
||
383 | */ |
||
384 | protected function renderLine($image, $width, $height, $color = null) |
||
404 | |||
405 | /** |
||
406 | * 画线 |
||
407 | * @param $image |
||
408 | * @param $max |
||
409 | * @param $color |
||
410 | */ |
||
411 | protected function drawLines($image, $max, $color = null) |
||
433 | |||
434 | /** |
||
435 | * 创建失真 |
||
436 | * @param $image |
||
437 | * @param $width |
||
438 | * @param $height |
||
439 | * @param $bg |
||
440 | * @return resource |
||
441 | */ |
||
442 | protected function distort($image, $width, $height, $bg) |
||
477 | |||
478 | /** |
||
479 | * 获取颜色 |
||
480 | * @param $image |
||
481 | * @param $x |
||
482 | * @param $y |
||
483 | * @param $background |
||
484 | * @return int |
||
485 | */ |
||
486 | protected function getColor($image, $x, $y, $background) |
||
496 | |||
497 | /** |
||
498 | * @param $name |
||
499 | * @param $arguments |
||
500 | * @return $this |
||
501 | */ |
||
502 | public function __call($name, $arguments) |
||
510 | |||
511 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.