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 SuccessResponseBuilder 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 SuccessResponseBuilder, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
26 | class SuccessResponseBuilder extends ResponseBuilder |
||
27 | { |
||
28 | /** |
||
29 | * The manager responsible for transforming and serializing data. |
||
30 | * |
||
31 | * @var \League\Fractal\Manager |
||
32 | */ |
||
33 | protected $manager; |
||
34 | |||
35 | /** |
||
36 | * The meta data appended to the serialized data. |
||
37 | * |
||
38 | * @var array |
||
39 | */ |
||
40 | protected $meta = []; |
||
41 | |||
42 | /** |
||
43 | * The included relations. |
||
44 | * |
||
45 | * @var array |
||
46 | */ |
||
47 | protected $relations = []; |
||
48 | |||
49 | /** |
||
50 | * The Fractal resource instance containing the data and transformer. |
||
51 | * |
||
52 | * @var \League\Fractal\Resource\ResourceInterface |
||
53 | */ |
||
54 | protected $resource; |
||
55 | |||
56 | /** |
||
57 | * The resource factory used to generate resource instances. |
||
58 | * |
||
59 | * @var \Flugg\Responder\ResourceFactory |
||
60 | */ |
||
61 | protected $resourceFactory; |
||
62 | |||
63 | /** |
||
64 | * The HTTP status code for the response. |
||
65 | * |
||
66 | * @var int |
||
67 | */ |
||
68 | protected $statusCode = 200; |
||
69 | |||
70 | /** |
||
71 | * SuccessResponseBuilder constructor. |
||
72 | * |
||
73 | * @param \Illuminate\Contracts\Routing\ResponseFactory|\Laravel\Lumen\Http\ResponseFactory $responseFactory |
||
74 | * @param \Flugg\Responder\ResourceFactory $resourceFactory |
||
75 | * @param \League\Fractal\Manager $manager |
||
76 | */ |
||
77 | public function __construct($responseFactory, ResourceFactory $resourceFactory, Manager $manager) |
||
85 | |||
86 | /** |
||
87 | * Add data to the meta data appended to the response data. |
||
88 | * |
||
89 | * @param array $data |
||
90 | * @return self |
||
91 | */ |
||
92 | public function addMeta(array $data):SuccessResponseBuilder |
||
98 | |||
99 | /** |
||
100 | * Set the serializer used to serialize the resource data. |
||
101 | * |
||
102 | * @param array|string $relations |
||
103 | * @return self |
||
104 | */ |
||
105 | public function include($relations):SuccessResponseBuilder |
||
115 | |||
116 | /** |
||
117 | * Set the serializer used to serialize the resource data. |
||
118 | * |
||
119 | * @param \League\Fractal\Serializer\SerializerAbstract|string $serializer |
||
120 | * @return self |
||
121 | */ |
||
122 | public function serializer($serializer):SuccessResponseBuilder |
||
128 | |||
129 | /** |
||
130 | * Set the HTTP status code for the response. |
||
131 | * |
||
132 | * @param int $statusCode |
||
133 | * @return self |
||
134 | * @throws \InvalidArgumentException |
||
135 | */ |
||
136 | View Code Duplication | public function setStatus(int $statusCode):ResponseBuilder |
|
144 | |||
145 | /** |
||
146 | * Return response success flag as true |
||
147 | * |
||
148 | * @return bool |
||
149 | */ |
||
150 | public function isSuccessResponse():bool |
||
154 | |||
155 | /** |
||
156 | * Set the transformation data. This will set a new resource instance on the response |
||
157 | * builder depending on what type of data is provided. |
||
158 | * |
||
159 | * @param mixed|null $data |
||
160 | * @param callable|string|null $transformer |
||
161 | * @param string|null $resourceKey |
||
162 | * @return self |
||
163 | */ |
||
164 | public function transform($data = null, $transformer = null, string $resourceKey = null):SuccessResponseBuilder |
||
186 | |||
187 | /** |
||
188 | * Convert the response to an array. |
||
189 | * |
||
190 | * @return array |
||
191 | */ |
||
192 | public function toArray():array |
||
196 | |||
197 | /** |
||
198 | * Get the Fractal resource instance. |
||
199 | * |
||
200 | * @return \League\Fractal\Resource\ResourceInterface |
||
201 | */ |
||
202 | public function getResource():ResourceInterface |
||
213 | |||
214 | /** |
||
215 | * Get the Fractal manager responsible for transforming and serializing the data. |
||
216 | * |
||
217 | * @return \League\Fractal\Manager |
||
218 | */ |
||
219 | public function getManager():Manager |
||
223 | |||
224 | /** |
||
225 | * Resolve a serializer instance from the value. |
||
226 | * |
||
227 | * @param \League\Fractal\Serializer\SerializerAbstract|string $serializer |
||
228 | * @return \League\Fractal\Serializer\SerializerAbstract |
||
229 | * @throws \Flugg\Responder\Exceptions\InvalidSerializerException |
||
230 | */ |
||
231 | protected function resolveSerializer($serializer):SerializerAbstract |
||
243 | |||
244 | /** |
||
245 | * Resolve a model instance from the data. |
||
246 | * |
||
247 | * @param \Illuminate\Database\Eloquent\Model|array $data |
||
248 | * @return \Illuminate\Database\Eloquent\Model |
||
249 | * @throws \InvalidArgumentException |
||
250 | */ |
||
251 | protected function resolveModel($data):Model |
||
264 | |||
265 | /** |
||
266 | * Resolve a transformer. |
||
267 | * |
||
268 | * @param \Illuminate\Database\ELoquent\Model $model |
||
269 | * @param \Flugg\Responder\Transformer|callable|null $transformer |
||
270 | * @return \Flugg\Responder\Transformer|callable |
||
271 | */ |
||
272 | protected function resolveTransformer(Model $model, $transformer = null) |
||
282 | |||
283 | /** |
||
284 | * Resolve a transformer from the model. If the model is not transformable, a closure |
||
285 | * based transformer will be created instead, from the model's fillable attributes. |
||
286 | * |
||
287 | * @param \Illuminate\Database\ELoquent\Model $model |
||
288 | * @return \Flugg\Responder\Transformer|callable |
||
289 | */ |
||
290 | protected function resolveTransformerFromModel(Model $model) |
||
300 | |||
301 | /** |
||
302 | * Parse a transformer class and set relations. |
||
303 | * |
||
304 | * @param \Flugg\Responder\Transformer|callable $transformer |
||
305 | * @param \Illuminate\Database\ELoquent\Model $model |
||
306 | * @return \Flugg\Responder\Transformer|callable |
||
307 | * @throws \InvalidTransformerException |
||
308 | */ |
||
309 | protected function parseTransformer($transformer, Model $model) |
||
321 | |||
322 | /** |
||
323 | * Resolve eager loaded relations from the model. |
||
324 | * |
||
325 | * @param \Illuminate\Database\Eloquent\Model $model |
||
326 | * @return array |
||
327 | */ |
||
328 | protected function resolveRelations(Model $model):array |
||
332 | |||
333 | /** |
||
334 | * Resolve eager loaded relations from the model including any nested relations. |
||
335 | * |
||
336 | * @param \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model $data |
||
337 | * @return array |
||
338 | */ |
||
339 | protected function resolveNestedRelations($data):array |
||
357 | |||
358 | /** |
||
359 | * Resolve the resource key from the model. |
||
360 | * |
||
361 | * @param \Illuminate\Database\Eloquent\Model $model |
||
362 | * @param string|null $resourceKey |
||
363 | * @return string |
||
364 | */ |
||
365 | protected function resolveResourceKey(Model $model, string $resourceKey = null):string |
||
377 | |||
378 | /** |
||
379 | * Serialize the transformation data. |
||
380 | * |
||
381 | * @param ResourceInterface $resource |
||
382 | * @return array |
||
383 | */ |
||
384 | protected function serialize(ResourceInterface $resource):array |
||
388 | } |
||
389 |
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.