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  | 
            ||
| 20 | class Requester  | 
            ||
| 21 | { | 
            ||
| 22 | //  | 
            ||
| 23 | // Account API  | 
            ||
| 24 | //  | 
            ||
| 25 | |||
| 26 | /**  | 
            ||
| 27 | * Fetching an account  | 
            ||
| 28 | *  | 
            ||
| 29 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#fetching-an-account  | 
            ||
| 30 | * @param Client $client  | 
            ||
| 31 | * @param SessionStorage $session  | 
            ||
| 32 | * @param int $id  | 
            ||
| 33 | * @return Entity\Account  | 
            ||
| 34 | */  | 
            ||
| 35 | 1 | public static function getAccount(Client $client, SessionStorage $session, $id)  | 
            |
| 36 |     { | 
            ||
| 37 | 1 | v::intVal()->min(0)->assert($id);  | 
            |
| 38 | |||
| 39 | 1 | return static::map(  | 
            |
| 40 | 1 | Entity\Account::class,  | 
            |
| 41 | 1 |             $client->requestAPI('GET', sprintf('/api/v1/accounts/%d', $id), [], $session) | 
            |
| 42 | );  | 
            ||
| 43 | }  | 
            ||
| 44 | |||
| 45 | /**  | 
            ||
| 46 | * Getting the current user  | 
            ||
| 47 | *  | 
            ||
| 48 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#getting-the-current-user  | 
            ||
| 49 | * @param Client $client  | 
            ||
| 50 | * @param SessionStorage $session  | 
            ||
| 51 | * @return Entity\Account  | 
            ||
| 52 | */  | 
            ||
| 53 | public static function getAccountCurrentUser(Client $client, SessionStorage $session)  | 
            ||
| 54 |     { | 
            ||
| 55 | return static::map(  | 
            ||
| 56 | Entity\Account::class,  | 
            ||
| 57 |             $client->requestAPI('GET', '/api/v1/accounts/verify_credentials', [], $session) | 
            ||
| 58 | );  | 
            ||
| 59 | }  | 
            ||
| 60 | |||
| 61 | /**  | 
            ||
| 62 | * Updating the current user  | 
            ||
| 63 | *  | 
            ||
| 64 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#updating-the-current-user  | 
            ||
| 65 | * @param Client $client  | 
            ||
| 66 | * @param SessionStorage $session  | 
            ||
| 67 | * @param array $update_data  | 
            ||
| 68 | * @return Entity\Account  | 
            ||
| 69 | */  | 
            ||
| 70 | public static function updateAccount(Client $client, SessionStorage $session, $update_data)  | 
            ||
| 71 |     { | 
            ||
| 72 | $form_params = [];  | 
            ||
| 73 | |||
| 74 |         if (isset($update_data['display_name'])) { | 
            ||
| 75 | v::stringType()->assert($update_data['display_name']);  | 
            ||
| 76 | $form_params['display_name'] = (string)$update_data['display_name'];  | 
            ||
| 77 | }  | 
            ||
| 78 | |||
| 79 |         if (isset($update_data['note'])) { | 
            ||
| 80 | v::stringType()->assert($update_data['note']);  | 
            ||
| 81 | $form_params['note'] = (string)$update_data['note'];  | 
            ||
| 82 | }  | 
            ||
| 83 | |||
| 84 | return static::map(  | 
            ||
| 85 | Entity\Account::class,  | 
            ||
| 86 |             $client->requestAPI('PATCH', '/api/v1/accounts/update_credentials', [ | 
            ||
| 87 | 'form_params' => $form_params  | 
            ||
| 88 | ], $session)  | 
            ||
| 89 | );  | 
            ||
| 90 | }  | 
            ||
| 91 | |||
| 92 | /**  | 
            ||
| 93 | * Getting an account's followers  | 
            ||
| 94 | *  | 
            ||
| 95 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#updating-the-current-user  | 
            ||
| 96 | * @param Client $client  | 
            ||
| 97 | * @param SessionStorage $session  | 
            ||
| 98 | * @param int $account_id  | 
            ||
| 99 | * @return Entity\Account[]  | 
            ||
| 100 | */  | 
            ||
| 101 | public static function getAccountFollowers(Client $client, SessionStorage $session, $account_id)  | 
            ||
| 114 | |||
| 115 | /**  | 
            ||
| 116 | * Fetching a user's blocks  | 
            ||
| 117 | *  | 
            ||
| 118 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#updating-the-current-user  | 
            ||
| 119 | * @param Client $client  | 
            ||
| 120 | * @param SessionStorage $session  | 
            ||
| 121 | * @param array $options  | 
            ||
| 122 | * @return Entity\Account[]  | 
            ||
| 123 | */  | 
            ||
| 124 | View Code Duplication | public static function getBlocks(Client $client, SessionStorage $session, $options = [])  | 
            |
| 150 | |||
| 151 | /**  | 
            ||
| 152 | * Fetching a user's favourites  | 
            ||
| 153 | *  | 
            ||
| 154 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#updating-the-current-user  | 
            ||
| 155 | * @param Client $client  | 
            ||
| 156 | * @param SessionStorage $session  | 
            ||
| 157 | * @param array $options  | 
            ||
| 158 | * @return Entity\Status[]  | 
            ||
| 159 | */  | 
            ||
| 160 | View Code Duplication | public static function getFavourites(Client $client, SessionStorage $session, $options = [])  | 
            |
| 186 | |||
| 187 | /**  | 
            ||
| 188 | * Fetching a list of follow requests  | 
            ||
| 189 | *  | 
            ||
| 190 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#fetching-a-list-of-follow-requests  | 
            ||
| 191 | * @param Client $client  | 
            ||
| 192 | * @param SessionStorage $session  | 
            ||
| 193 | * @param array $options  | 
            ||
| 194 | * @return Entity\Accounts[]  | 
            ||
| 195 | */  | 
            ||
| 196 | View Code Duplication | public static function getFollowRequests(Client $client, SessionStorage $session, $options = [])  | 
            |
| 222 | |||
| 223 | //  | 
            ||
| 224 | // Status API  | 
            ||
| 225 | //  | 
            ||
| 226 | |||
| 227 | /**  | 
            ||
| 228 | * Posting a new status  | 
            ||
| 229 | *  | 
            ||
| 230 | * @see https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md#posting-a-new-status  | 
            ||
| 231 | * @param Toot $toot  | 
            ||
| 232 | * @return Entity\Account  | 
            ||
| 233 | */  | 
            ||
| 234 | public static function postStatus(Client $client, SessionStorage $session, Toot $toot)  | 
            ||
| 263 | |||
| 264 | //  | 
            ||
| 265 | // Utility method  | 
            ||
| 266 | //  | 
            ||
| 267 | |||
| 268 | /**  | 
            ||
| 269 | * @param string|string[] $class  | 
            ||
| 270 | * @param ResponseInterface $response  | 
            ||
| 271 | * @return Entity\Entity|Entity\Entity[]  | 
            ||
| 272 | */  | 
            ||
| 273 | 1 | private static function map($class, ResponseInterface $response)  | 
            |
| 280 | }  | 
            ||
| 281 | 
Let’s assume you have a class which uses late-static binding:
}
The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the
getSomeVariable()on that sub-class, you will receive a runtime error:In the case above, it makes sense to update
SomeClassto useselfinstead: