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  | 
            ||
| 19 | class PHPFeature implements FeatureInterface  | 
            ||
| 20 | { | 
            ||
| 21 | |||
| 22 | /**  | 
            ||
| 23 | * RegEx pattern that matches the comparison string.  | 
            ||
| 24 | *  | 
            ||
| 25 | * @since 0.1.0  | 
            ||
| 26 | *  | 
            ||
| 27 | * @var string  | 
            ||
| 28 | */  | 
            ||
| 29 | const COMPARISON_PATTERN = '/^(?:(<=|lt|<|le|>=|gt|>|ge|=|==|eq|!=|<>|ne))([0-9].*)$/';  | 
            ||
| 30 | |||
| 31 | /**  | 
            ||
| 32 | * Reference to the Configuration object.  | 
            ||
| 33 | *  | 
            ||
| 34 | * @since 0.1.0  | 
            ||
| 35 | *  | 
            ||
| 36 | * @var ConfigInterface  | 
            ||
| 37 | */  | 
            ||
| 38 | protected $config;  | 
            ||
| 39 | |||
| 40 | /**  | 
            ||
| 41 | * Reference to the Version object.  | 
            ||
| 42 | *  | 
            ||
| 43 | * @since 0.1.0  | 
            ||
| 44 | *  | 
            ||
| 45 | * @var SemanticVersion  | 
            ||
| 46 | */  | 
            ||
| 47 | protected $version;  | 
            ||
| 48 | |||
| 49 | /**  | 
            ||
| 50 | * Instantiate a PHPFeature object.  | 
            ||
| 51 | *  | 
            ||
| 52 | * @since 0.1.0  | 
            ||
| 53 | *  | 
            ||
| 54 | * @param SemanticVersion|string|int|null $phpVersion Version of PHP to  | 
            ||
| 55 | * check the features  | 
            ||
| 56 | * for.  | 
            ||
| 57 | * @param ConfigInterface|null $config Configuration that  | 
            ||
| 58 | * contains the known  | 
            ||
| 59 | * features.  | 
            ||
| 60 | * @throws RuntimeException If the PHP version could not be validated.  | 
            ||
| 61 | */  | 
            ||
| 62 | public function __construct($phpVersion = null, ConfigInterface $config = null)  | 
            ||
| 86 | |||
| 87 | /**  | 
            ||
| 88 | * Check whether a feature or a collection of features is supported.  | 
            ||
| 89 | *  | 
            ||
| 90 | * Accepts either a string or an array of strings. Returns true if all the  | 
            ||
| 91 | * passed-in features are supported, or false if at least one of them is  | 
            ||
| 92 | * not.  | 
            ||
| 93 | *  | 
            ||
| 94 | * @since 0.1.0  | 
            ||
| 95 | *  | 
            ||
| 96 | * @param string|array $features What features to check the support of.  | 
            ||
| 97 | * @return bool  | 
            ||
| 98 | * @throws InvalidArgumentException If the wrong type of argument is passed  | 
            ||
| 99 | * in.  | 
            ||
| 100 | * @throws RuntimeException If a requirement could not be parsed.  | 
            ||
| 101 | */  | 
            ||
| 102 | public function isSupported($features)  | 
            ||
| 125 | |||
| 126 | /**  | 
            ||
| 127 | * Get the minimum required version that supports all of the requested  | 
            ||
| 128 | * features.  | 
            ||
| 129 | *  | 
            ||
| 130 | * Accepts either a string or an array of strings. Returns a  | 
            ||
| 131 | * SemanticVersion object for the version number that is known to support  | 
            ||
| 132 | * all the passed-in features, or false if at least one of  | 
            ||
| 133 | * them is not supported by any known version.  | 
            ||
| 134 | *  | 
            ||
| 135 | * @since 0.2.0  | 
            ||
| 136 | *  | 
            ||
| 137 | * @param string|array $features What features to check the support of.  | 
            ||
| 138 | * @return SemanticVersion|bool  | 
            ||
| 139 | * @throws InvalidArgumentException If the wrong type of argument is passed  | 
            ||
| 140 | * in.  | 
            ||
| 141 | * @throws RuntimeException If a requirement could not be parsed.  | 
            ||
| 142 | */  | 
            ||
| 143 | public function getMinimumRequired($features)  | 
            ||
| 167 | |||
| 168 | /**  | 
            ||
| 169 | * Check whether a single feature is supported.  | 
            ||
| 170 | *  | 
            ||
| 171 | * @since 0.1.0  | 
            ||
| 172 | *  | 
            ||
| 173 | * @param string $feature The feature to check.  | 
            ||
| 174 | * @param string $minimumRequired Optional. Minimum required version that  | 
            ||
| 175 | * supports all features.  | 
            ||
| 176 | * @return bool  | 
            ||
| 177 | * @throws RuntimeException If the requirement could not be parsed.  | 
            ||
| 178 | */  | 
            ||
| 179 | protected function checkSupport($feature, &$minimumRequired = null)  | 
            ||
| 201 | |||
| 202 | /**  | 
            ||
| 203 | * Check whether a single requirement is met.  | 
            ||
| 204 | *  | 
            ||
| 205 | * @since 0.1.0  | 
            ||
| 206 | *  | 
            ||
| 207 | * @param string $requirement A requirement that is composed of an  | 
            ||
| 208 | * operator and a version milestone.  | 
            ||
| 209 | * @param string $minimumRequired Optional. Minimum required version that  | 
            ||
| 210 | * supports all features.  | 
            ||
| 211 | * @return bool  | 
            ||
| 212 | * @throws RuntimeException If the requirement could not be parsed.  | 
            ||
| 213 | */  | 
            ||
| 214 | protected function checkRequirement($requirement, &$minimumRequired = null)  | 
            ||
| 244 | |||
| 245 | /**  | 
            ||
| 246 | * Get the required version for a single requirement.  | 
            ||
| 247 | *  | 
            ||
| 248 | * @since 0.2.0  | 
            ||
| 249 | *  | 
            ||
| 250 | * @param string $milestone A version milestone that is used to define the  | 
            ||
| 251 | * requirement.  | 
            ||
| 252 | * @param string $operator An operator that gets applied to the milestone.  | 
            ||
| 253 | * Possible values: '<=', 'lt', '<', 'le', '>=',  | 
            ||
| 254 | * 'gt', '>', 'ge', '=', '==', 'eq', '!=', '<>',  | 
            ||
| 255 | * 'ne'  | 
            ||
| 256 | * @return string  | 
            ||
| 257 | */  | 
            ||
| 258 | protected function getRequiredVersion($milestone, $operator)  | 
            ||
| 265 | }  | 
            ||
| 266 |