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 Assert 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 Assert, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
151 | class Assert |
||
|
|||
152 | { |
||
153 | 90 | public static function string($value, $message = '') |
|
162 | |||
163 | 12 | public static function stringNotEmpty($value, $message = '') |
|
168 | |||
169 | 17 | View Code Duplication | public static function integer($value, $message = '') |
178 | |||
179 | 16 | View Code Duplication | public static function integerish($value, $message = '') |
188 | |||
189 | 16 | View Code Duplication | public static function float($value, $message = '') |
198 | |||
199 | 20 | View Code Duplication | public static function numeric($value, $message = '') |
208 | |||
209 | 16 | View Code Duplication | public static function boolean($value, $message = '') |
218 | |||
219 | 23 | View Code Duplication | public static function scalar($value, $message = '') |
228 | |||
229 | 23 | View Code Duplication | public static function object($value, $message = '') |
238 | |||
239 | 16 | public static function resource($value, $type = null, $message = '') |
|
256 | |||
257 | 20 | View Code Duplication | public static function isCallable($value, $message = '') |
266 | |||
267 | 20 | View Code Duplication | public static function isArray($value, $message = '') |
276 | |||
277 | 516 | public static function isTraversable($value, $message = '') |
|
286 | |||
287 | 16 | View Code Duplication | public static function isInstanceOf($value, $class, $message = '') |
297 | |||
298 | 16 | View Code Duplication | public static function notInstanceOf($value, $class, $message = '') |
308 | |||
309 | 23 | public static function isEmpty($value, $message = '') |
|
318 | |||
319 | 31 | public static function notEmpty($value, $message = '') |
|
328 | |||
329 | 11 | public static function null($value, $message = '') |
|
330 | { |
||
331 | 11 | if (null !== $value) { |
|
332 | 8 | static::reportInvalidArgument(sprintf( |
|
333 | 8 | $message ?: 'Expected null. Got: %s', |
|
334 | 8 | static::valueToString($value) |
|
335 | )); |
||
336 | } |
||
337 | 3 | } |
|
338 | |||
339 | 11 | public static function notNull($value, $message = '') |
|
347 | |||
348 | 15 | public static function true($value, $message = '') |
|
349 | { |
||
350 | 15 | if (true !== $value) { |
|
351 | 11 | static::reportInvalidArgument(sprintf( |
|
352 | 11 | $message ?: 'Expected a value to be true. Got: %s', |
|
353 | 11 | static::valueToString($value) |
|
354 | )); |
||
355 | } |
||
356 | 4 | } |
|
357 | |||
358 | 19 | public static function false($value, $message = '') |
|
359 | { |
||
360 | 19 | if (false !== $value) { |
|
361 | 15 | static::reportInvalidArgument(sprintf( |
|
362 | 15 | $message ?: 'Expected a value to be false. Got: %s', |
|
363 | 15 | static::valueToString($value) |
|
364 | )); |
||
365 | } |
||
366 | 4 | } |
|
367 | |||
368 | 32 | public static function eq($value, $value2, $message = '') |
|
369 | { |
||
370 | 32 | if ($value2 != $value) { |
|
371 | 16 | static::reportInvalidArgument(sprintf( |
|
372 | 16 | $message ?: 'Expected a value equal to %2$s. Got: %s', |
|
373 | 16 | static::valueToString($value), |
|
374 | 16 | static::valueToString($value2) |
|
375 | )); |
||
376 | } |
||
377 | 16 | } |
|
378 | |||
379 | 16 | public static function notEq($value, $value2, $message = '') |
|
388 | |||
389 | 16 | public static function same($value, $value2, $message = '') |
|
390 | { |
||
391 | 16 | if ($value2 !== $value) { |
|
392 | 12 | static::reportInvalidArgument(sprintf( |
|
393 | 12 | $message ?: 'Expected a value identical to %2$s. Got: %s', |
|
394 | 12 | static::valueToString($value), |
|
395 | 12 | static::valueToString($value2) |
|
396 | )); |
||
397 | } |
||
398 | 4 | } |
|
399 | |||
400 | 16 | public static function notSame($value, $value2, $message = '') |
|
409 | |||
410 | 8 | public static function greaterThan($value, $limit, $message = '') |
|
411 | { |
||
412 | 8 | if ($value <= $limit) { |
|
413 | 4 | static::reportInvalidArgument(sprintf( |
|
414 | 4 | $message ?: 'Expected a value greater than %2$s. Got: %s', |
|
415 | 4 | static::valueToString($value), |
|
416 | 4 | static::valueToString($limit) |
|
417 | )); |
||
418 | } |
||
419 | 4 | } |
|
420 | |||
421 | 12 | public static function greaterThanEq($value, $limit, $message = '') |
|
422 | { |
||
423 | 12 | if ($value < $limit) { |
|
424 | 4 | static::reportInvalidArgument(sprintf( |
|
425 | 4 | $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', |
|
426 | 4 | static::valueToString($value), |
|
427 | 4 | static::valueToString($limit) |
|
428 | )); |
||
429 | } |
||
430 | 8 | } |
|
431 | |||
432 | 8 | public static function lessThan($value, $limit, $message = '') |
|
433 | { |
||
434 | 8 | if ($value >= $limit) { |
|
435 | 4 | static::reportInvalidArgument(sprintf( |
|
436 | 4 | $message ?: 'Expected a value less than %2$s. Got: %s', |
|
437 | 4 | static::valueToString($value), |
|
438 | 4 | static::valueToString($limit) |
|
439 | )); |
||
440 | } |
||
441 | 4 | } |
|
442 | |||
443 | 12 | public static function lessThanEq($value, $limit, $message = '') |
|
444 | { |
||
445 | 12 | if ($value > $limit) { |
|
446 | 4 | static::reportInvalidArgument(sprintf( |
|
447 | 4 | $message ?: 'Expected a value less than or equal to %2$s. Got: %s', |
|
448 | 4 | static::valueToString($value), |
|
449 | 4 | static::valueToString($limit) |
|
450 | )); |
||
451 | } |
||
452 | 8 | } |
|
453 | |||
454 | 16 | View Code Duplication | public static function range($value, $min, $max, $message = '') |
465 | |||
466 | 8 | public static function oneOf($value, array $values, $message = '') |
|
476 | |||
477 | 20 | View Code Duplication | public static function contains($value, $subString, $message = '') |
487 | |||
488 | 20 | View Code Duplication | public static function notContains($value, $subString, $message = '') |
489 | { |
||
490 | 20 | if (false !== strpos($value, $subString)) { |
|
491 | 12 | static::reportInvalidArgument(sprintf( |
|
492 | 12 | $message ?: '%2$s was not expected to be contained in a value. Got: %s', |
|
493 | 12 | static::valueToString($value), |
|
494 | 12 | static::valueToString($subString) |
|
495 | )); |
||
496 | } |
||
498 | |||
499 | 12 | View Code Duplication | public static function startsWith($value, $prefix, $message = '') |
509 | |||
510 | 12 | public static function startsWithLetter($value, $message = '') |
|
511 | { |
||
512 | 12 | $valid = isset($value[0]); |
|
513 | |||
514 | 12 | if ($valid) { |
|
515 | 8 | $locale = setlocale(LC_CTYPE, 0); |
|
516 | 8 | setlocale(LC_CTYPE, 'C'); |
|
517 | 8 | $valid = ctype_alpha($value[0]); |
|
518 | 8 | setlocale(LC_CTYPE, $locale); |
|
519 | } |
||
520 | |||
521 | 12 | if (!$valid) { |
|
522 | 8 | static::reportInvalidArgument(sprintf( |
|
523 | 8 | $message ?: 'Expected a value to start with a letter. Got: %s', |
|
524 | 8 | static::valueToString($value) |
|
525 | )); |
||
526 | } |
||
527 | 4 | } |
|
528 | |||
529 | 12 | View Code Duplication | public static function endsWith($value, $suffix, $message = '') |
530 | { |
||
531 | 12 | if ($suffix !== substr($value, -static::strlen($suffix))) { |
|
532 | 8 | static::reportInvalidArgument(sprintf( |
|
533 | 8 | $message ?: 'Expected a value to end with %2$s. Got: %s', |
|
534 | 8 | static::valueToString($value), |
|
535 | 8 | static::valueToString($suffix) |
|
536 | )); |
||
537 | } |
||
538 | 4 | } |
|
539 | |||
540 | 12 | public static function regex($value, $pattern, $message = '') |
|
541 | { |
||
542 | 12 | if (!preg_match($pattern, $value)) { |
|
543 | 8 | static::reportInvalidArgument(sprintf( |
|
544 | 8 | $message ?: 'The value %s does not match the expected pattern.', |
|
545 | 8 | static::valueToString($value) |
|
546 | )); |
||
547 | } |
||
548 | 4 | } |
|
549 | |||
550 | 12 | View Code Duplication | public static function alpha($value, $message = '') |
564 | |||
565 | 12 | View Code Duplication | public static function digits($value, $message = '') |
579 | |||
580 | 12 | View Code Duplication | public static function alnum($value, $message = '') |
594 | |||
595 | 16 | View Code Duplication | public static function lower($value, $message = '') |
609 | |||
610 | 16 | View Code Duplication | public static function upper($value, $message = '') |
611 | { |
||
612 | 16 | $locale = setlocale(LC_CTYPE, 0); |
|
613 | 16 | setlocale(LC_CTYPE, 'C'); |
|
614 | 16 | $valid = !ctype_upper($value); |
|
615 | 16 | setlocale(LC_CTYPE, $locale); |
|
616 | |||
617 | 16 | if ($valid) { |
|
618 | 12 | static::reportInvalidArgument(sprintf( |
|
619 | 12 | $message ?: 'Expected a value to contain uppercase characters only. Got: %s', |
|
620 | 12 | static::valueToString($value) |
|
621 | )); |
||
622 | } |
||
623 | 4 | } |
|
624 | |||
625 | 24 | public static function length($value, $length, $message = '') |
|
635 | |||
636 | 24 | public static function minLength($value, $min, $message = '') |
|
646 | |||
647 | 24 | public static function maxLength($value, $max, $message = '') |
|
648 | { |
||
649 | 24 | if (static::strlen($value) > $max) { |
|
650 | 8 | static::reportInvalidArgument(sprintf( |
|
651 | 8 | $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', |
|
652 | 8 | static::valueToString($value), |
|
653 | $max |
||
654 | )); |
||
655 | } |
||
656 | 16 | } |
|
657 | |||
658 | 40 | View Code Duplication | public static function lengthBetween($value, $min, $max, $message = '') |
671 | |||
672 | 36 | public static function fileExists($value, $message = '') |
|
673 | { |
||
674 | 36 | static::string($value); |
|
675 | |||
676 | 36 | if (!file_exists($value)) { |
|
677 | 12 | static::reportInvalidArgument(sprintf( |
|
678 | 12 | $message ?: 'The file %s does not exist.', |
|
679 | 12 | static::valueToString($value) |
|
680 | )); |
||
681 | } |
||
682 | 24 | } |
|
683 | |||
684 | 12 | View Code Duplication | public static function file($value, $message = '') |
685 | { |
||
686 | 12 | static::fileExists($value, $message); |
|
687 | |||
688 | 8 | if (!is_file($value)) { |
|
689 | 4 | static::reportInvalidArgument(sprintf( |
|
690 | 4 | $message ?: 'The path %s is not a file.', |
|
691 | 4 | static::valueToString($value) |
|
692 | )); |
||
693 | } |
||
694 | 4 | } |
|
695 | |||
696 | 12 | View Code Duplication | public static function directory($value, $message = '') |
697 | { |
||
698 | 12 | static::fileExists($value, $message); |
|
699 | |||
700 | 8 | if (!is_dir($value)) { |
|
701 | 4 | static::reportInvalidArgument(sprintf( |
|
702 | 4 | $message ?: 'The path %s is no directory.', |
|
703 | 4 | static::valueToString($value) |
|
704 | )); |
||
705 | } |
||
706 | 4 | } |
|
707 | |||
708 | public static function readable($value, $message = '') |
||
709 | { |
||
710 | if (!is_readable($value)) { |
||
711 | static::reportInvalidArgument(sprintf( |
||
712 | $message ?: 'The path %s is not readable.', |
||
713 | static::valueToString($value) |
||
714 | )); |
||
715 | } |
||
716 | } |
||
717 | |||
718 | public static function writable($value, $message = '') |
||
719 | { |
||
720 | if (!is_writable($value)) { |
||
721 | static::reportInvalidArgument(sprintf( |
||
722 | $message ?: 'The path %s is not writable.', |
||
723 | static::valueToString($value) |
||
724 | )); |
||
725 | } |
||
726 | } |
||
727 | |||
728 | 8 | public static function classExists($value, $message = '') |
|
737 | |||
738 | 8 | public static function subclassOf($value, $class, $message = '') |
|
748 | |||
749 | 8 | View Code Duplication | public static function implementsInterface($value, $interface, $message = '') |
750 | { |
||
751 | 8 | if (!in_array($interface, class_implements($value))) { |
|
752 | 4 | static::reportInvalidArgument(sprintf( |
|
753 | 4 | $message ?: 'Expected an implementation of %2$s. Got: %s', |
|
754 | 4 | static::valueToString($value), |
|
755 | 4 | static::valueToString($interface) |
|
756 | )); |
||
757 | } |
||
758 | 4 | } |
|
759 | |||
760 | 12 | View Code Duplication | public static function propertyExists($classOrObject, $property, $message = '') |
761 | { |
||
762 | 12 | if (!property_exists($classOrObject, $property)) { |
|
763 | 4 | static::reportInvalidArgument(sprintf( |
|
764 | 4 | $message ?: 'Expected the property %s to exist.', |
|
765 | 4 | static::valueToString($property) |
|
766 | )); |
||
767 | } |
||
768 | 8 | } |
|
769 | |||
770 | 12 | View Code Duplication | public static function propertyNotExists($classOrObject, $property, $message = '') |
771 | { |
||
772 | 12 | if (property_exists($classOrObject, $property)) { |
|
773 | 8 | static::reportInvalidArgument(sprintf( |
|
774 | 8 | $message ?: 'Expected the property %s to not exist.', |
|
775 | 8 | static::valueToString($property) |
|
776 | )); |
||
777 | } |
||
778 | 4 | } |
|
779 | |||
780 | 27 | View Code Duplication | public static function methodExists($classOrObject, $method, $message = '') |
781 | { |
||
782 | 27 | if (!method_exists($classOrObject, $method)) { |
|
783 | 19 | static::reportInvalidArgument(sprintf( |
|
784 | 19 | $message ?: 'Expected the method %s to exist.', |
|
785 | 19 | static::valueToString($method) |
|
786 | )); |
||
787 | } |
||
788 | 8 | } |
|
789 | |||
790 | 27 | View Code Duplication | public static function methodNotExists($classOrObject, $method, $message = '') |
791 | { |
||
792 | 27 | if (method_exists($classOrObject, $method)) { |
|
793 | 8 | static::reportInvalidArgument(sprintf( |
|
794 | 8 | $message ?: 'Expected the method %s to not exist.', |
|
795 | 8 | static::valueToString($method) |
|
796 | )); |
||
797 | } |
||
798 | 19 | } |
|
799 | |||
800 | 12 | View Code Duplication | public static function keyExists($array, $key, $message = '') |
801 | { |
||
802 | 12 | if (!array_key_exists($key, $array)) { |
|
803 | 4 | static::reportInvalidArgument(sprintf( |
|
804 | 4 | $message ?: 'Expected the key %s to exist.', |
|
805 | 4 | static::valueToString($key) |
|
806 | )); |
||
807 | } |
||
808 | 8 | } |
|
809 | |||
810 | 12 | View Code Duplication | public static function keyNotExists($array, $key, $message = '') |
811 | { |
||
812 | 12 | if (array_key_exists($key, $array)) { |
|
813 | 8 | static::reportInvalidArgument(sprintf( |
|
814 | 8 | $message ?: 'Expected the key %s to not exist.', |
|
815 | 8 | static::valueToString($key) |
|
816 | )); |
||
817 | } |
||
818 | 4 | } |
|
819 | |||
820 | 8 | public static function count($array, $number, $message = '') |
|
828 | |||
829 | 48 | public static function uuid($value, $message = '') |
|
830 | { |
||
831 | 48 | $value = str_replace(array('urn:', 'uuid:', '{', '}'), '', $value); |
|
832 | |||
833 | // The nil UUID is special form of UUID that is specified to have all |
||
834 | // 128 bits set to zero. |
||
835 | 48 | if ('00000000-0000-0000-0000-000000000000' === $value) { |
|
836 | 4 | return; |
|
837 | } |
||
838 | |||
839 | 44 | if (!preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) { |
|
840 | 20 | static::reportInvalidArgument(sprintf( |
|
841 | 20 | $message ?: 'Value %s is not a valid UUID.', |
|
842 | 20 | static::valueToString($value) |
|
843 | )); |
||
844 | } |
||
845 | 24 | } |
|
846 | |||
847 | 24 | public static function throws(Closure $expression, $class = 'Exception', $message = '') |
|
872 | |||
873 | 820 | public static function __callStatic($name, $arguments) |
|
901 | |||
902 | 384 | protected static function valueToString($value) |
|
934 | |||
935 | 129 | protected static function typeToString($value) |
|
939 | |||
940 | 124 | protected static function strlen($value) |
|
952 | |||
953 | 524 | protected static function reportInvalidArgument($message) |
|
957 | |||
958 | private function __construct() |
||
961 | } |
||
962 |