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 Parameter 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 Parameter, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
10 | class Parameter |
||
11 | { |
||
12 | protected $name; |
||
13 | protected $description; |
||
14 | protected $serviceDescription; |
||
15 | protected $type; |
||
16 | protected $required; |
||
17 | protected $enum; |
||
18 | protected $pattern; |
||
19 | protected $minimum; |
||
20 | protected $maximum; |
||
21 | protected $minLength; |
||
22 | protected $maxLength; |
||
23 | protected $minItems; |
||
24 | protected $maxItems; |
||
25 | protected $default; |
||
26 | protected $static; |
||
27 | protected $instanceOf; |
||
28 | protected $filters; |
||
29 | protected $location; |
||
30 | protected $sentAs; |
||
31 | protected $data; |
||
32 | protected $properties = array(); |
||
33 | protected $additionalProperties; |
||
34 | protected $items; |
||
35 | protected $parent; |
||
36 | protected $ref; |
||
37 | protected $format; |
||
38 | protected $propertiesCache = null; |
||
39 | |||
40 | /** |
||
41 | * Create a new Parameter using an associative array of data. The array can contain the following information: |
||
42 | * - name: (string) Unique name of the parameter |
||
43 | * - type: (string|array) Type of variable (string, number, integer, boolean, object, array, numeric, |
||
44 | * null, any). Types are using for validation and determining the structure of a parameter. You |
||
45 | * can use a union type by providing an array of simple types. If one of the union types matches |
||
46 | * the provided value, then the value is valid. |
||
47 | * - instanceOf: (string) When the type is an object, you can specify the class that the object must implement |
||
48 | * - required: (bool) Whether or not the parameter is required |
||
49 | * - default: (mixed) Default value to use if no value is supplied |
||
50 | * - static: (bool) Set to true to specify that the parameter value cannot be changed from the default |
||
51 | * - description: (string) Documentation of the parameter |
||
52 | * - location: (string) The location of a request used to apply a parameter. Custom locations can be registered |
||
53 | * with a command, but the defaults are uri, query, header, body, json, xml, postField, postFile. |
||
54 | * - sentAs: (string) Specifies how the data being modeled is sent over the wire. For example, you may wish |
||
55 | * to include certain headers in a response model that have a normalized casing of FooBar, but the |
||
56 | * actual header is x-foo-bar. In this case, sentAs would be set to x-foo-bar. |
||
57 | * - filters: (array) Array of static method names to to run a parameter value through. Each value in the |
||
58 | * array must be a string containing the full class path to a static method or an array of complex |
||
59 | * filter information. You can specify static methods of classes using the full namespace class |
||
60 | * name followed by '::' (e.g. Foo\Bar::baz()). Some filters require arguments in order to properly |
||
61 | * filter a value. For complex filters, use a hash containing a 'method' key pointing to a static |
||
62 | * method, and an 'args' key containing an array of positional arguments to pass to the method. |
||
63 | * Arguments can contain keywords that are replaced when filtering a value: '@value' is replaced |
||
64 | * with the value being validated, '@api' is replaced with the Parameter object. |
||
65 | * - properties: When the type is an object, you can specify nested parameters |
||
66 | * - additionalProperties: (array) This attribute defines a schema for all properties that are not explicitly |
||
67 | * defined in an object type definition. If specified, the value MUST be a schema or a boolean. If |
||
68 | * false is provided, no additional properties are allowed beyond the properties defined in the |
||
69 | * schema. The default value is an empty schema which allows any value for additional properties. |
||
70 | * - items: This attribute defines the allowed items in an instance array, and MUST be a schema or an array |
||
71 | * of schemas. The default value is an empty schema which allows any value for items in the |
||
72 | * instance array. |
||
73 | * When this attribute value is a schema and the instance value is an array, then all the items |
||
74 | * in the array MUST be valid according to the schema. |
||
75 | * - pattern: When the type is a string, you can specify the regex pattern that a value must match |
||
76 | * - enum: When the type is a string, you can specify a list of acceptable values |
||
77 | * - minItems: (int) Minimum number of items allowed in an array |
||
78 | * - maxItems: (int) Maximum number of items allowed in an array |
||
79 | * - minLength: (int) Minimum length of a string |
||
80 | * - maxLength: (int) Maximum length of a string |
||
81 | * - minimum: (int) Minimum value of an integer |
||
82 | * - maximum: (int) Maximum value of an integer |
||
83 | * - data: (array) Any additional custom data to use when serializing, validating, etc |
||
84 | * - format: (string) Format used to coax a value into the correct format when serializing or unserializing. |
||
85 | * You may specify either an array of filters OR a format, but not both. |
||
86 | * Supported values: date-time, date, time, timestamp, date-time-http |
||
87 | * - $ref: (string) String referencing a service description model. The parameter is replaced by the |
||
88 | * schema contained in the model. |
||
89 | * |
||
90 | * @param array $data Array of data as seen in service descriptions |
||
91 | * @param ServiceDescriptionInterface $description Service description used to resolve models if $ref tags are found |
||
92 | * |
||
93 | * @throws InvalidArgumentException |
||
94 | */ |
||
95 | public function __construct(array $data = array(), ServiceDescriptionInterface $description = null) |
||
128 | |||
129 | /** |
||
130 | * Convert the object to an array |
||
131 | * |
||
132 | * @return array |
||
133 | */ |
||
134 | public function toArray() |
||
177 | |||
178 | /** |
||
179 | * Get the default or static value of the command based on a value |
||
180 | * |
||
181 | * @param string $value Value that is currently set |
||
182 | * |
||
183 | * @return mixed Returns the value, a static value if one is present, or a default value |
||
184 | */ |
||
185 | public function getValue($value) |
||
193 | |||
194 | /** |
||
195 | * Run a value through the filters OR format attribute associated with the parameter |
||
196 | * |
||
197 | * @param mixed $value Value to filter |
||
198 | * |
||
199 | * @return mixed Returns the filtered value |
||
200 | */ |
||
201 | public function filter($value) |
||
234 | |||
235 | /** |
||
236 | * Get the name of the parameter |
||
237 | * |
||
238 | * @return string |
||
239 | */ |
||
240 | public function getName() |
||
244 | |||
245 | /** |
||
246 | * Get the key of the parameter, where sentAs will supersede name if it is set |
||
247 | * |
||
248 | * @return string |
||
249 | */ |
||
250 | public function getWireName() |
||
254 | |||
255 | /** |
||
256 | * Set the name of the parameter |
||
257 | * |
||
258 | * @param string $name Name to set |
||
259 | * |
||
260 | * @return self |
||
261 | */ |
||
262 | public function setName($name) |
||
268 | |||
269 | /** |
||
270 | * Get the type(s) of the parameter |
||
271 | * |
||
272 | * @return string|array |
||
273 | */ |
||
274 | public function getType() |
||
278 | |||
279 | /** |
||
280 | * Set the type(s) of the parameter |
||
281 | * |
||
282 | * @param string|array $type Type of parameter or array of simple types used in a union |
||
283 | * |
||
284 | * @return self |
||
285 | */ |
||
286 | public function setType($type) |
||
292 | |||
293 | /** |
||
294 | * Get if the parameter is required |
||
295 | * |
||
296 | * @return bool |
||
297 | */ |
||
298 | public function getRequired() |
||
302 | |||
303 | /** |
||
304 | * Set if the parameter is required |
||
305 | * |
||
306 | * @param bool $isRequired Whether or not the parameter is required |
||
307 | * |
||
308 | * @return self |
||
309 | */ |
||
310 | public function setRequired($isRequired) |
||
316 | |||
317 | /** |
||
318 | * Get the default value of the parameter |
||
319 | * |
||
320 | * @return string|null |
||
321 | */ |
||
322 | public function getDefault() |
||
326 | |||
327 | /** |
||
328 | * Set the default value of the parameter |
||
329 | * |
||
330 | * @param string|null $default Default value to set |
||
331 | * |
||
332 | * @return self |
||
333 | */ |
||
334 | public function setDefault($default) |
||
340 | |||
341 | /** |
||
342 | * Get the description of the parameter |
||
343 | * |
||
344 | * @return string|null |
||
345 | */ |
||
346 | public function getDescription() |
||
350 | |||
351 | /** |
||
352 | * Set the description of the parameter |
||
353 | * |
||
354 | * @param string $description Description |
||
355 | * |
||
356 | * @return self |
||
357 | */ |
||
358 | public function setDescription($description) |
||
364 | |||
365 | /** |
||
366 | * Get the minimum acceptable value for an integer |
||
367 | * |
||
368 | * @return int|null |
||
369 | */ |
||
370 | public function getMinimum() |
||
374 | |||
375 | /** |
||
376 | * Set the minimum acceptable value for an integer |
||
377 | * |
||
378 | * @param int|null $min Minimum |
||
379 | * |
||
380 | * @return self |
||
381 | */ |
||
382 | public function setMinimum($min) |
||
388 | |||
389 | /** |
||
390 | * Get the maximum acceptable value for an integer |
||
391 | * |
||
392 | * @return int|null |
||
393 | */ |
||
394 | public function getMaximum() |
||
398 | |||
399 | /** |
||
400 | * Set the maximum acceptable value for an integer |
||
401 | * |
||
402 | * @param int $max Maximum |
||
403 | * |
||
404 | * @return self |
||
405 | */ |
||
406 | public function setMaximum($max) |
||
412 | |||
413 | /** |
||
414 | * Get the minimum allowed length of a string value |
||
415 | * |
||
416 | * @return int |
||
417 | */ |
||
418 | public function getMinLength() |
||
422 | |||
423 | /** |
||
424 | * Set the minimum allowed length of a string value |
||
425 | * |
||
426 | * @param int|null $min Minimum |
||
427 | * |
||
428 | * @return self |
||
429 | */ |
||
430 | public function setMinLength($min) |
||
436 | |||
437 | /** |
||
438 | * Get the maximum allowed length of a string value |
||
439 | * |
||
440 | * @return int|null |
||
441 | */ |
||
442 | public function getMaxLength() |
||
446 | |||
447 | /** |
||
448 | * Set the maximum allowed length of a string value |
||
449 | * |
||
450 | * @param int $max Maximum length |
||
451 | * |
||
452 | * @return self |
||
453 | */ |
||
454 | public function setMaxLength($max) |
||
460 | |||
461 | /** |
||
462 | * Get the maximum allowed number of items in an array value |
||
463 | * |
||
464 | * @return int|null |
||
465 | */ |
||
466 | public function getMaxItems() |
||
470 | |||
471 | /** |
||
472 | * Set the maximum allowed number of items in an array value |
||
473 | * |
||
474 | * @param int $max Maximum |
||
475 | * |
||
476 | * @return self |
||
477 | */ |
||
478 | public function setMaxItems($max) |
||
484 | |||
485 | /** |
||
486 | * Get the minimum allowed number of items in an array value |
||
487 | * |
||
488 | * @return int |
||
489 | */ |
||
490 | public function getMinItems() |
||
494 | |||
495 | /** |
||
496 | * Set the minimum allowed number of items in an array value |
||
497 | * |
||
498 | * @param int|null $min Minimum |
||
499 | * |
||
500 | * @return self |
||
501 | */ |
||
502 | public function setMinItems($min) |
||
508 | |||
509 | /** |
||
510 | * Get the location of the parameter |
||
511 | * |
||
512 | * @return string|null |
||
513 | */ |
||
514 | public function getLocation() |
||
518 | |||
519 | /** |
||
520 | * Set the location of the parameter |
||
521 | * |
||
522 | * @param string|null $location Location of the parameter |
||
523 | * |
||
524 | * @return self |
||
525 | */ |
||
526 | public function setLocation($location) |
||
532 | |||
533 | /** |
||
534 | * Get the sentAs attribute of the parameter that used with locations to sentAs an attribute when it is being |
||
535 | * applied to a location. |
||
536 | * |
||
537 | * @return string|null |
||
538 | */ |
||
539 | public function getSentAs() |
||
543 | |||
544 | /** |
||
545 | * Set the sentAs attribute |
||
546 | * |
||
547 | * @param string|null $name Name of the value as it is sent over the wire |
||
548 | * |
||
549 | * @return self |
||
550 | */ |
||
551 | public function setSentAs($name) |
||
557 | |||
558 | /** |
||
559 | * Retrieve a known property from the parameter by name or a data property by name. When not specific name value |
||
560 | * is specified, all data properties will be returned. |
||
561 | * |
||
562 | * @param string|null $name Specify a particular property name to retrieve |
||
563 | * |
||
564 | * @return array|mixed|null |
||
565 | */ |
||
566 | public function getData($name = null) |
||
580 | |||
581 | /** |
||
582 | * Set the extra data properties of the parameter or set a specific extra property |
||
583 | * |
||
584 | * @param string|array|null $nameOrData The name of a specific extra to set or an array of extras to set |
||
585 | * @param mixed|null $data When setting a specific extra property, specify the data to set for it |
||
586 | * |
||
587 | * @return self |
||
588 | */ |
||
589 | public function setData($nameOrData, $data = null) |
||
599 | |||
600 | /** |
||
601 | * Get whether or not the default value can be changed |
||
602 | * |
||
603 | * @return mixed|null |
||
604 | */ |
||
605 | public function getStatic() |
||
609 | |||
610 | /** |
||
611 | * Set to true if the default value cannot be changed |
||
612 | * |
||
613 | * @param bool $static True or false |
||
614 | * |
||
615 | * @return self |
||
616 | */ |
||
617 | public function setStatic($static) |
||
623 | |||
624 | /** |
||
625 | * Get an array of filters used by the parameter |
||
626 | * |
||
627 | * @return array |
||
628 | */ |
||
629 | public function getFilters() |
||
633 | |||
634 | /** |
||
635 | * Set the array of filters used by the parameter |
||
636 | * |
||
637 | * @param array $filters Array of functions to use as filters |
||
638 | * |
||
639 | * @return self |
||
640 | */ |
||
641 | public function setFilters(array $filters) |
||
650 | |||
651 | /** |
||
652 | * Add a filter to the parameter |
||
653 | * |
||
654 | * @param string|array $filter Method to filter the value through |
||
655 | * |
||
656 | * @return self |
||
657 | * @throws InvalidArgumentException |
||
658 | */ |
||
659 | public function addFilter($filter) |
||
675 | |||
676 | /** |
||
677 | * Get the parent object (an {@see OperationInterface} or {@see Parameter} |
||
678 | * |
||
679 | * @return OperationInterface|Parameter|null |
||
680 | */ |
||
681 | public function getParent() |
||
685 | |||
686 | /** |
||
687 | * Set the parent object of the parameter |
||
688 | * |
||
689 | * @param OperationInterface|Parameter|null $parent Parent container of the parameter |
||
690 | * |
||
691 | * @return self |
||
692 | */ |
||
693 | public function setParent($parent) |
||
699 | |||
700 | /** |
||
701 | * Get the properties of the parameter |
||
702 | * |
||
703 | * @return array |
||
704 | */ |
||
705 | public function getProperties() |
||
716 | |||
717 | /** |
||
718 | * Get a specific property from the parameter |
||
719 | * |
||
720 | * @param string $name Name of the property to retrieve |
||
721 | * |
||
722 | * @return null|Parameter |
||
723 | */ |
||
724 | public function getProperty($name) |
||
738 | |||
739 | /** |
||
740 | * Remove a property from the parameter |
||
741 | * |
||
742 | * @param string $name Name of the property to remove |
||
743 | * |
||
744 | * @return self |
||
745 | */ |
||
746 | public function removeProperty($name) |
||
753 | |||
754 | /** |
||
755 | * Add a property to the parameter |
||
756 | * |
||
757 | * @param Parameter $property Properties to set |
||
758 | * |
||
759 | * @return self |
||
760 | */ |
||
761 | public function addProperty(Parameter $property) |
||
769 | |||
770 | /** |
||
771 | * Get the additionalProperties value of the parameter |
||
772 | * |
||
773 | * @return bool|Parameter|null |
||
774 | */ |
||
775 | View Code Duplication | public function getAdditionalProperties() |
|
784 | |||
785 | /** |
||
786 | * Set the additionalProperties value of the parameter |
||
787 | * |
||
788 | * @param bool|Parameter|null $additional Boolean to allow any, an Parameter to specify a schema, or false to disallow |
||
789 | * |
||
790 | * @return self |
||
791 | */ |
||
792 | public function setAdditionalProperties($additional) |
||
798 | |||
799 | /** |
||
800 | * Set the items data of the parameter |
||
801 | * |
||
802 | * @param Parameter|null $items Items to set |
||
803 | * |
||
804 | * @return self |
||
805 | */ |
||
806 | public function setItems(Parameter $items = null) |
||
814 | |||
815 | /** |
||
816 | * Get the item data of the parameter |
||
817 | * |
||
818 | * @return Parameter|null |
||
819 | */ |
||
820 | View Code Duplication | public function getItems() |
|
829 | |||
830 | /** |
||
831 | * Get the class that the parameter must implement |
||
832 | * |
||
833 | * @return null|string |
||
834 | */ |
||
835 | public function getInstanceOf() |
||
839 | |||
840 | /** |
||
841 | * Set the class that the parameter must be an instance of |
||
842 | * |
||
843 | * @param string|null $instanceOf Class or interface name |
||
844 | * |
||
845 | * @return self |
||
846 | */ |
||
847 | public function setInstanceOf($instanceOf) |
||
853 | |||
854 | /** |
||
855 | * Get the enum of strings that are valid for the parameter |
||
856 | * |
||
857 | * @return array|null |
||
858 | */ |
||
859 | public function getEnum() |
||
863 | |||
864 | /** |
||
865 | * Set the enum of strings that are valid for the parameter |
||
866 | * |
||
867 | * @param array|null $enum Array of strings or null |
||
868 | * |
||
869 | * @return self |
||
870 | */ |
||
871 | public function setEnum(array $enum = null) |
||
877 | |||
878 | /** |
||
879 | * Get the regex pattern that must match a value when the value is a string |
||
880 | * |
||
881 | * @return string |
||
882 | */ |
||
883 | public function getPattern() |
||
887 | |||
888 | /** |
||
889 | * Set the regex pattern that must match a value when the value is a string |
||
890 | * |
||
891 | * @param string $pattern Regex pattern |
||
892 | * |
||
893 | * @return self |
||
894 | */ |
||
895 | public function setPattern($pattern) |
||
901 | |||
902 | /** |
||
903 | * Get the format attribute of the schema |
||
904 | * |
||
905 | * @return string |
||
906 | */ |
||
907 | public function getFormat() |
||
911 | |||
912 | /** |
||
913 | * Set the format attribute of the schema |
||
914 | * |
||
915 | * @param string $format Format to set (e.g. date, date-time, timestamp, time, date-time-http) |
||
916 | * |
||
917 | * @return self |
||
918 | */ |
||
919 | public function setFormat($format) |
||
925 | } |
||
926 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.