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:
1 | <?php |
||
13 | abstract class Properties |
||
14 | { |
||
15 | /** |
||
16 | * The original property values. |
||
17 | * |
||
18 | * @var array |
||
19 | */ |
||
20 | protected $original = []; |
||
21 | |||
22 | /** |
||
23 | * The current/modified property values. |
||
24 | * |
||
25 | * @var array |
||
26 | */ |
||
27 | protected $current = []; |
||
28 | |||
29 | /** |
||
30 | * Any properties that have been flagged for removal. |
||
31 | * |
||
32 | * @var array |
||
33 | */ |
||
34 | protected $remove = []; |
||
35 | |||
36 | /** |
||
37 | * Constructor. |
||
38 | * |
||
39 | * @param array $original Any original properties to apply. |
||
40 | */ |
||
41 | public function __construct(array $original = []) |
||
45 | |||
46 | /** |
||
47 | * Gets the current value of an property. |
||
48 | * |
||
49 | * @param string $key The property key. |
||
50 | * @return mixed |
||
51 | */ |
||
52 | public function get($key) |
||
62 | |||
63 | /** |
||
64 | * Sets a new value to an property. |
||
65 | * |
||
66 | * @param string $key The property key. |
||
67 | * @param mixed $value The value to set. |
||
68 | * @return mixed |
||
69 | */ |
||
70 | public function set($key, $value) |
||
99 | |||
100 | /** |
||
101 | * Sets a new value to an property. |
||
102 | * |
||
103 | * @param string $key The property key. |
||
104 | * @return self |
||
105 | */ |
||
106 | public function remove($key) |
||
116 | |||
117 | /** |
||
118 | * Rolls back the properties to their original state. |
||
119 | * |
||
120 | * @return self |
||
121 | */ |
||
122 | public function rollback() |
||
128 | |||
129 | /** |
||
130 | * Replaces the current properties with new ones. |
||
131 | * Will revert/rollback any current changes. |
||
132 | * |
||
133 | * @param array $original |
||
134 | * @return self |
||
135 | */ |
||
136 | public function replace(array $original) |
||
142 | |||
143 | |||
144 | /** |
||
145 | * Deteremines if the properties have different values from their original state. |
||
146 | * |
||
147 | * @return bool |
||
148 | */ |
||
149 | public function areDirty() |
||
153 | |||
154 | /** |
||
155 | * Calculates any property changes. |
||
156 | * |
||
157 | * @return array |
||
158 | */ |
||
159 | public function calculateChangeSet() |
||
160 | { |
||
161 | $set = []; |
||
162 | View Code Duplication | foreach ($this->current as $key => $current) { |
|
|
|||
163 | $original = isset($this->original[$key]) ? $this->original[$key] : null; |
||
164 | $set[$key]['old'] = $original; |
||
165 | $set[$key]['new'] = $current; |
||
166 | } |
||
167 | View Code Duplication | foreach ($this->remove as $key) { |
|
168 | $set[$key]['old'] = $this->original[$key]; |
||
169 | $set[$key]['new'] = null; |
||
170 | } |
||
171 | ksort($set); |
||
172 | return $set; |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Clears an property from the removal queue. |
||
177 | * |
||
178 | * @param string $key The field key. |
||
179 | * @return self |
||
180 | */ |
||
181 | protected function clearRemoval($key) |
||
191 | |||
192 | /** |
||
193 | * Clears an property as having been changed. |
||
194 | * |
||
195 | * @param string $key The field key. |
||
196 | * @return self |
||
197 | */ |
||
198 | protected function clearChange($key) |
||
205 | |||
206 | /** |
||
207 | * Determines if an property is in the removal queue. |
||
208 | * |
||
209 | * @param string $key The field key. |
||
210 | * @return bool |
||
211 | */ |
||
212 | protected function willRemove($key) |
||
216 | |||
217 | /** |
||
218 | * Determines if an property has a new value. |
||
219 | * |
||
220 | * @param string $key The field key. |
||
221 | * @return bool |
||
222 | */ |
||
223 | protected function willChange($key) |
||
227 | |||
228 | /** |
||
229 | * Determines if an property has an original value. |
||
230 | * |
||
231 | * @param string $key The field key. |
||
232 | * @return bool |
||
233 | */ |
||
234 | protected function hasOriginal($key) |
||
238 | |||
239 | /** |
||
240 | * Gets the property's original value. |
||
241 | * |
||
242 | * @param string $key The field key. |
||
243 | * @return mixed |
||
244 | */ |
||
245 | protected function getOriginal($key) |
||
252 | |||
253 | /** |
||
254 | * Gets all original properties. |
||
255 | * |
||
256 | * @return array |
||
257 | */ |
||
258 | protected function getOriginalAll() |
||
262 | |||
263 | /** |
||
264 | * Gets all current properties. |
||
265 | * |
||
266 | * @return array |
||
267 | */ |
||
268 | protected function getCurrentAll() |
||
272 | |||
273 | /** |
||
274 | * Gets the property's current value. |
||
275 | * |
||
276 | * @param string $key The field key. |
||
277 | * @return mixed |
||
278 | */ |
||
279 | protected function getCurrent($key) |
||
286 | } |
||
287 |
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.