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 |
||
12 | class Stub implements \JsonSerializable |
||
13 | { |
||
14 | /** |
||
15 | * @var IResponse[] |
||
16 | */ |
||
17 | private $responses = []; |
||
18 | |||
19 | /** |
||
20 | * @var IPredicate[] |
||
21 | */ |
||
22 | private $predicates = []; |
||
23 | |||
24 | /** |
||
25 | * @param IResponse|IResponse[] $responses |
||
26 | * @param IPredicate|IPredicate[]|null $predicates |
||
27 | */ |
||
28 | 27 | public function __construct($responses = [], $predicates = []) |
|
29 | { |
||
30 | 27 | if (is_array($responses)) { |
|
31 | 17 | $this->addResponses($responses); |
|
32 | 27 | } elseif (null !== $responses) { |
|
33 | 9 | $this->addResponse($responses); |
|
34 | 9 | } |
|
35 | |||
36 | 27 | if (is_array($predicates)) { |
|
37 | 23 | $this->addPredicates($predicates); |
|
38 | 27 | } elseif (null !== $predicates) { |
|
39 | 4 | $this->addPredicate($predicates); |
|
40 | 4 | } |
|
41 | 27 | } |
|
42 | |||
43 | /** |
||
44 | * @param IResponse[] $responses |
||
45 | */ |
||
46 | 17 | private function addResponses(array $responses) |
|
47 | { |
||
48 | 17 | foreach ($responses as $response) { |
|
49 | 9 | $this->addResponse($response); |
|
50 | 17 | } |
|
51 | 17 | } |
|
52 | |||
53 | /** |
||
54 | * @param IResponse $responses |
||
55 | */ |
||
56 | 18 | private function addResponse(IResponse $responses) |
|
60 | |||
61 | /** |
||
62 | * @param IPredicate[] $predicates |
||
63 | */ |
||
64 | 23 | private function addPredicates(array $predicates) |
|
65 | { |
||
66 | 23 | foreach ($predicates as $predicate) { |
|
67 | 3 | $this->addPredicate($predicate); |
|
68 | 23 | } |
|
69 | 23 | } |
|
70 | |||
71 | /** |
||
72 | * @param IPredicate $predicate |
||
73 | */ |
||
74 | 7 | private function addPredicate(IPredicate $predicate) |
|
78 | |||
79 | /** |
||
80 | * @return array |
||
81 | */ |
||
82 | 3 | public function getPredicates() |
|
86 | |||
87 | /** |
||
88 | * @param array $match |
||
89 | * @return bool |
||
90 | */ |
||
91 | 1 | public function isPredicatesMatch(array $match) |
|
95 | |||
96 | /** |
||
97 | * @return array |
||
98 | */ |
||
99 | 8 | private function jsonSerializePredicates() |
|
100 | { |
||
101 | 8 | $predicates = []; |
|
102 | 8 | foreach ($this->predicates as $predicate) { |
|
103 | 3 | $predicates[] = $predicate->jsonSerialize(); |
|
104 | 8 | } |
|
105 | |||
106 | 8 | return $predicates; |
|
107 | } |
||
108 | |||
109 | 1 | public function clearPredicates() |
|
113 | |||
114 | 1 | public function clearResponses() |
|
118 | |||
119 | /** |
||
120 | * @return array |
||
121 | */ |
||
122 | 7 | public function jsonSerialize() |
|
123 | { |
||
124 | return [ |
||
125 | 7 | 'predicates' => $this->jsonSerializePredicates(), |
|
126 | 7 | 'responses' => $this->jsonSerializeResponses(), |
|
127 | 7 | ]; |
|
128 | } |
||
129 | |||
130 | /** |
||
131 | * @return array |
||
132 | */ |
||
133 | 7 | private function jsonSerializeResponses() |
|
134 | { |
||
135 | 7 | $responses = []; |
|
136 | 7 | foreach ($this->responses as $response) { |
|
137 | 5 | $responses[] = $response->jsonSerialize(); |
|
138 | 7 | } |
|
139 | |||
140 | 7 | return $responses; |
|
141 | } |
||
142 | |||
143 | /** |
||
144 | * @return IResponse[] |
||
145 | */ |
||
146 | 3 | public function getResponses() |
|
150 | |||
151 | /** |
||
152 | * @param int $nth |
||
153 | * @return IResponse |
||
154 | * @throws \Meare\Juggler\Exception\Client\NotFoundException |
||
155 | */ |
||
156 | 2 | public function getResponse($nth = 0) |
|
164 | |||
165 | /** |
||
166 | * @param int $index |
||
167 | * @return bool |
||
168 | */ |
||
169 | 3 | public function hasResponse($index) |
|
173 | |||
174 | /** |
||
175 | * Returns first or nth "is" response if exists |
||
176 | * |
||
177 | * @param int $nth |
||
178 | * @return IsResponse |
||
179 | */ |
||
180 | 2 | public function getIsResponse($nth = 0) |
|
184 | |||
185 | /** |
||
186 | * Returns first or nth response of type ("is", "proxy" or "inject") if exists |
||
187 | * |
||
188 | * @param string $type |
||
189 | * @param int $nth number of $type-response in a list |
||
190 | * @return IResponse |
||
191 | * @throws NotFoundException |
||
192 | */ |
||
193 | 4 | public function getResponseOfType($type, $nth = 0) |
|
194 | { |
||
195 | 4 | View Code Duplication | if (!in_array($type, [IResponse::TYPE_IS, IResponse::TYPE_PROXY, IResponse::TYPE_INJECT])) { |
|
|||
196 | 1 | throw new \InvalidArgumentException("Unknown response type: '$type'"); |
|
197 | } |
||
198 | 3 | $matches_found = 0; |
|
199 | 3 | foreach ($this->responses as $response) { |
|
200 | 3 | if ($response->getType() === $type && $matches_found++ === $nth) { |
|
201 | 1 | return $response; |
|
202 | } |
||
203 | 3 | } |
|
204 | 2 | throw new NotFoundException("Unable to find response of type '$type' at position $nth ($matches_found '$type' responses were found)"); |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * Returns first or nth "proxy" response if exists |
||
209 | * |
||
210 | * @param int $nth |
||
211 | * @return ProxyResponse |
||
212 | */ |
||
213 | 2 | public function getProxyResponse($nth = 0) |
|
217 | |||
218 | /** |
||
219 | * Returns first or nth "inject" response if exists |
||
220 | * |
||
221 | * @param int $nth |
||
222 | * @return Injection |
||
223 | */ |
||
224 | 1 | public function getInjectionResponse($nth = 0) |
|
228 | } |
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.